--- url: https://canary.warp-drive.io/guides/configuration/ember.md description: >- Restore legacy Adapter, Serializer, Model, and EmberObject features through @warp-drive/legacy in an Ember app, and decide when LegacyNetworkHandler is still needed. --- :::warning Legacy guide This guide covers a legacy setup. New apps should create their store with `useRecommendedStore` as shown in [Setup](/guides/configuration/index.md#configure-the-store), without `@warp-drive/legacy`. ::: :::warning caution Older legacy features of WarpDrive (inherited from when the library was named EmberData) should only be used with Ember. ::: # Legacy Feature Setup for Ember Apps ## Configuring TypeScript TypeScript will automatically discover the types these packages provide. If you're using `ember-source`, you should also configure and use Ember's native types. If you previously had any [DefinitelyTyped (@types)](https://github.com/DefinitelyTyped/DefinitelyTyped) packages installed for ember or ember-data you should remove those. If you have any references to ember-data or warp-drive types or types packages in package.json or tsconfig.json you can remove those. ## What is "Legacy" You've probably heard old code patterns referred to as "legacy code" before. In WarpDrive, Legacy refers to older features to which we are giving a second, extended life. When features are deprecated in `@warp-drive/core`, they are added to `@warp-drive/legacy` in a way that allows apps to opt-in to bring them back. Legacy features will not live forever, but they will receive a second deprecation cycle before being deleted. There is no set schedule to when code in legacy might be deprecated. Sometimes it may become deprecated immediately after the feature is removed from core, other times it may last for several majors. Occasionally a deprecation in core won't be able to be restored from legacy at all. It all depends on how easy the feature is to maintain support for weighed against the community and maintenance costs of keeping it around. For example, if Ember were to deprecated EmberObject, then maintaining support for Model, Adapter and Serializer would become untenable quickly - so we would opt to simultaneously deprecate these from legacy. The `@warp-drive/legacy` package is opt-in. New apps should not use it, existing apps should work to remove the features it provides. Consider it your cleanup checklist. ## Restoring EmberObject Features * use per-trait or per-resource or per-field extension ## Restoring Ember ArrayLike Features * use per-field extension ## Adapter/Serializer and Legacy Request Methods You should configure support for legacy requests if your application still makes requests which use an Adapter or Serializer. Some example APIs you may still be using that are reasons to configure this legacy support include: * You have async relationships that don't yet have links * You have sync relationships that you load via references that don't yet have links * You still use methods on the store to fetch data other than `store.request` * You still fetch data with the Legacy builders * You still use `model.save` or `model.destroyRecord` You may also find you want to use Legacy Requests if you are creating a new application and [LinksMode](../the-manual/misc/links-mode.md) is not sufficient * add the [LegacyNetworkHandler](/api/@warp-drive/legacy/compat/variables/LegacyNetworkHandler) * add the Legacy Request APIs back * add the [adapterFor](/api/@warp-drive/legacy/compat/functions/adapterFor), [serializerFor](/api/@warp-drive/legacy/compat/functions/serializerFor), [modelFor](/api/@warp-drive/legacy/model/functions/modelFor), [pushPayload](/api/@warp-drive/legacy/compat/functions/pushPayload) and [normalize](/api/@warp-drive/legacy/compat/functions/normalize) hooks back * caveat: serialization/normalization of newer field schemas ## Model * custom extensions ## ModelFragments ## Other * resetOnRemote * filterDuplicates --- --- url: https://canary.warp-drive.io/guides/configuration/legacy-package-setup.md description: >- Install the pre-unification @ember-data/* and @warp-drive/* packages with exact pinned versions, for apps still on the legacy multi-package setup rather than @warp-drive/core. --- :::warning Legacy guide This guide covers a legacy setup. New apps should follow [Installation](/guides/installation/index.md) and [Setup](/guides/configuration/index.md), which use `@warp-drive/core` instead of these packages. ::: ::: tip Boilerplate Sucks 👎🏽 We're re-aligning our packages into a new streamlined installation and setup experience. Below you'll find the current *boilerplate heavy* setup. Curious? Read the [RFC](https://rfcs.emberjs.com/id/1075-warp-drive-package-unification/) ::: # Configuration ***Warp*Drive** is highly configurable. The library is designed as a series of small packages with clear interface-driven boundaries between each other and brought together by configuration. Below, we detail the installation for the most common configurations. ::: warning ⚠️ Caution WarpDrive packages follow lockstep: dependencies and peer-dependencies between WarpDrive packages are version-locked at the time of publish. We find this means its best to use exact versions instead of ranges as all WarpDrive packages should be upgraded together at once. All of the installation commands below pin the version for this reason. ::: ## Installation {#installation} Install the core packages: ::: info 💡 TIP WarpDrive uses npm channel tags to simplify installation. * `@lts` is the latest LTS release * `@latest` is the latest stable release * `@beta` is the latest beta release * `@canary` is the latest canary release Replace `@latest` in the commands below with the desired channel if needed. ::: ::: code-group ```sh [pnpm] pnpm add -E \ @warp-drive/core-types@latest \ @warp-drive/build-config@latest \ @warp-drive/schema-record@latest \ @ember-data/store@latest \ @ember-data/request@latest \ @ember-data/request-utils@latest \ @ember-data/graph@latest \ @ember-data/json-api@latest; ``` ```sh [npm] npm add -E \ @warp-drive/core-types@latest \ @warp-drive/build-config@latest \ @warp-drive/schema-record@latest \ @ember-data/store@latest \ @ember-data/request@latest \ @ember-data/request-utils@latest \ @ember-data/graph@latest \ @ember-data/json-api@latest; ``` ```sh [yarn] yarn add -E \ @warp-drive/core-types@latest \ @warp-drive/build-config@latest \ @warp-drive/schema-record@latest \ @ember-data/store@latest \ @ember-data/request@latest \ @ember-data/request-utils@latest \ @ember-data/graph@latest \ @ember-data/json-api@latest; ``` ```sh [bun] bun add --exact \ @warp-drive/core-types@latest \ @warp-drive/build-config@latest \ @warp-drive/schema-record@latest \ @ember-data/store@latest \ @ember-data/request@latest \ @ember-data/request-utils@latest \ @ember-data/graph@latest \ @ember-data/json-api@latest; ``` ::: Optionally, install the ESLint plugin `eslint-plugin-warp-drive` ::: code-group ```sh [pnpm] pnpm add -E eslint-plugin-warp-drive@latest ``` ```sh [npm] npm add -E eslint-plugin-warp-drive@latest ``` ```sh [yarn] yarn add -E eslint-plugin-warp-drive@latest ``` ```sh [bun] bun add --exact eslint-plugin-warp-drive@latest ``` ::: ### 🐹 For Ember.js Only Install `@warp-drive/ember` ::: code-group ```sh [pnpm] pnpm add -E @warp-drive/ember@latest ``` ```sh [npm] npm add -E @warp-drive/ember@latest ``` ```sh [yarn] yarn add -E @warp-drive/ember@latest ``` ```sh [bun] bun add --exact @warp-drive/ember@latest ``` ::: Optionally, for Ember Inspector support install `@ember-data/debug` ::: code-group ```sh [pnpm] pnpm add -E @ember-data/debug@latest ``` ```sh [npm] npm add -E @ember-data/debug@latest ``` ```sh [yarn] yarn add-E @ember-data/debug@latest ``` ```sh [bun] bun add --exact @ember-data/debug@latest ``` ::: Optionally, to use the legacy `@ember-data/model` experience (via Model or via [ReactiveResource](/api/@warp-drive/core/reactive/types/ReactiveResource)) install the following packages: ::: code-group ```sh [pnpm] pnpm add -E \ @ember-data/model@latest \ @ember-data/legacy-compat@latest; ``` ```sh [npm] npm add -E \ @ember-data/model@latest \ @ember-data/legacy-compat@latest; ``` ```sh [yarn] yarn add -E \ @ember-data/model@latest \ @ember-data/legacy-compat@latest; ``` ```sh [bun] bun add --exact \ @ember-data/model@latest \ @ember-data/legacy-compat@latest; ``` ::: Optionally, to use the legacy **Adapter/Serializer** experience, install the following packages: ::: code-group ```sh [pnpm] pnpm add -E \ @ember-data/adapter@latest \ @ember-data/serializer@latest \ @ember-data/legacy-compat@latest; ``` ```sh [npm] npm add -E \ @ember-data/adapter@latest \ @ember-data/serializer@latest \ @ember-data/legacy-compat@latest; ``` ```sh [yarn] yarn add -E \ @ember-data/adapter@latest \ @ember-data/serializer@latest \ @ember-data/legacy-compat@latest; ``` ```sh [bun] bun add --exact \ @ember-data/adapter@latest \ @ember-data/serializer@latest \ @ember-data/legacy-compat@latest; ``` ::: ### Other Packages Install `@ember-data/rest` for utilities for working with requests that follow common REST API patterns. ::: code-group ```sh [pnpm] pnpm add -E @ember-data/rest@latest ``` ```sh [npm] npm add -E @ember-data/rest@latest ``` ```sh [yarn] yarn add -E @ember-data/rest@latest ``` ```sh [bun] bun add --exact @ember-data/rest@latest ``` ::: Install `@ember-data/active-record` for utilities for working with requests that follow the rails ActiveRecord structure. ::: code-group ```sh [pnpm] pnpm add -E @ember-data/active-record@latest ``` ```sh [npm] npm add -E @ember-data/active-record@latest ``` ```sh [yarn] yarn add -E @ember-data/active-record@latest ``` ```sh [bun] bun add --exact @ember-data/active-record@latest ``` ::: Install `@warp-drive/experiments` for bleeding edge unstable features we're prototyping like SharedWorker and PersistedCache. ::: code-group ```sh [pnpm] pnpm add -E @warp-drive/experiments@latest ``` ```sh [npm] npm add -E @warp-drive/experiments@latest ``` ```sh [yarn] yarn add -E @warp-drive/experiments@latest ``` ```sh [bun] bun add --exact @warp-drive/experiments@latest ``` ::: ## What about the `ember-data` package? The `ember-data` package declares the core and ember.js packages including all legacy packages as its dependencies. It configures and automatically provides a store service configured for the maximal legacy experience, This auto-bundled experience sounds useful, however, this approach works poorly with vite, TypeScript and peer dependency grouping. If you're curious, the exact list of packages to replicate `ember-data` including all deprecations is: ::: code-group ```sh [pnpm] pnpm add -E \ @warp-drive/core-types@latest \ @warp-drive/build-config@latest \ @ember-data/store@latest \ @ember-data/request@latest \ @ember-data/request-utils@latest \ @ember-data/graph@latest \ @ember-data/json-api@latest \ @ember-data/adapter \ @ember-data/debug \ @ember-data/legacy-compat \ @ember-data/model \ @ember-data/serializer \ @embroider/macros \ @ember-data/tracking \ @warp-drive/ember; ``` ```sh [npm] npm add -E \ @warp-drive/core-types@latest \ @warp-drive/build-config@latest \ @ember-data/store@latest \ @ember-data/request@latest \ @ember-data/request-utils@latest \ @ember-data/graph@latest \ @ember-data/json-api@latest \ @ember-data/adapter \ @ember-data/debug \ @ember-data/legacy-compat \ @ember-data/model \ @ember-data/serializer \ @embroider/macros \ @ember-data/tracking \ @warp-drive/ember; ``` ```sh [yarn] yarn add -E \ @warp-drive/core-types@latest \ @warp-drive/build-config@latest \ @ember-data/store@latest \ @ember-data/request@latest \ @ember-data/request-utils@latest \ @ember-data/graph@latest \ @ember-data/json-api@latest \ @ember-data/adapter \ @ember-data/debug \ @ember-data/legacy-compat \ @ember-data/model \ @ember-data/serializer \ @embroider/macros \ @ember-data/tracking \ @warp-drive/ember; ``` ```sh [bun] bun add --exact \ @warp-drive/core-types@latest \ @warp-drive/build-config@latest \ @ember-data/store@latest \ @ember-data/request@latest \ @ember-data/request-utils@latest \ @ember-data/graph@latest \ @ember-data/json-api@latest \ @ember-data/adapter \ @ember-data/debug \ @ember-data/legacy-compat \ @ember-data/model \ @ember-data/serializer \ @embroider/macros \ @ember-data/tracking \ @warp-drive/ember; ``` ::: --- --- url: >- https://canary.warp-drive.io/guides/configuration/legacy-package-setup/setup/ember.md description: >- Configure a legacy Ember app to import @warp-drive/ember/install, drop @ember-data/tracking, and add LegacyNetworkHandler plus adapterFor and serializerFor hooks to the store. --- :::warning Legacy guide This guide covers a legacy setup. New apps should follow [Installation](/guides/installation/index.md) and [Setup](/guides/configuration/index.md), which use `@warp-drive/core` instead of these packages. ::: # Ember.js ## Configure Reactivity 1. Ensure `@warp-drive/ember` is [installed](../index.md#installation) with the proper version 2. In the main entry point for your app add the following side-effect import ```ts [app/app.ts] import '@warp-drive/ember/install'; ``` 3. If you have tests, such as unit tests, which make use of WarpDrive directly and not via an app container you may also need to add the side-effect import to `tests/test-helper.{js,ts}` 4. If it is installed, remove the package `@ember-data/tracking`. 5. Change any usage of `untracked` ```ts import { untracked } from '@ember-data/tracking'; // [!code --] import { untrack as untracked } from '@glimmer/validator'; // [!code ++] ``` ::: tip 💡 @glimmer/validator is a virtual dep You do not need to add a dependency on `@glimmer/validator`, this is a virtual package provided by `ember-source`. ::: 6. Remove the deprecation for use of @ember-data/tracking by setting the deprecation to `false` in your build config: ```ts [ember-cli-build.js] 'use strict'; const EmberApp = require('ember-cli/lib/broccoli/ember-app'); const { compatBuild } = require('@embroider/compat'); module.exports = async function (defaults) { const { setConfig } = await import('@warp-drive/build-config'); const { buildOnce } = await import('@embroider/vite'); const app = new EmberApp(defaults, {}); setConfig(app, __dirname, { // this should be the most recent . version for // which all deprecations have been fully resolved // and should be updated when that changes compatWith: '4.12' deprecations: { // [!code focus:3] DEPRECATE_TRACKING_PACKAGE: false } }); return compatBuild(app, buildOnce); }; ``` ## Setup Legacy Support This guide presumes you've already gone through the [setup steps that apply to all applications](./universal.md) "Legacy" is a term that applies to a fairly broad set of patterns that ***Warp*Drive**/***Ember*Data** is migrating away from. The previous guide showed how to configure schemas and reactivity to work with the legacy [`Model`](/api/@warp-drive/legacy/model/classes/Model) approach. You may also wish to configure legacy support for `Adapters` and `Serializers`. Reasons to configure this legacy support include: * You have an existing application that has not migrated all requests away from this pattern * You are creating a new application and [LinksMode](../../../the-manual/misc/links-mode.md) is not sufficient 1. Ensure `@ember-data/legacy-compat` is [installed](../index.md#installation) with the proper version 2. Add desired hooks to the store. The below example builds from the `Model` example in the prior guide. ```ts [app/services/store.ts] import Store, { CacheHandler } from '@ember-data/store'; import type { CacheCapabilitiesManager, ModelSchema, SchemaService } from '@ember-data/store/types'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import { CachePolicy } from '@ember-data/request-utils'; import JSONAPICache from '@ember-data/json-api'; import type { ResourceKey } from '@warp-drive/core-types'; import type { TypeFromInstance } from '@warp-drive/core-types/record'; import type Model from '@ember-data/model'; import { buildSchema, instantiateRecord, modelFor, teardownRecord } from '@ember-data/model'; import { // [!code focus:9] adapterFor, cleanup, LegacyNetworkHandler, normalize, pushPayload, serializeRecord, serializerFor, } from '@ember-data/legacy-compat'; export default class AppStore extends Store { requestManager = new RequestManager() .use([LegacyNetworkHandler, Fetch]) // [!code focus] .useCache(CacheHandler); lifetimes = new CachePolicy({ apiCacheHardExpires: 15 * 60 * 1000, // 15 minutes apiCacheSoftExpires: 1 * 30 * 1000, // 30 seconds constraints: { headers: { 'X-WarpDrive-Expires': true, 'Cache-Control': true, 'Expires': true, } } }); createSchemaService(): SchemaService { return buildSchema(this); } createCache(capabilities: CacheCapabilitiesManager) { return new JSONAPICache(capabilities); } instantiateRecord(key: ResourceKey, createRecordArgs: Record) { return instantiateRecord.call(this, key, createRecordArgs); } teardownRecord(record: unknown): void { return teardownRecord.call(this, record as Model); } modelFor(type: TypeFromInstance): ModelSchema; modelFor(type: string): ModelSchema; modelFor(type: string): ModelSchema { return (modelFor.call(this, type) as ModelSchema) || super.modelFor(type); } adapterFor = adapterFor; // [!code focus:5] serializerFor = serializerFor; pushPayload = pushPayload; normalize = normalize; serializeRecord = serializeRecord; destroy() { // [!code focus:4] cleanup.call(this); super.destroy(); } } ``` --- --- url: >- https://canary.warp-drive.io/guides/configuration/legacy-package-setup/setup/universal.md description: >- Configure the legacy multi-package setup with setConfig in ember-cli-build, unstable-preview-types in tsconfig, and a hand-built Store using RequestManager and JSONAPICache. --- :::warning Legacy guide This guide covers a legacy setup. New apps should follow [Installation](/guides/installation/index.md) and [Setup](/guides/configuration/index.md), which use `@warp-drive/core` instead of these packages. ::: ::: tip Boilerplate Sucks 👎🏽 We're re-aligning our packages into a new streamlined installation and setup experience. Below you'll find the current *boilerplate heavy* setup. Curious? Read the [RFC](https://rfcs.emberjs.com/id/1075-warp-drive-package-unification/) ::: # Setup All frameworks should follow this configuration first. ## Configure the Build Plugin ***Warp*Drive** uses a [babel plugin](https://www.npmjs.com/package/@embroider/macros) to inject app-specific configuration allowing us to provide advanced dev-mode debugging features, deprecation management, and canary feature toggles. For Ember.js, this plugin comes built-in to the toolchain and all you need to do is provide it the desired configuration in `ember-cli-build`. For all other projects, the configuration is done inside of the app's babel configuration file. ::: code-group ```ts [New Ember Apps] 'use strict'; const EmberApp = require('ember-cli/lib/broccoli/ember-app'); const { compatBuild } = require('@embroider/compat'); module.exports = async function (defaults) { const { setConfig } = await import('@warp-drive/build-config'); // [!code focus] const { buildOnce } = await import('@embroider/vite'); const app = new EmberApp(defaults, {}); setConfig(app, __dirname, { // [!code focus:7] // this should be the most recent . version for // which all deprecations have been fully resolved // and should be updated when that changes // for new apps it should be the version you installed compatWith: '5.5' }); return compatBuild(app, buildOnce); }; ``` ```ts [Existing Ember Apps] 'use strict'; const EmberApp = require('ember-cli/lib/broccoli/ember-app'); const { compatBuild } = require('@embroider/compat'); module.exports = async function (defaults) { const { setConfig } = await import('@warp-drive/build-config'); // [!code focus] const { buildOnce } = await import('@embroider/vite'); const app = new EmberApp(defaults, {}); setConfig(app, __dirname, { // [!code focus:9] // this should be the most recent . version for // which all deprecations have been fully resolved // and should be updated when that changes compatWith: '4.12' deprecations: { // ... list individual deprecations that have been resolved here } }); return compatBuild(app, buildOnce); }; ``` ::: ## Add TypeScript Types ::: code-group ```tsconfig.json [Ember Polaris] { compilerOptions: { types: [ "@ember-data/graph/unstable-preview-types", // [!code ++] "@ember-data/json-api/unstable-preview-types", // [!code ++] "@ember-data/request/unstable-preview-types", // [!code ++] "@ember-data/request-utils/unstable-preview-types", // [!code ++] "@ember-data/store/unstable-preview-types", // [!code ++] "@warp-drive/core-types/unstable-preview-types", // [!code ++] "@warp-drive/schema-record/unstable-preview-types", // [!code ++] ] } } ``` ```tsconfig.json [Ember Full Legacy] { compilerOptions: { types: [ "@ember-data/adapter/unstable-preview-types", // [!code ++] "@ember-data/graph/unstable-preview-types", // [!code ++] "@ember-data/json-api/unstable-preview-types", // [!code ++] "@ember-data/legacy-compat/unstable-preview-types", // [!code ++] "@ember-data/model/unstable-preview-types", // [!code ++] "@ember-data/request/unstable-preview-types", // [!code ++] "@ember-data/request-utils/unstable-preview-types", // [!code ++] "@ember-data/serializer/unstable-preview-types", // [!code ++] "@ember-data/store/unstable-preview-types", // [!code ++] "@warp-drive/core-types/unstable-preview-types", // [!code ++] "@warp-drive/schema-record/unstable-preview-types", // [!code ++] ] } } ``` ::: `@warp-drive/build-config` and `@ember-data/debug` need no entry in this list. On `@warp-drive/build-config` 5.6 through 5.8 only, also add `"@warp-drive/build-config/declarations"`. ## Configure the Store To get up and running we need to configure a [`Store`](/api/@warp-drive/core/classes/Store) to understand how we want to handle requests, what our data looks like, how to cache it, and what sort of reactive objects to create for that data. Here's an example final configuration. Below we'll show each bit in parts and discuss what each does. ::: tip 💡 Guide Looking for Legacy Adapter/Serializer Support? → After finishing this page read the guide for [Ember.js](./ember.md) ::: ::: code-group ```ts [ReactiveResource] import Store, { CacheHandler } from '@ember-data/store'; import type { CacheCapabilitiesManager } from '@ember-data/store/types'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import { CachePolicy } from '@ember-data/request-utils'; import JSONAPICache from '@ember-data/json-api'; import type { ResourceKey } from '@warp-drive/core-types'; import { instantiateRecord, registerDerivations, SchemaService, teardownRecord } from '@warp-drive/schema-record'; export default class AppStore extends Store { requestManager = new RequestManager() .use([Fetch]) .useCache(CacheHandler); lifetimes = new CachePolicy({ apiCacheHardExpires: 15 * 60 * 1000, // 15 minutes apiCacheSoftExpires: 1 * 30 * 1000, // 30 seconds constraints: { headers: { 'X-WarpDrive-Expires': true, 'Cache-Control': true, 'Expires': true, } } }); createSchemaService() { const schema = new SchemaService(); registerDerivations(schema); return schema; } createCache(capabilities: CacheCapabilitiesManager) { return new JSONAPICache(capabilities); } instantiateRecord(key: ResourceKey, createArgs?: Record) { return instantiateRecord(this, key, createArgs); } teardownRecord(record: unknown): void { return teardownRecord(record); } } ``` ```ts [Model (Ember Only)] import Store, { CacheHandler } from '@ember-data/store'; import type { CacheCapabilitiesManager, ModelSchema, SchemaService } from '@ember-data/store/types'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import { CachePolicy } from '@ember-data/request-utils'; import JSONAPICache from '@ember-data/json-api'; import type { ResourceKey } from '@warp-drive/core-types'; import type { TypeFromInstance } from '@warp-drive/core-types/record'; import type Model from '@ember-data/model'; import { buildSchema, instantiateRecord, modelFor, teardownRecord } from '@ember-data/model'; export default class AppStore extends Store { requestManager = new RequestManager() .use([Fetch]) .useCache(CacheHandler); lifetimes = new CachePolicy({ apiCacheHardExpires: 15 * 60 * 1000, // 15 minutes apiCacheSoftExpires: 1 * 30 * 1000, // 30 seconds constraints: { headers: { 'X-WarpDrive-Expires': true, 'Cache-Control': true, 'Expires': true, } } }); createSchemaService(): SchemaService { return buildSchema(this); } createCache(capabilities: CacheCapabilitiesManager) { return new JSONAPICache(capabilities); } instantiateRecord(key: ResourceKey, createRecordArgs: Record) { return instantiateRecord.call(this, key, createRecordArgs); } teardownRecord(record: unknown): void { return teardownRecord.call(this, record as Model); } modelFor(type: TypeFromInstance): ModelSchema; modelFor(type: string): ModelSchema; modelFor(type: string): ModelSchema { return (modelFor.call(this, type) as ModelSchema) || super.modelFor(type); } } ``` ```ts [Migration (Ember Only)] import Store, { CacheHandler, recordIdentifierFor } from '@ember-data/store'; import type { CacheCapabilitiesManager, ModelSchema } from '@ember-data/store/types'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import { CachePolicy } from '@ember-data/request-utils'; import JSONAPICache from '@ember-data/json-api'; import type { ResourceKey } from '@warp-drive/core-types'; import type { TypeFromInstance } from '@warp-drive/core-types/record'; import { DelegatingSchemaService } from '@ember-data/model/migration-support'; import type Model from '@ember-data/model'; import { instantiateRecord as instantiateModel, modelFor, teardownRecord as teardownModel } from '@ember-data/model'; import { instantiateRecord, registerDerivations, SchemaService, teardownRecord } from '@warp-drive/schema-record'; export default class AppStore extends Store { requestManager = new RequestManager() .use([Fetch]) .useCache(CacheHandler); lifetimes = new CachePolicy({ apiCacheHardExpires: 15 * 60 * 1000, // 15 minutes apiCacheSoftExpires: 1 * 30 * 1000, // 30 seconds constraints: { headers: { 'X-WarpDrive-Expires': true, 'Cache-Control': true, 'Expires': true, } } }); createSchemaService() { const schema = new SchemaService(); registerDerivations(schema); return new DelegatingSchemaService(this, schema); } createCache(capabilities: CacheCapabilitiesManager) { return new JSONAPICache(capabilities); } instantiateRecord(key: ResourceKey, createArgs?: Record) { if (this.schema.isDelegated(key)) { return instantiateModel.call(this, key, createRecordArgs) } return instantiateRecord(this, key, createArgs); } teardownRecord(record: unknown): void { const key = recordIdentifierFor(record); if (this.schema.isDelegated(key)) { return teardownModel.call(this, record as Model); } return teardownRecord(record); } modelFor(type: TypeFromInstance): ModelSchema; modelFor(type: string): ModelSchema; modelFor(type: string): ModelSchema { return (modelFor.call(this, type) as ModelSchema) || super.modelFor(type); } } ``` ::: ### Start With A Store The store is the central piece of the ***Warp*Drive** experience. It functions as a coordinator, linking together requests for data with schemas, caching and reactivity. While it's easy to use ***just*** ***Warp*Drive**'s request management, most apps will find they require far more than basic fetch management. For this reason it's often best to start with a Store even when you aren't sure yet. ```ts import Store from '@ember-data/store'; export default class AppStore extends Store {} ``` ### Add Basic Request Management [`RequestManager`](/api/@warp-drive/core/classes/RequestManager) provides a chain-of-responsibility style pipeline for helping you handle centralized concerns around requesting and updating data from your backend. ::: tip 💡 Guide → Learn more about [Making Requests](../../../the-manual/requests/index.md) ::: ```ts import Store from '@ember-data/store'; import RequestManager from '@ember-data/request'; // [!code focus:2] import Fetch from '@ember-data/request/fetch'; export default class AppStore extends Store { requestManager = new RequestManager() // [!code focus:2] .use([Fetch]); } ``` ### Add a Source for Schema for your Data ***Warp*Drive** uses simple JSON schemas to define the shape and features of reactive objects. Schemas may seem simple, but they come packed with features that will help you build incredible applications. ::: tip 💡 Guide → Learn more about [Resource Schemas](../../../the-manual/schemas/index.md) ::: ::: code-group ```ts [ReactiveResource] import Store from '@ember-data/store'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import { // [!code focus:4] registerDerivations, SchemaService, } from '@warp-drive/schema-record'; export default class AppStore extends Store { requestManager = new RequestManager() .use([Fetch]); createSchemaService() { // [!code focus:5] const schema = new SchemaService(); registerDerivations(schema); return schema; } } ``` ```ts [Model (Ember Only)] import Store from '@ember-data/store'; import type { ModelSchema, SchemaService } from '@ember-data/store/types'; // [!code focus] import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import type { TypeFromInstance } from '@warp-drive/core-types/record'; // [!code focus] import { // [!code focus:4] buildSchema, modelFor, } from '@warp-drive/schema-record'; export default class AppStore extends Store { requestManager = new RequestManager() .use([Fetch]); createSchemaService(): SchemaService { // [!code focus:3] return buildSchema(this); } modelFor(type: TypeFromInstance): ModelSchema; // [!code focus:6] modelFor(type: string): ModelSchema; modelFor(type: string): ModelSchema { return (modelFor.call(this, type) as ModelSchema) || super.modelFor(type); } } ``` ```ts [Migration (Ember Only)] import Store from '@ember-data/store'; import type { ModelSchema } from '@ember-data/store/types'; // [!code focus] import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import type { TypeFromInstance } from '@warp-drive/core-types/record'; // [!code focus:2] import { DelegatingSchemaService } from '@ember-data/model/migration-support'; import { // [!code focus:3] modelFor, } from '@warp-drive/schema-record'; import { // [!code focus:4] registerDerivations, SchemaService, } from '@warp-drive/schema-record'; export default class AppStore extends Store { requestManager = new RequestManager() .use([Fetch]); createSchemaService() { // [!code focus:5] const schema = new SchemaService(); registerDerivations(schema); return new DelegatingSchemaService(this, schema); } modelFor(type: TypeFromInstance): ModelSchema; // [!code focus:6] modelFor(type: string): ModelSchema; modelFor(type: string): ModelSchema { return (modelFor.call(this, type) as ModelSchema) || super.modelFor(type); } } ``` ::: ### Add a Cache Do you really need a cache? Are sunsets beautiful? Caching is what powers features like immutability, mutation management, and allows ***Warp*Drive** to understand your relational data. Some caches are simple request/response maps. ***Warp*Drive**'s is not. The Cache deeply understands the structure of your data, ensuring your data remains consistent both within and across requests. Out of the box, ***Warp*Drive** provides a Cache that expects the [{json:api}](https://jsonapi.org) format. This format excels at simiplifying common complex problems around cache consistency and information density. Most APIs can be quickly adapted to work with it, but if a cache built to understand another format would do better it just needs to follow the same interface. ```ts import Store, { CacheHandler } from '@ember-data/store'; // [!code focus:2] import type { CacheCapabilitiesManager } from '@ember-data/store/types'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import JSONAPICache from '@ember-data/json-api'; // [!code focus] import { registerDerivations, SchemaService, } from '@warp-drive/schema-record'; export default class AppStore extends Store { requestManager = new RequestManager() .use([Fetch]) .useCache(CacheHandler); createSchemaService() { const schema = new SchemaService(); registerDerivations(schema); return schema; } createCache(capabilities: CacheCapabilitiesManager) { // [!code focus:2] return new JSONAPICache(capabilities); } } ``` ### Setup Your Data to be Reactive While it is possible to use ***Warp*Drive** to store and retrieve raw json, you'd be missing out on the best part. Reactive objects transform raw cached data into rich, reactive data. The resulting objects are immutable, always displaying the latest state in the cache while preventing accidental or unsafe mutation in your app. ::: code-group ```ts [ReactiveResource] import Store, { CacheHandler } from '@ember-data/store'; import type { CacheCapabilitiesManager } from '@ember-data/store/types'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import JSONAPICache from '@ember-data/json-api'; import type { ResourceKey } from '@warp-drive/core-types'; // [!code focus] import { instantiateRecord, // [!code focus] registerDerivations, SchemaService, teardownRecord // [!code focus] } from '@warp-drive/schema-record'; export default class AppStore extends Store { requestManager = new RequestManager() .use([Fetch]) .useCache(CacheHandler); createSchemaService() { const schema = new SchemaService(); registerDerivations(schema); return schema; } createCache(capabilities: CacheCapabilitiesManager) { return new JSONAPICache(capabilities); } instantiateRecord(key: ResourceKey, createArgs?: Record) { // [!code focus:3] return instantiateRecord(this, key, createArgs); } teardownRecord(record: unknown): void { // [!code focus:3] return teardownRecord(record); } } ``` ```ts [Model (Ember Only)] import Store, { CacheHandler } from '@ember-data/store'; import type { CacheCapabilitiesManager, ModelSchema, SchemaService } from '@ember-data/store/types'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import JSONAPICache from '@ember-data/json-api'; import type { ResourceKey } from '@warp-drive/core-types'; // [!code focus] import type { TypeFromInstance } from '@warp-drive/core-types/record'; import type Model from '@ember-data/model'; // [!code focus] import { buildSchema, instantiateRecord, // [!code focus] modelFor, teardownRecord // [!code focus] } from '@ember-data/model'; export default class AppStore extends Store { requestManager = new RequestManager() .use([Fetch]) .useCache(CacheHandler); createSchemaService(): SchemaService { return buildSchema(this); } createCache(capabilities: CacheCapabilitiesManager) { return new JSONAPICache(capabilities); } instantiateRecord(key: ResourceKey, createRecordArgs: Record) { // [!code focus:3] return instantiateRecord.call(this, key, createRecordArgs); } teardownRecord(record: unknown): void { // [!code focus:3] return teardownRecord.call(this, record as Model); } modelFor(type: TypeFromInstance): ModelSchema; modelFor(type: string): ModelSchema; modelFor(type: string): ModelSchema { return (modelFor.call(this, type) as ModelSchema) || super.modelFor(type); } } ``` ```ts [Migration (Ember Only)] import Store, { CacheHandler, recordIdentifierFor } from '@ember-data/store'; import type { CacheCapabilitiesManager, ModelSchema } from '@ember-data/store/types'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import JSONAPICache from '@ember-data/json-api'; import type { ResourceKey } from '@warp-drive/core-types'; // [!code focus] import type { TypeFromInstance } from '@warp-drive/core-types/record'; import { DelegatingSchemaService } from '@ember-data/model/migration-support'; import type Model from '@ember-data/model'; // [!code focus] import { instantiateRecord as instantiateModel, // [!code focus] modelFor, teardownRecord as teardownModel // [!code focus] } from '@ember-data/model'; import { instantiateRecord, // [!code focus] registerDerivations, SchemaService, teardownRecord // [!code focus] } from '@warp-drive/schema-record'; export default class AppStore extends Store { requestManager = new RequestManager() .use([Fetch]) .useCache(CacheHandler); createSchemaService() { const schema = new SchemaService(); registerDerivations(schema); return new DelegatingSchemaService(this, schema); } createCache(capabilities: CacheCapabilitiesManager) { return new JSONAPICache(capabilities); } instantiateRecord(key: ResourceKey, createArgs?: Record) { // [!code focus:6] if (this.schema.isDelegated(key)) { return instantiateModel.call(this, key, createRecordArgs) } return instantiateRecord(this, key, createArgs); } teardownRecord(record: unknown): void { // [!code focus:7] const key = recordIdentifierFor(record); if (this.schema.isDelegated(key)) { return teardownModel.call(this, record as Model); } return teardownRecord(record); } modelFor(type: TypeFromInstance): ModelSchema; modelFor(type: string): ModelSchema; modelFor(type: string): ModelSchema { return (modelFor.call(this, type) as ModelSchema) || super.modelFor(type); } } ``` ::: ### Decide How Long Requests are Valid for with a CachePolicy And of course, what's a great cache without an eviction policy? ***Warp*Drive** provides an interface for creating Cache Policies. Whenever a request is made, the policy is checked to determine if the current cached representation is still valid. Policies also have the ability to subscribe to cache updates and issue invalidation notifications. The `` component subscribes to these notifications and will trigger a reload if necessary if an invalidated request is in active use, letting you craft advanced policies that meet your product's needs. ***Warp*Drive** provides a basic [CachePolicy](/api/@warp-drive/core/types/CachePolicy), [`DefaultCachePolicy`](/api/@warp-drive/core/store/classes/DefaultCachePolicy) (re-exported by `@ember-data/request-utils` as `CachePolicy`), with a number of great defaults that is a great starting point for most applications. We configure this basic policy below. The basic policy will invalidate requests based on caching and date headers available on request responses, falling back to a simple time based policy. ```ts import Store, { CacheHandler } from '@ember-data/store'; import type { CacheCapabilitiesManager } from '@ember-data/store/types'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import { CachePolicy } from '@ember-data/request-utils'; // [!code focus] import JSONAPICache from '@ember-data/json-api'; import type { ResourceKey } from '@warp-drive/core-types'; import { instantiateRecord, registerDerivations, SchemaService, teardownRecord } from '@warp-drive/schema-record'; export default class AppStore extends Store { requestManager = new RequestManager() .use([Fetch]) .useCache(CacheHandler); lifetimes = new CachePolicy({ // [!code focus:9] apiCacheHardExpires: 15 * 60 * 1000, // 15 minutes apiCacheSoftExpires: 1 * 30 * 1000, // 30 seconds constraints: { headers: { 'X-WarpDrive-Expires': true, 'Cache-Control': true, 'Expires': true, } } }); createSchemaService() { const schema = new SchemaService(); registerDerivations(schema); return schema; } createCache(capabilities: CacheCapabilitiesManager) { return new JSONAPICache(capabilities); } instantiateRecord(key: ResourceKey, createArgs?: Record) { return instantiateRecord(this, key, createArgs); } teardownRecord(record: unknown): void { return teardownRecord(record); } } ``` ### Configure Your Framework The final setup step is to configure reactivity for your framework. See each framework's guide for this step. * [Ember.js](./ember.md) ## Configure ESLint 🚧 Under Construction --- --- url: https://canary.warp-drive.io/guides/the-manual/typescript/configuration.md description: >- Add the unstable-preview-types entries to tsconfig.json so your app consumes WarpDrive's alpha-stage native types from either the runtime packages or the -types packages. --- :::warning Legacy guide This guide covers a legacy setup. `@warp-drive/core` and the other current packages ship their own types, so new apps can skip this page and follow [Installation](/guides/installation/index.md) instead. ::: # Configuration There are currently two ways to gain access to WarpDrives's native types. Follow the configuration guide below for the [installation](./installation.md) option you chose. 1. [Use A Version That Has Types](#using-native-types) 2. [Use Official Types Packages](#using-types-packages) with releases `>= 4.12.*` > \[!IMPORTANT] > WarpDrive's Native Types require the use of Ember's > Native Types, the configuration below will also setup > Your application to consume Ember's Native Types. ### Using Native Types To consume `alpha` stage types, you must import the types in your project's `tsconfig.json`. For alpha stage types, we add `unstable-preview-types` to the path to help you remember the potential volatility. ```json { "compilerOptions": { "types": [ "ember-source/types", "ember-data/unstable-preview-types", // [!code ++:13] "@ember-data/store/unstable-preview-types", "@ember-data/adapter/unstable-preview-types", "@ember-data/graph/unstable-preview-types", "@ember-data/json-api/unstable-preview-types", "@ember-data/legacy-compat/unstable-preview-types", "@ember-data/request/unstable-preview-types", "@ember-data/request-utils/unstable-preview-types", "@ember-data/model/unstable-preview-types", "@ember-data/serializer/unstable-preview-types", "@warp-drive/core-types/unstable-preview-types", "@warp-drive/build-config/unstable-preview-types", "@warp-drive/schema-record/unstable-preview-types" ] } } ``` ### Using Types Packages To consume `alpha` stage types, you must import the types in your project's `tsconfig.json`. For alpha stage types, we add `unstable-preview-types` to the path to help you remember the potential volatility. ```diff { "compilerOptions": { + "types": [ + "ember-source/types", + "ember-data-types/unstable-preview-types", + "@ember-data-types/store/unstable-preview-types", + "@ember-data-types/adapter/unstable-preview-types", + "@ember-data-types/graph/unstable-preview-types", + "@ember-data-types/json-api/unstable-preview-types", + "@ember-data-types/legacy-compat/unstable-preview-types", + "@ember-data-types/request/unstable-preview-types", + "@ember-data-types/request-utils/unstable-preview-types", + "@ember-data-types/model/unstable-preview-types", + "@ember-data-types/serializer/unstable-preview-types", + "@warp-drive-types/core-types/unstable-preview-types" + ] } } ``` --- --- url: https://canary.warp-drive.io/guides/the-manual/typescript/installation.md description: >- Install WarpDrive's native types with `npx warp-drive retrofit types@canary` or by hand, replacing DefinitelyTyped @types packages with typed releases or -types packages. --- :::warning Legacy guide This guide covers a legacy setup. `@warp-drive/core` and the other current packages ship their own types, so new apps can skip this page and follow [Installation](/guides/installation/index.md) instead. ::: # Installation WarpDrive now provides a cli that will handle installation and configuration for you when installing the types-packages for native types to use with older releases (such as 4.12). ```sh npx warp-drive retrofit types@canary ``` The cli will * uninstall DT packages for ember-source and ember-data * add native types as sources to your ts-config for both ember-source and ember-data * install all required types packages for ember-data based on the dependencies in your package.json The cli may also be used to update to the latest canary versions of the types by simply running the command again. For additional documentation or to manually install and configure, continue reading the below guide. *** > \[!CAUTION] > EmberData does not maintain the DefinitelyTyped types for > EmberData (e.g. the `@types/ember-data__*`). If you were > previously using these, you should uninstall them first. > \[!IMPORTANT] > EmberData's Native Types require the use of Ember's > Native Types. > > Type definitions need to be installed top-level, this means > you have to install every EmberData package `ember-data` > depends on. > \[!TIP] > When installing packages, use an NPM dist tag to get the latest > version for a given channel. E.g. `pnpm install ember-data@latest` > valid channels with types are `latest`, `canary`, `v4-latest` and `v4-canary` There are currently two ways to gain access to EmberData's native types. 1. [Use A Version That Has Types](#using-versions-that-supply-types) 2. [Use Official Types Packages](#using-types-packages) with releases `>= 4.12.*` *** ### Using Versions That Supply Types The following versions supply their own type definitions. These type definitions will still need to be configured for use in tsconfig. * Versions of 4.x >= 4.13.0-alpha.0 * Versions of 5.x >= 5.3.8 In order to use the types for these versions, the dependencies of `ember-data` (and their peer-dependencies) must also be added to `package.json`. Generally that means the following packages are needed, though you may need fewer (or more!) depending on if you have migrated away from Adapter/Serializer and replaced [Model](/api/@warp-drive/legacy/model/classes/Model) with [ReactiveResource](/api/@warp-drive/core/reactive/types/ReactiveResource): | Name | Latest | Canary | V4 | | ---- | -------| ------ | -- | | [ember-data](https://github.com/warp-drive-data/warp-drive/blob/main/packages/-ember-data/README.md) | ![NPM Stable Version](https://img.shields.io/npm/v/ember-data/latest?label=\&color=90EE90) | ![NPM Canary Version](https://img.shields.io/npm/v/ember-data/canary?label=\&color=90EE90) | ![NPM V4 Version](https://img.shields.io/npm/v/ember-data/v4-canary?label=\&color=90EE90) | | [@ember-data/adapter](https://github.com/warp-drive-data/warp-drive/blob/main/packages/adapter/README.md) | ![NPM Stable Version](https://img.shields.io/npm/v/%40ember-data/adapter/latest?label=\&color=90EE90) | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data/adapter/canary?label=\&color=90EE90) | ![NPM V4 Version](https://img.shields.io/npm/v/%40ember-data/adapter/v4-canary?label=\&color=90EE90) | | [@ember-data/graph](https://github.com/warp-drive-data/warp-drive/blob/main/packages/graph/README.md) | ![NPM Stable Version](https://img.shields.io/npm/v/%40ember-data/graph/latest?label=\&color=90EE90) | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data/graph/canary?label=\&color=90EE90) | ![NPM V4 Version](https://img.shields.io/npm/v/%40ember-data/graph/v4-canary?label=\&color=90EE90) | | [@ember-data/json-api](https://github.com/warp-drive-data/warp-drive/blob/main/packages/json-api/README.md) | ![NPM Stable Version](https://img.shields.io/npm/v/%40ember-data/json-api/latest?label=\&color=90EE90) | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data/json-api/canary?label=\&color=90EE90) | ![NPM V4 Version](https://img.shields.io/npm/v/%40ember-data/json-api/v4-canary?label=\&color=90EE90) | | [@ember-data/legacy-compat](https://github.com/warp-drive-data/warp-drive/blob/main/packages/legacy-compat/README.md) | ![NPM Stable Version](https://img.shields.io/npm/v/%40ember-data/legacy-compat/latest?label=\&color=90EE90) | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data/legacy-compat/canary?label=\&color=90EE90) | ![NPM V4 Version](https://img.shields.io/npm/v/%40ember-data/legacy-compat/v4-canary?label=\&color=90EE90) | | [@ember-data/model](https://github.com/warp-drive-data/warp-drive/blob/main/packages/model/README.md) | ![NPM Stable Version](https://img.shields.io/npm/v/%40ember-data/model/latest?label=\&color=90EE90) | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data/model/canary?label=\&color=90EE90) | ![NPM V4 Version](https://img.shields.io/npm/v/%40ember-data/model/v4-canary?label=\&color=90EE90) | | [@ember-data/request](https://github.com/warp-drive-data/warp-drive/blob/main/packages/request/README.md) | ![NPM Stable Version](https://img.shields.io/npm/v/%40ember-data/request/latest?label=\&color=90EE90) | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data/request/canary?label=\&color=90EE90) | ![NPM V4 Version](https://img.shields.io/npm/v/%40ember-data/request/v4-canary?label=\&color=90EE90) | | [@ember-data/request-utils](https://github.com/warp-drive-data/warp-drive/blob/main/packages/request-utils/README.md) | ![NPM Stable Version](https://img.shields.io/npm/v/%40ember-data/request-utils/latest?label=\&color=90EE90) | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data/request-utils/canary?label=\&color=90EE90) | ![NPM V4 Version](https://img.shields.io/npm/v/%40ember-data/request-utils/v4-canary?label=\&color=90EE90) | | [@ember-data/serializer](https://github.com/warp-drive-data/warp-drive/blob/main/packages/serializer/README.md) | ![NPM Stable Version](https://img.shields.io/npm/v/%40ember-data/serializer/latest?label=\&color=90EE90) | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data/serializer/canary?label=\&color=90EE90) | ![NPM V4 Version](https://img.shields.io/npm/v/%40ember-data/serializer/v4-canary?label=\&color=90EE90) | | [@ember-data/store](https://github.com/warp-drive-data/warp-drive/blob/main/packages/store/README.md) | ![NPM Stable Version](https://img.shields.io/npm/v/%40ember-data/store/latest?label=\&color=90EE90) | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data/store/canary?label=\&color=90EE90) | ![NPM V4 Version](https://img.shields.io/npm/v/%40ember-data/store/v4-canary?label=\&color=90EE90) | | [@warp-drive/core-types](https://github.com/warp-drive-data/warp-drive/blob/main/packages/core-types/README.md) | ![NPM Latest Version](https://img.shields.io/npm/v/%40warp-drive/core-types/latest?label=\&color=90EE90) | ![NPM Canary Version](https://img.shields.io/npm/v/%40warp-drive/core-types/canary?label=\&color=90EE90) | ![NPM V4 Version](https://img.shields.io/npm/v/%40warp-drive/core-types/v4-canary?label=\&color=90EE90) | Here's a single install command for pnpm. Swap pnpm for yarn or npm as needed. ``` PACKAGES=("@types/ember" "@types/ember-data" "@types/ember-data__adapter" "@types/ember-data__model" "@types/ember-data__serializer" "@types/ember-data__store" "@types/ember__application" "@types/ember__array" "@types/ember__component" "@types/ember__controller" "@types/ember__debug" "@types/ember__destroyable" "@types/ember__engine" "@types/ember__error" "@types/ember__helper" "@types/ember__modifier" "@types/ember__object" "@types/ember__owner" "@types/ember__routing" "@types/ember__runloop" "@types/ember__service" "@types/ember__string" "@types/ember__template" "@types/ember__test" "@types/ember__utils" "ember-data" ); for pkg in "${PACKAGES[@]}"; do pnpm remove "$pkg"; done pnpm install ember-data@latest @ember-data/adapter@latest @ember-data/graph@latest @ember-data/json-api@latest @ember-data/legacy-compat@latest @ember-data/model@latest @ember-data/request@latest @ember-data/request-utils@latest @ember-data/serializer@latest @ember-data/store@latest @warp-drive/core-types@latest ``` Here's an example change to package.json which drops all use of types from `@types/` for both Ember and EmberData and adds the appropriate canary packages. ```diff - "@types/ember": "4.0.11", - "@types/ember-data": "4.4.16", - "@types/ember-data__adapter": "4.0.6", - "@types/ember-data__model": "4.0.5", - "@types/ember-data__serializer": "4.0.6", - "@types/ember-data__store": "4.0.7", - "@types/ember__application": "4.0.11", - "@types/ember__array": "4.0.10", - "@types/ember__component": "4.0.22", - "@types/ember__controller": "4.0.12", - "@types/ember__debug": "4.0.8", - "@types/ember__destroyable": "4.0.5", - "@types/ember__engine": "4.0.11", - "@types/ember__error": "4.0.6", - "@types/ember__helper": "4.0.7", - "@types/ember__modifier": "4.0.9", - "@types/ember__object": "4.0.12", - "@types/ember__owner": "4.0.9", - "@types/ember__routing": "4.0.22", - "@types/ember__runloop": "4.0.10", - "@types/ember__service": "4.0.9", - "@types/ember__string": "3.16.3", - "@types/ember__template": "4.0.7", - "@types/ember__test": "4.0.6", - "@types/ember__utils": "4.0.7", - "ember-data": "~5.3.3", + "ember-data": "5.4.1-alpha.64", + "@ember-data/store": "5.4.1-alpha.64", + "@ember-data/adapter": "5.4.1-alpha.64", + "@ember-data/graph": "5.4.1-alpha.64", + "@ember-data/json-api": "5.4.1-alpha.64", + "@ember-data/legacy-compat": "5.4.1-alpha.64", + "@ember-data/request": "5.4.1-alpha.64", + "@ember-data/request-utils": "5.4.1-alpha.64", + "@ember-data/serializer": "5.4.1-alpha.64", + "@ember-data/model": "5.4.1-alpha.64", + "@warp-drive/core-types": "0.0.0-alpha.50", ``` > \[!TIP] > If your package manager enables deduping, we recommend deduping types as much as possible. > \[!TIP] > It is best to ensure no other dependencies are still bringing `@types/*` packages as this will cause weird type bugs. *** ### Using Types Packages > \[!WARNING] > When consuming types in this way, you may sometimes > encounter a misalignment between the types and the actual API. These misalignments should be rare for 4.12.\* => 5.4.\*. Overall, even when these misalignments occur, we suspect there are fewer mistakes or issues with these types than in the DefinitelyTyped types. Every package in the project that ships types also publishes its types under a second package name. This enables older releases to consume these types instead of relying on the DefinitelyTyped project. These types-only packages have the same version number as the version they were published with, and their org or name is suffixed with `-types`. **Required Packages for Types** | Name | Types Package | Version | | ---- | ------- | ------- | | [ember-data](https://github.com/warp-drive-data/warp-drive/blob/main/packages/-ember-data/README.md) | ember-data-types | ![NPM Canary Version](https://img.shields.io/npm/v/ember-data-types/canary?label=\&color=90EE90) | | [@ember-data/adapter](https://github.com/warp-drive-data/warp-drive/blob/main/packages/adapter/README.md) | @ember-data-types/adapter | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data-types/adapter/canary?label=\&color=90EE90) | | [@ember-data/graph](https://github.com/warp-drive-data/warp-drive/blob/main/packages/graph/README.md) | @ember-data-types/graph | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data-types/graph/canary?label=\&color=90EE90) | | [@ember-data/json-api](https://github.com/warp-drive-data/warp-drive/blob/main/packages/json-api/README.md) | @ember-data-types/json-api | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data-types/json-api/canary?label=\&color=90EE90) | | [@ember-data/legacy-compat](https://github.com/warp-drive-data/warp-drive/blob/main/packages/legacy-compat/README.md) | @ember-data-types/legacy-compat | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data-types/legacy-compat/canary?label=\&color=90EE90) | | [@ember-data/model](https://github.com/warp-drive-data/warp-drive/blob/main/packages/model/README.md) | @ember-data-types/model | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data-types/model/canary?label=\&color=90EE90) | | [@ember-data/request](https://github.com/warp-drive-data/warp-drive/blob/main/packages/request/README.md) | @ember-data-types/request | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data-types/request/canary?label=\&color=90EE90) | | [@ember-data/request-utils](https://github.com/warp-drive-data/warp-drive/blob/main/packages/request-utils/README.md) | @ember-data-types/request-utils | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data-types/request-utils/canary?label=\&color=90EE90) | | [@ember-data/serializer](https://github.com/warp-drive-data/warp-drive/blob/main/packages/serializer/README.md) | @ember-data-types/serializer | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data-types/serializer/canary?label=\&color=90EE90) | | [@ember-data/store](https://github.com/warp-drive-data/warp-drive/blob/main/packages/store/README.md) | @ember-data-types/store | ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data-types/store/canary?label=\&color=90EE90) | | [@warp-drive/core-types](https://github.com/warp-drive-data/warp-drive/blob/main/packages/core-types/README.md) | @warp-drive-types/core-types | ![NPM Canary Version](https://img.shields.io/npm/v/%40warp-drive-types/core-types/canary?label=\&color=90EE90) | Here's a single install command for pnpm. Swap pnpm for yarn or npm as needed. ``` pnpm install ember-data-types@canary @ember-data-types/adapter@canary @ember-data-types/graph@canary @ember-data-types/json-api@canary @ember-data-types/legacy-compat@canary @ember-data-types/model@canary @ember-data-types/request@canary @ember-data-types/request-utils@canary @ember-data-types/serializer@canary @ember-data-types/store@canary @warp-drive-types/core-types@canary ``` Here's an example change to package.json which drops all use of types from `@types/` for both Ember and EmberData and adds the appropriate canary packages. ```diff - "@types/ember": "4.0.11", - "@types/ember-data": "4.4.16", - "@types/ember-data__adapter": "4.0.6", - "@types/ember-data__model": "4.0.5", - "@types/ember-data__serializer": "4.0.6", - "@types/ember-data__store": "4.0.7", - "@types/ember__application": "4.0.11", - "@types/ember__array": "4.0.10", - "@types/ember__component": "4.0.22", - "@types/ember__controller": "4.0.12", - "@types/ember__debug": "4.0.8", - "@types/ember__destroyable": "4.0.5", - "@types/ember__engine": "4.0.11", - "@types/ember__error": "4.0.6", - "@types/ember__helper": "4.0.7", - "@types/ember__modifier": "4.0.9", - "@types/ember__object": "4.0.12", - "@types/ember__owner": "4.0.9", - "@types/ember__routing": "4.0.22", - "@types/ember__runloop": "4.0.10", - "@types/ember__service": "4.0.9", - "@types/ember__string": "3.16.3", - "@types/ember__template": "4.0.7", - "@types/ember__test": "4.0.6", - "@types/ember__utils": "4.0.7", + "@ember-data-types/adapter": "^5.4.1-alpha.64", + "@ember-data-types/model": "^5.4.1-alpha.64", + "@ember-data-types/serializer": "^5.4.1-alpha.64", + "@ember-data-types/store": "^5.4.1-alpha.64", + "@ember-data-types/graph": "^5.4.1-alpha.64", + "@ember-data-types/json-api": "^5.4.1-alpha.64", + "@ember-data-types/legacy-compat": "^5.4.1-alpha.64", + "@ember-data-types/request": "^5.4.1-alpha.64", + "@ember-data-types/request-utils": "^5.4.1-alpha.64", + "@warp-drive-types/core-types": "^0.0.0-alpha.50", "ember-data": "^4.12.7", + "ember-data-types": "^5.4.1-alpha.64", ``` --- --- url: https://canary.warp-drive.io/guides/the-manual/typescript/typing-models.md description: >- Brand legacy Model classes and Transforms with the `Type` symbol and add generics to `attr`, `belongsTo`, and `hasMany` so relationships and store calls infer types. --- :::warning Legacy guide This guide covers a legacy setup. New code should define its data with [ResourceSchemas](/guides/the-manual/schemas/resources/index.md) instead of Models. ::: # Typing Models & Transforms ## Type Example: add the `Type` brand to the `user` model. ```ts import Model, { attr } from '@warp-drive/legacy/model'; import { Type } from '@warp-drive/core/types/symbols'; export default class User extends Model { @attr declare name: string; [Type] = 'user' as const; } ``` The benefit of the above is that the value of Type is readable at runtime and thus easy to debug. However, you can also choose to do this via types only: ```ts import Model, { attr } from '@warp-drive/legacy/model'; import type { Type } from '@warp-drive/core/types/symbols'; export default class User extends Model { @attr declare name: string; declare [Type]: 'user'; } ``` WarpDrive will never access Type as an actual value, these brands are *purely* for type inference. ## Transforms Transforms with a `Type` brand will have their type and options validated. Once we move to stage-3 decorators, the signature of the field would also be validated against the transform. Example: Typing a Transform ```ts import type { Type } from '@warp-drive/core/types/symbols'; export default class BigIntTransform { deserialize(serialized: string): BigInt | null { return !serialized || serialized === '' ? null : BigInt(serialized + 'n'); } serialize(deserialized: BigInt | null): string | null { return !deserialized ? null : String(deserialized); } declare [Type]: 'big-int'; static create() { return new this(); } } ``` Example: Using Transforms ```ts import Model, { attr } from '@warp-drive/legacy/model'; import type { StringTransform } from '@warp-drive/legacy/serializer/transform'; import type { Type } from '@warp-drive/core/types/symbols'; export default class User extends Model { @attr('string') declare name: string; declare [Type]: 'user'; } ``` ## Sync BelongsTo `belongsTo` relationships will have their resource type and options config validated against the passed in type. Once we move to stage-3 decorators, explicitly setting the generic would not be required as it could be inferred from the field's type. ```ts import Model, { belongsTo } from '@warp-drive/legacy/model'; import type Address from './address'; import { Type } from '@warp-drive/core/types/symbols'; export default class User extends Model { @belongsTo
('address', { async: false, inverse: null }) declare address: Address; [Type] = 'user' as const; } ``` ## Async BelongsTo `belongsTo` relationships will have their resource type and options config validated against the passed in type. Once we move to stage-3 decorators, explicitly setting the generic would not be required as it could be inferred from the field's type. ```ts import Model, { belongsTo, AsyncBelongsTo } from '@warp-drive/legacy/model'; import type Address from './address'; import { Type } from '@warp-drive/core/types/symbols'; export default class User extends Model { @belongsTo
('address', { async: true, inverse: null }) declare address: AsyncBelongsTo
; [Type] = 'user' as const; } ``` ## Sync HasMany (data only) If you don't need access to meta or links on relationships, you can type the relationship as just an array. `hasMany` relationships will have their resource type and options config validated against the passed in type. Once we move to stage-3 decorators, explicitly setting the generic would not be required as it could be inferred from the field's type. ```ts import Model, { hasMany } from '@warp-drive/legacy/model'; import type Post from './post'; import { Type } from '@warp-drive/core/types/symbols'; export default class User extends Model { @hasMany('post', { async: false, inverse: 'author' }) declare posts: Post[]; [Type] = 'user' as const; } ``` ## Sync HasMany (with meta, links, etc) `hasMany` relationships will have their resource type and options config validated against the passed in type. Once we move to stage-3 decorators, explicitly setting the generic would not be required as it could be inferred from the field's type. ```ts import Model, { hasMany, HasMany } from '@warp-drive/legacy/model'; import type Post from './post'; import { Type } from '@warp-drive/core/types/symbols'; export default class User extends Model { @hasMany('post', { async: false, inverse: 'author' }) declare posts: HasMany; [Type] = 'user' as const; } ``` ## Async HasMany (restricted) If you don't need access to meta, links or template iterations on relationships, you can type the relationship as just a promise resolving to an array. Only use this if the value will always be awaited before iteration. `hasMany` relationships will have their resource type and options config validated against the passed in type. Once we move to stage-3 decorators, explicitly setting the generic would not be required as it could be inferred from the field's type. ```ts import Model, { hasMany, AsyncHasMany } from '@warp-drive/legacy/model'; import type Post from './post'; import { Type } from '@warp-drive/core/types/symbols'; export default class User extends Model { @hasMany('post', { async: true, inverse: 'author' }) declare posts: Promise; [Type] = 'user' as const; } ``` `Promise>` also works. ## Async HasMany (with links, meta, etc.) `hasMany` relationships will have their resource type and options config validated against the passed in type. Once we move to stage-3 decorators, explicitly setting the generic would not be required as it could be inferred from the field's type. ```ts import Model, { hasMany, AsyncHasMany } from '@warp-drive/legacy/model'; import type Post from './post'; import { Type } from '@warp-drive/core/types/symbols'; export default class User extends Model { @hasMany('post', { async: true, inverse: 'author' }) declare posts: AsyncHasMany; [Type] = 'user' as const; } ``` --- --- url: https://canary.warp-drive.io/upgrading/v5/codemods.md description: >- Run the `@ember-data/codemods` migrate-to-schema and legacy-compat-builders codemods to convert 4.x Models and mixins into 5.x schemas and store.request builders. --- :::warning Legacy guide This guide covers a legacy setup. New apps should start from [Installation](/guides/installation/index.md) and [Setup](/guides/configuration/index.md) instead. ::: # Using Codemods WarpDrive provides automated codemods to help migrate your EmberData application to modern WarpDrive patterns. The `@ember-data/codemods` package includes tools for transforming models and mixins into schemas, updating legacy store methods, and managing package dependencies. > \[!NOTE] > The codemods are under active development. Missing features and bugs are expected - please report any issues you find! ## Getting Started > \[!NOTE] > The codemods require Node.js `>= 22.2` and run on macOS, Linux (glibc and musl/Alpine), > and Windows, on both x64 and arm64. `pnpm dlx` works as well as `npx`. ### Listing Available Codemods ```bash npx @ember-data/codemods list ``` This will print the available codemods: | Codemod | Description | |---|---| | `migrate-to-schema` | Migrates EmberData models and mixins to WarpDrive schemas | | `legacy-compat-builders` | Updates legacy store methods to use `store.request` and builders | ### Running a Codemod ```bash npx @ember-data/codemods apply [options] ``` To see the options for a specific codemod: ```bash npx @ember-data/codemods apply --help ``` ## migrate-to-schema This codemod transforms EmberData models and mixins into WarpDrive's schema format. For each model it generates: * **Schema files** - Define the data structure using [`LegacyResourceSchema`](/api/@warp-drive/core/types/schema/fields/types/LegacyResourceSchema) * **Type files** - TypeScript interfaces for the resource * **Extension files** - Preserve computed properties, methods, and other non-data logic * **Trait files** - Reusable schema components extracted from mixins The codemod is **non-destructive** - original model files are not removed. New files are generated in the `app/data/` by default. ### Basic Usage ```bash # Transform all models and mixins (looks at ./app by default) npx @ember-data/codemods apply migrate-to-schema --project-name my-app # With custom search path npx @ember-data/codemods apply migrate-to-schema --project-name my-app ./packages/ember-app/app # Specify the WarpDrive import preset npx @ember-data/codemods apply migrate-to-schema --project-name my-app --warp-drive-imports legacy ``` | Option | Description | |---|---| | `--project-name ` | Project name for resolving classic ember module imports (e.g., `my-app/models/user`) | | `--warp-drive-imports ` | WarpDrive import preset: `legacy` (default, `@ember-data/*`), `modern` (`@warp-drive/*`), or `mirror` (`@warp-drive-mirror/*`) | | `--config ` | Path to a JSON configuration file | | `--skip-processed` | Skip files that have already been processed | | `--force-typescript` | Force all output files to TypeScript (`.ts`) | | `--model-source-dir ` | Directory containing model files (default: `./app/models`) | | `--mixin-source-dir ` | Directory containing mixin files (default: `./app/mixins`) | | `--output-dir ` | Output directory for generated schemas (default: `./app/data`) | ### Configuration When the defaults aren't enough: For projects with custom base classes, re-exported models, or monorepo structures, the codemod accepts a JSON configuration file: ```bash npx @ember-data/codemods apply migrate-to-schema --config=./codemod.config.json ``` > \[!TIP] > For the full list of available configuration options, see the [config type definition](https://github.com/warp-drive-data/warp-drive/blob/main/packages/codemods/src/schema-migration/config.ts) and the [JSON schema](https://github.com/warp-drive-data/warp-drive/blob/main/packages/codemods/src/schema-migration/config-schema.json). #### Simple Configuration For most projects, a minimal config is all you need. The `warpDriveImports` option tells the codemod which package set your app uses for WarpDrive APIs - `"legacy"` for classic `@ember-data/*` packages, `"modern"` for the new `@warp-drive/*` packages: ```json { "projectName": "example-app", "warpDriveImports": "legacy", "typeMapping": { "uuid": "string", "currency": "number", "json": "unknown" } } ``` #### Complex Configuration For projects with custom import sources, intermediate base classes, or monorepo structures where models and mixins live across multiple packages: ```json { "projectName": "example-app", "emberDataImportSource": "@example-org/warp-drive/v1/model", "resourcesImport": "example-app/data/resources", "forceTypeScript": true, "typeMapping": { "uuid": "string", "currency": "number", "json": "unknown" }, "warpDriveImports": { "Model": { "imported": "default", "source": "@example-org/warp-drive/v1/model" }, "Type": { "imported": "Type", "source": "@example-org/warp-drive/v1/core-types/symbols" }, "WithLegacy": { "imported": "WithLegacy", "source": "@example-org/warp-drive/v1/model/migration-support" }, "withDefaults": { "imported": "withDefaults", "source": "@example-org/warp-drive/v1/model/migration-support" }, "LegacyResourceSchema": { "imported": "LegacyResourceSchema", "source": "@example-org/warp-drive/v1/core-types/schema/fields" } }, "intermediateModelPaths": [ "example-app/core/data-field-model", "@example-org/client-core/mixins/base-model", "../core/base-model" ], "additionalMixinSources": [ { "pattern": "@example-org/core/mixins/*", "dir": "../../libraries/core/package/src/mixins/*" } ], "additionalModelSources": [ { "pattern": "example-app/core/", "dir": "./app/core/" }, { "pattern": "../core/", "dir": "./app/core/" } ] } ``` Key configuration options: * **`projectName`** - The Ember app name, used for resolving classic module imports like `example-app/models/user`. * **`emberDataImportSource`** / **`warpDriveImports`** - Tell the codemod where your app imports EmberData and WarpDrive APIs from, when they differ from the defaults (`@ember-data/model`, `@warp-drive/core`, etc.). * **`typeMapping`** - Maps custom EmberData transform names (e.g., `@attr('uuid')`) to TypeScript types for the generated type files. * **`intermediateModelPaths`** - Import paths of base classes between [`Model`](/api/@warp-drive/legacy/model/classes/Model) and your concrete models. The codemod will analyze these and convert them to traits. * **`importSubstitutes`** - For base classes whose source can't be analyzed, tells the codemod what trait/extension names to reference. * **`additionalModelSources`** / **`additionalMixinSources`** - Maps import patterns to on-disk directories so the codemod can locate source files that live outside the main `app/` directory (e.g., in a monorepo's shared libraries). ### What Gets Generated Given a model like: ```ts // app/models/user.ts import Model, { attr, belongsTo, hasMany } from '@ember-data/model'; import type { Type } from '@warp-drive/core-types/symbols'; export default class User extends Model { declare [Type]: 'user'; @attr('string') declare name: string; @attr('string') declare email: string; @belongsTo('company', { async: false, inverse: null }) declare company: Company; @hasMany('post', { async: true, inverse: 'author' }) declare posts: Post[]; get displayName() { return this.name || this.email; } } ``` The codemod produces: ::: code-group ```ts [app/data/resources/user/schema.ts] import { withDefaults } from '@warp-drive/legacy/model/migration-support'; export const UserSchema = withDefaults({ type: 'user', fields: [ { kind: 'attribute', name: 'name', type: 'string' }, { kind: 'attribute', name: 'email', type: 'string' }, { kind: 'belongsTo', name: 'company', type: 'company', options: { async: false, inverse: null }, }, { kind: 'hasMany', name: 'posts', type: 'post', options: { async: true, inverse: 'author' }, }, ], objectExtensions: ['user-extension'], }); ``` ```ts [app/data/resources/user/type.ts] import type { Type } from '@warp-drive/core/types/symbols'; import { WithLegacy } from '@warp-drive/legacy/model/migration-support'; export interface User { [Type]: 'user'; name: string; email: string; company: Company; posts: Post[]; } export type LegacyUser = WithLegacy; ``` ```ts [app/data/resources/user/ext.ts] import type { LegacyUser } from './type'; export interface UserExtension extends LegacyUser {} export class UserExtension { get displayName() { return this.name || this.email; } } const Registration = { name: 'user-extension', kind: 'object', features: UserExtension, }; export default Registration; ``` ::: ### Mixins Become Traits Mixins are decomposed into trait schemas and extensions: ::: tabs \== Before ```ts // app/mixins/timestamped.ts import Mixin from '@ember/object/mixin'; import { attr } from '@ember-data/model'; export default Mixin.create({ createdAt: attr(), updatedAt: attr(), async softDelete() { // ... } }); ``` \== After ::: code-group ```ts [app/data/traits/timestamped/schema.ts] export const TimestampedTrait = { name: 'timestamped', mode: 'legacy', fields: [ { kind: 'attribute', name: 'createdAt' }, { kind: 'attribute', name: 'updatedAt' }, ], }; ``` ```ts [app/data/traits/timestamped/type.ts] export interface Timestamped { createdAt: unknown; updatedAt: unknown; } ``` ```ts [app/data/traits/timestamped/ext.ts] import type { Timestamped } from './type'; export interface TimestampedExtension extends Timestamped {} export class TimestampedExtension { async softDelete() { // ... } } const Registration = { kind: 'object', name: 'timestamped-extension', features: TimestampedExtension, }; export default Registration; ``` ::: Models that use the mixin will reference the trait and extension by name in their generated schemas: ```ts export const UserSchema = withDefaults({ type: 'user', fields: [/* ... */], traits: ['timestamped'], objectExtensions: ['timestamped-extension', 'user-extension'], }); ``` ### Caveats * **Parent / base classes require manual migration.** The codemod does not reliably migrate abstract base classes such as `BaseModel` or `DataFieldModel`. If your app has intermediate classes between `Model` and your concrete models, you should migrate those by hand first and then use `importSubstitutes` or `intermediateModelPaths` in your [configuration](#configuration) to tell the codemod how to reference them. * **Re-exported models from libraries are not migrated.** The codemod tries its best to follow imports and locate source files, but models that are re-exported from external packages (e.g., `import MyModel from '@my-org/shared-models/my-model'`) cannot have their source analyzed. These will be skipped. Use `additionalModelSources` to point the codemod at the on-disk location of library code, or migrate those models manually. * **Only the default export is processed per file.** If a file contains multiple classes, only the default export (or `export { X as default }`) is analyzed. Additional class declarations in the same file are silently ignored. Split them into separate files before running the codemod. * Run the codemod, review the output, and iterate on configuration as needed. Most projects will need at least a minimal config file. ### Registering Generated Schemas After the codemod generates your schema, type, and extension files, you need to register them with the WarpDrive store. You can use `import.meta.glob` (available in Vite and Embroider) to bulk-load everything from the generated directories instead of manually importing each file. #### Loading schemas, traits, and extensions ```ts const schemaModules = import.meta.glob('./data/resources/**/*.schema.ts', { eager: true }); const traitModules = import.meta.glob('./data/traits/**/*.schema.ts', { eager: true }); const extensionModules = import.meta.glob( ['./data/resources/**/*.ext.ts', './data/traits/**/*.ext.ts'], { eager: true } ); ``` Each module's default or named export contains the schema/trait/extension object that needs to be registered. #### Registering with `useLegacyStore` [`useLegacyStore`](/api/@warp-drive/legacy/functions/useLegacyStore) accepts `schemas`, `traits`, and `CAUTION_MEGA_DANGER_ZONE_extensions` arrays directly: ```ts import { useLegacyStore } from '@warp-drive/legacy'; import { JSONAPICache } from '@warp-drive/json-api'; const schemas = Object.values(import.meta.glob('../data/resources/**/*.schema.ts', { eager: true, import: 'default' })); const traits = Object.values(import.meta.glob('../data/traits/**/*.schema.ts', { eager: true, import: 'default' })); const extensions = Object.values(import.meta.glob( ['../data/resources/**/*.ext.ts', '../data/traits/**/*.ext.ts'], { eager: true, import: 'default' } )); export default useLegacyStore({ legacyRequests: true, cache: JSONAPICache, schemas, traits, CAUTION_MEGA_DANGER_ZONE_extensions: extensions, }); ``` #### Registering with a custom store If you are using a custom [`Store`](/api/@warp-drive/core/classes/Store) subclass with `createSchemaService()`, register manually on the [`SchemaService`](/api/@warp-drive/core/reactive/classes/SchemaService): ```ts createSchemaService() { const schema = new SchemaService(); registerDerivations(schema); schema.registerResources(schemas); for (const trait of traits) { schema.registerTrait(trait); } for (const extension of extensions) { schema.CAUTION_MEGA_DANGER_ZONE_registerExtension(extension); } return schema; } ``` ## legacy-compat-builders This codemod updates legacy store methods (`findAll`, `findRecord`, `query`, `queryRecord`, `saveRecord`) to use `store.request` with builders from `@ember-data/legacy-compat/builders`. ### Usage ```bash # Transform all files matching the pattern npx @ember-data/codemods apply legacy-compat-builders './app/**/*.{js,ts}' # Transform only specific methods npx @ember-data/codemods apply legacy-compat-builders --methods findRecord query './app/**/*.{js,ts}' # Dry run npx @ember-data/codemods apply legacy-compat-builders --dry './app/**/*.{js,ts}' ``` ### Options | Option | Description | |---|---| | `-d, --dry` | Dry run (no changes made) | | `-v, --verbose ` | Verbosity level (`0`, `1`, `2`) | | `-l, --log-file [path]` | Write logs to a file | | `-i, --ignore ` | Ignore files matching the pattern | | `--store-names ` | Identifier names for the store (default: `["store"]`) | | `--methods ` | Only transform specific methods | ### Examples #### findAll ```ts // before const posts = await store.findAll('post'); // after import { findAll } from '@ember-data/legacy-compat/builders'; const { content: posts } = await store.request(findAll('post')); ``` #### findRecord ```ts // before const post = await store.findRecord({ type: 'post', id: '1' }); // after import { findRecord } from '@ember-data/legacy-compat/builders'; const { content: post } = await store.request(findRecord({ type: 'post', id: '1' })); ``` #### query ```ts // before const posts = await store.query('post', { id: '1' }); // after import { query } from '@ember-data/legacy-compat/builders'; const { content: posts } = await store.request(query('post', { id: '1' })); ``` #### queryRecord ```ts // before const post = await store.queryRecord('post', { id: '1' }); // after import { queryRecord } from '@ember-data/legacy-compat/builders'; const { content: post } = await store.request(queryRecord('post', { id: '1' })); ``` #### saveRecord ```ts // before const post = store.createRecord('post', { name: 'Krystan rules, you drool' }); const saved = await store.saveRecord(post); // after import { saveRecord } from '@ember-data/legacy-compat/builders'; const post = store.createRecord('post', { name: 'Krystan rules, you drool' }); const { content: saved } = await store.request(saveRecord(post)); ``` ### Caveats * Calls to legacy store methods that are **not awaited** will not be transformed. The codemod cannot safely add `await` since it doesn't know if consuming code can handle the change. * **Exception**: In a route's `model` hook, the codemod will transform the call and add `await`. * `store.findRecord` calls with a `preload` option are not transformed, as this option is not supported by the legacy compat builders. * GJS and GTS files are not currently supported. See the [V3/V4 to V5 migration guide](./index.md) for the full migration process including store setup, reactivity configuration, and post-migration cleanup. --- --- url: https://canary.warp-drive.io/upgrading/v5/incremental-adoption.md description: >- Move an existing 4.12 EmberData app still on adapters and serializers onto RequestManager, LegacyNetworkHandler, and request builders one step at a time. --- :::warning Legacy guide This guide covers a legacy setup. New code should set up its store as shown in [Setup](/guides/configuration/index.md) and make requests as shown in [Making Requests](/guides/the-manual/requests/index.md). ::: # Incremental adoption guide for existing projects * ⮐ [Migrating 4.x to 5.x](./index.md) This guide is for existing projects that want to adopt the new APIs of the WarpDrive incrementally. ## Step 1: Upgrade to WarpDrive 4.12.x This version of WarpDrive is the first version that supports the new APIs. It is also an LTS version, so you can stay on it for a while. You can refer the [WarpDrive Compatibility table](https://github.com/warp-drive-data/warp-drive/blob/main/README.md#compatibility) to see which version of WarpDrive is compatible with your Ember version. ## Step 2: Add `Store` service to your application You will need to create your own store service. Before, a store service was automatically injected by 'ember-data'. Here is how you do it: ```js // eslint-disable-next-line ember/use-ember-data-rfc-395-imports import Store from 'ember-data/store'; export default class AppStore extends Store {} ``` Notice we still want to import the `Store` class from `ember-data/store` package. You might have a lint rule that says don't do it. You can disable it for this import. The reason we want to import it from `ember-data/store` is because we want to use WarpDrive models, serializers, adapters, etc. while alongside we want to start utilizing new APIs. > Note: You can also use `@ember-data/store` package, but you will need to configure a lot more to make things work to use old APIs. We recommend using `ember-data/store` package to avoid confusion. > Note: Because we are extending `ember-data/store`, it is still v1 addon, so things might not work for you if you are using typescript. We recommend to have `store.js` file for now. ## Step 3: Add `RequestManager` to your application Now let's configure a [`RequestManager`](/api/@warp-drive/core/classes/RequestManager) for our store. The RequestManager is responsible for sending requests to the server. It fulfills requests using a chain-of-responsibility pipeline, which means you can add your own request handlers to it. First you need to install [`@ember-data/request`](https://github.com/warp-drive-data/warp-drive/tree/main/packages/request) and [`@ember-data/legacy-compat`](https://github.com/warp-drive-data/warp-drive/tree/main/packages/legacy-compat) packages. The first contains the `RequestManager` service and a few request handlers, while the second has [`LegacyNetworkHandler`](/api/@warp-drive/legacy/compat/variables/LegacyNetworkHandler) that will handle all old-style `this.store.*` calls. Here is how your own `RequestManager` service may look like: ```ts // eslint-disable-next-line ember/use-ember-data-rfc-395-imports import Store from 'ember-data/store'; import { CacheHandler } from '@ember-data/store'; import { LegacyNetworkHandler } from '@ember-data/legacy-compat'; import type { Handler, NextFn, RequestContext } from '@ember-data/request'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; /* eslint-disable no-console */ const TestHandler: Handler = { async request(context: RequestContext, next: NextFn) { console.log('TestHandler.request', context.request); const result = await next(Object.assign({}, context.request)); console.log('TestHandler.response after fetch', result.response); return result; }, }; export default class AppStore extends Store { requestManager = new RequestManager() .use([LegacyNetworkHandler, TestHandler, Fetch]) .useCache(CacheHandler); } ``` Let's go over the code above: 1. `LegacyNetworkHandler` is the handler that is responsible for sending requests to the server using the old APIs. It will interrupt handlers chain if it detects request using old APIs. It will process it as it used to be doing with Adapters/Fetch/Serializers workflow. 2. Next is `TestHandler`. It is a handler that is responsible for logging requests. It is a quick example of how you can add your own handlers to the request manager. We will take a look at more useful examples later. 3. Lastly [`Fetch`](/api/@warp-drive/core/variables/Fetch). It is a handler that sends requests to the server using the `fetch` API. It expects responses to be JSON and when in use it should be the last handler you put in the chain. After finishing each request it will convert the response into json and pass it back to the handlers chain in reverse order as the request context's response. So `TestHandler` will receive `response` property first, and so on if we would have any. The [CacheHandler](/api/@warp-drive/core/variables/CacheHandler) is a special handler that enables requests to fulfill from and update the cache associated to this store. You can read more about request manager in the [request manager guide](/guides/the-manual/requests/index.md). ## Step 4: Install `@ember-data/json-api`, `@ember-data/request-utils` packages If you were using JSON:API adapter/serializer for your backend communication, you can use `@ember-data/json-api` package. It is a package that contains predefined builders for JSON:API requests. You can read more about it in the [`@ember-data/json-api`](https://github.com/warp-drive-data/warp-drive/tree/main/packages/json-api). If you have different backend format - WarpDrive provides you with builders for `REST`([`@ember-data/rest`](https://github.com/warp-drive-data/warp-drive/tree/main/packages/rest)) and `ActiveRecord`([`@ember-data/active-record`](https://github.com/warp-drive-data/warp-drive/tree/main/packages/active-record)). `@ember-data/request-utils` package contains a lot of useful utilities for building requests. You can read more about it in its [Readme](https://github.com/warp-drive-data/warp-drive/tree/main/packages/request-utils#readme). It has request builders for all type of requests. ## Step 5: Off you go! Start using new APIs Now you can start refactoring old code to use new APIs. You can start with the `findAll` method. It is the easiest one to refactor. Here is how you do it: ```diff app/components/projects/list.ts + import { query } from '@ember-data/json-api/request'; loadProjects: Task = task(async () => { - const projects = await this.store.findAll('project'); - this.projects = [...projects]; + const { content } = await this.store.request(query('project', {}, { host: config.api.host })); + this.projects = content.data; }); ``` You most likely would need to add Auth Handler to your request manager to add `accessToken` to your requests. Let's say you have your `accessToken` in the `session` service. Here is how you can add it to the request manager: ```js import { service } from '@ember/service'; export default class AuthHandler { @service session; request({ request }, next) { const headers = new Headers(request.headers); headers.append( 'Authorization', `Bearer ${this.session.accessToken}`, ); return next(Object.assign({}, request, { headers })); } } ``` You can read more about auth topic [here](/guides/the-manual/cookbook/auth-handlers.md). Another good thing to do is to configure default host and namespace for your requests. There is an utility for that out of the box of `@ember-data/request-utils` called [`setBuildURLConfig`](/api/@warp-drive/utilities/functions/setBuildURLConfig). You can do it anywhere in your app theoretically, but we recommend doing it in the `app/app.js` file. Here is how you can do it: ```diff app/app.js import Application from '@ember/application'; import Resolver from 'ember-resolver'; import loadInitializers from 'ember-load-initializers'; import config from 'base-ember-typescript-app/config/environment'; +import { setBuildURLConfig } from '@ember-data/request-utils'; + +setBuildURLConfig({ + host: 'https://api.example.com', + namespace: 'v1', +}); export default class App extends Application { modulePrefix = config.modulePrefix; podModulePrefix = config.podModulePrefix; Resolver = Resolver; } loadInitializers(App, config.modulePrefix); ``` *** * ⮐ [Migrating 4.x to 5.x](./index.md) --- --- url: https://canary.warp-drive.io/upgrading/v5.md description: >- Migrate an EmberData 4.6 or 4.12 app to WarpDrive 5.x step by step, using native types, mirror packages, useLegacyStore, and schemas in place of Models. --- :::warning Legacy guide This guide covers a legacy setup. New apps should start from [Installation](/guides/installation/index.md) and [Setup](/guides/configuration/index.md) instead. ::: # Migrating 4.x to 5.x   authored 2023-06-10 This guide will *likely* work for apps on 3.28 that have resolved EmberData deprecations from the 3.x series. This guide is primarily intended for apps that got ***"stuck"*** on either 4.6 (due to ModelFragments) or 4.12 (typically due to the ArrayLike deprecation) Note - it is not actually a requirement of 5.x to replace Models with Schemas (nor to replace adapters/serializers with requests). These things are deprecated *in* 5.x, but they still work. The reason to take the approach outlined in this guide is because we have used capabilities provided by the [@warp-drive/legacy package](/api/@warp-drive/legacy/) and by [LegacyMode](/guides/the-manual/schemas/resources/legacy-mode.md) schemas together with [Extensions](/api/@warp-drive/core/reactive/types/CAUTION_MEGA_DANGER_ZONE_Extension) to mimic much of the removed API surface to allow apps to bridge the gap to 5.x more easily. ## Pre-Migration (update to Native Types) If you use TypeScript, before migrating, you should update your types to use the native types provided by both `ember-source` and WarpDrive. You can do this even if you are on an older version (pre-5.x) that didn't ship it's own types by using the "types" packages we specially publish for this purpose. ### Step 1 - delete all the ember/ember-data DT type packages ```package.json { "dependencies": { "@types/ember": "4.0.11", // [!code --:25] "@types/ember-data": "4.4.16", "@types/ember-data__adapter": "4.0.6", "@types/ember-data__model": "4.0.5", "@types/ember-data__serializer": "4.0.6", "@types/ember-data__store": "4.0.7", "@types/ember__application": "4.0.11", "@types/ember__array": "4.0.10", "@types/ember__component": "4.0.22", "@types/ember__controller": "4.0.12", "@types/ember__debug": "4.0.8", "@types/ember__destroyable": "4.0.5", "@types/ember__engine": "4.0.11", "@types/ember__error": "4.0.6", "@types/ember__helper": "4.0.7", "@types/ember__modifier": "4.0.9", "@types/ember__object": "4.0.12", "@types/ember__owner": "4.0.9", "@types/ember__routing": "4.0.22", "@types/ember__runloop": "4.0.10", "@types/ember__service": "4.0.9", "@types/ember__string": "3.16.3", "@types/ember__template": "4.0.7", "@types/ember__test": "4.0.6", "@types/ember__utils": "4.0.7", } } ``` ### Step 2 - install the official packages using the latest versions. Each package that we publish has a corresponding types-only package that you can use to gain access to official types while still using an older version of the library that doesn't have its own types yet. | Package | Types Package | | ------- | ------------- | | `ember-data` | `ember-data-types` | | `@ember-data/*` | `@ember-data-types/*` | | `@warp-drive/*` | `@warp-drive-types/*` | :::tip 💡 Why are there non-types packages below? Starting in 5.7, due to package unification these types also require the installation of the new "package unification" packages since the actual source code (and types) originates from there. ::: ::: code-group ```sh [pnpm] pnpm add -E ember-data-types@latest \ @ember-data-types/adapter@latest \ @ember-data-types/graph@latest \ @ember-data-types/json-api@latest \ @ember-data-types/legacy-compat@latest \ @ember-data-types/model@latest \ @ember-data-types/request@latest \ @ember-data-types/request-utils@latest \ @ember-data-types/serializer@latest \ @ember-data-types/store@latest \ @warp-drive-types/core-types@latest \ @warp-drive/core@latest \ @warp-drive/json-api@latest \ @warp-drive/legacy@latest \ @warp-drive/utilities@latest ``` ```sh [npm] npm add -E ember-data-types@latest \ @ember-data-types/adapter@latest \ @ember-data-types/graph@latest \ @ember-data-types/json-api@latest \ @ember-data-types/legacy-compat@latest \ @ember-data-types/model@latest \ @ember-data-types/request@latest \ @ember-data-types/request-utils@latest \ @ember-data-types/serializer@latest \ @ember-data-types/store@latest \ @warp-drive-types/core-types@latest \ @warp-drive/core@latest \ @warp-drive/json-api@latest \ @warp-drive/legacy@latest \ @warp-drive/utilities@latest ``` ```sh [yarn] yarn add -E ember-data-types@latest \ @ember-data-types/adapter@latest \ @ember-data-types/graph@latest \ @ember-data-types/json-api@latest \ @ember-data-types/legacy-compat@latest \ @ember-data-types/model@latest \ @ember-data-types/request@latest \ @ember-data-types/request-utils@latest \ @ember-data-types/serializer@latest \ @ember-data-types/store@latest \ @warp-drive-types/core-types@latest \ @warp-drive/core@latest \ @warp-drive/json-api@latest \ @warp-drive/legacy@latest \ @warp-drive/utilities@latest ``` ```sh [bun] bun add --exact ember-data-types@latest \ @ember-data-types/adapter@latest \ @ember-data-types/graph@latest \ @ember-data-types/json-api@latest \ @ember-data-types/legacy-compat@latest \ @ember-data-types/model@latest \ @ember-data-types/request@latest \ @ember-data-types/request-utils@latest \ @ember-data-types/serializer@latest \ @ember-data-types/store@latest \ @warp-drive-types/core-types@latest \ @warp-drive/core@latest \ @warp-drive/json-api@latest \ @warp-drive/legacy@latest \ @warp-drive/utilities@latest ``` ::: This will install the following at the latest release ```package.json { "dependencies": { "ember-data-types": "latest", // [!code ++:15] "@ember-data-types/adapter": "latest", "@ember-data-types/graph": "latest", "@ember-data-types/json-api": "latest", "@ember-data-types/legacy-compat": "latest", "@ember-data-types/model": "latest", "@ember-data-types/request-utils": "latest", "@ember-data-types/request": "latest", "@ember-data-types/serializer": "latest", "@ember-data-types/store": "latest", "@warp-drive-types/core-types": "latest", "@warp-drive/core": "latest", "@warp-drive/json-api": "latest", "@warp-drive/legacy": "latest", "@warp-drive/utilities": "latest", } } ``` ### Step 3 - configure tsconfig.json ```diff { "compilerOptions": { "types": [ "ember-source/types", // [!code ++:12] "ember-data-types/unstable-preview-types", "@ember-data-types/store/unstable-preview-types", "@ember-data-types/adapter/unstable-preview-types", "@ember-data-types/graph/unstable-preview-types", "@ember-data-types/json-api/unstable-preview-types", "@ember-data-types/legacy-compat/unstable-preview-types", "@ember-data-types/request/unstable-preview-types", "@ember-data-types/request-utils/unstable-preview-types", "@ember-data-types/model/unstable-preview-types", "@ember-data-types/serializer/unstable-preview-types", "@warp-drive-types/core-types/unstable-preview-types" ] } } ``` ### Step 4 - brand your models ```ts import Model from '@ember-data/model'; import type { Type } from '@warp-drive/core-types/symbols'; export default class User extends Model { declare [Type]: 'user'; } ``` ### Step 5 - replace registry usage with branded model usages ```ts // find store.findRecord('user', '1'); // [!code --] store.findRecord('user', '1'); // [!code ++] store.findAll('user'); // [!code --] store.findAll('user'); // [!code ++] store.query('user', {}); // [!code --] store.query('user'); // [!code ++] store.queryRecord('user', {}); // [!code --] store.queryRecord('user'); // [!code ++] // peek store.peekRecord('user', '1'); // [!code --] store.peekRecord('user', '1'); // [!code ++] // push const user = store.push({ // [!code --] const user = store.push({ // [!code ++] data: { type: 'user', id: '1', attributes: { name: 'Chris' } } }) as User; // [!code --] }); // [!code ++] ``` **Additional Resources** * [Typing Requests](/guides/the-manual/requests/typing-requests) * [Typing Models](/guides/the-manual/typescript/typing-models) * [Why Brands](/guides/the-manual/typescript/why-brands) ### Step 6 - fix other type issues that arise ArrayLike API usage is likely to give you the most issues here, if anything does. ## Migration ### Step 1 - Install the Mirror Packages ::: code-group ```sh [pnpm] pnpm add -E @warp-drive-mirror/core@latest @warp-drive-mirror/json-api@latest @warp-drive-mirror/ember@latest @warp-drive-mirror/legacy@latest @warp-drive-mirror/utilities@latest ``` ```sh [npm] npm add -E @warp-drive-mirror/core@latest @warp-drive-mirror/json-api@latest @warp-drive-mirror/ember@latest @warp-drive-mirror/legacy@latest @warp-drive-mirror/utilities@latest ``` ```sh [yarn] yarn add -E @warp-drive-mirror/core@latest @warp-drive-mirror/json-api@latest @warp-drive-mirror/ember@latest @warp-drive-mirror/legacy@latest @warp-drive-mirror/utilities@latest ``` ```sh [bun] bun add --exact @warp-drive-mirror/core@latest @warp-drive-mirror/json-api@latest @warp-drive-mirror/ember@latest @warp-drive-mirror/legacy@latest @warp-drive-mirror/utilities@latest ``` ::: This will install the following at the latest release ```package.json { "dependencies": { "@warp-drive-mirror/core": "latest", // [!code ++:5] "@warp-drive-mirror/ember": "latest", "@warp-drive-mirror/json-api": "latest", "@warp-drive-mirror/legacy": "latest", "@warp-drive-mirror/utilities": "latest", } } ``` ### Step 2 - Configure The Build ::: tabs key:paradigm \== Classic Config ```ts [ember-cli-build.js] 'use strict'; const EmberApp = require('ember-cli/lib/broccoli/ember-app'); const { compatBuild } = require('@embroider/compat'); module.exports = async function (defaults) { const { setConfig } = await import('@warp-drive-mirror/core/build-config'); // [!code focus] const { buildOnce } = await import('@embroider/vite'); const app = new EmberApp(defaults, {}); setConfig(app, __dirname, { // [!code focus:9] // this should be the most recent . version for // which all deprecations have been fully resolved // and should be updated when that changes compatWith: '4.12', deprecations: { // ... list individual deprecations that have been resolved here } }); return compatBuild(app, buildOnce); }; ``` \== Vite Minimal Config ```ts [babel.config.mjs] import { setConfig } from '@warp-drive-mirror/core/build-config'; import { buildMacros } from '@embroider/macros/babel'; const Macros = buildMacros({ configure: (config) => { setConfig(config, { // for universal apps this MUST be at least 5.6 compatWith: '5.6' }); }, }); export default { plugins: [ ...Macros.babelMacros, ], }; ``` ::: ### Step 3 - Configure Reactivity Next we configure WarpDrive to use Ember's signals implementation. Add this near the top of your `app/app.ts` file. If you already have `import '@warp-drive/ember/install';` leave that too, you'll need both. Their order does not matter. ```ts [app/app.ts] import '@warp-drive-mirror/ember/install'; ``` ### Step 4 - Configure the Store We use `useLegacyStore` to create a store service preconfigured with maximal support for legacy APIs. :::tabs \== Coming from 4.12 ```ts [app/services/v2-store.ts] import { useLegacyStore } from '@warp-drive/legacy'; import { JSONAPICache } from '@warp-drive/json-api'; const Store = useLegacyStore({ legacyRequests: true, cache: JSONAPICache, schemas: [ // -- your schemas here for // anything migrated off of Model ], handlers: [ // -- your additional handlers here // Fetch, LegacyNetworkHandler, and CacheHandler // are automatically provided when needed ] }); type Store = InstanceType; export default Store; ``` \== Coming from ModelFragments + 4.6 ```ts [app/services/v2-store.ts] import { useLegacyStore } from '@warp-drive/legacy'; import { JSONAPICache } from '@warp-drive/json-api'; export default useLegacyStore({ legacyRequests: true, modelFragments: true, cache: JSONAPICache, schemas: [ // -- your schemas here for // anything migrated off of Model ], handlers: [ // -- your additional handlers here // Fetch, LegacyNetworkHandler, and CacheHandler // are automatically provided when needed ] }); ``` ::: **Additional Reading** (for when you have questions later) * [useLegacyStore](/api/@warp-drive/legacy/functions/useLegacyStore) * [LinksMode setting](/api/@warp-drive/legacy/types/LegacyModelAndNetworkAndRequestStoreSetupOptions#linksmode) * [legacyRequests setting](/api/@warp-drive/legacy/types/LegacyModelAndNetworkAndRequestStoreSetupOptions#legacyrequests) * [modelFragments setting](/api/@warp-drive/legacy/types/LegacyModelAndNetworkAndRequestStoreSetupOptions#modelfragments) * About the [LinksMode feature](/guides/the-manual/misc/links-mode) * [Model Migration Support](/api/@warp-drive/legacy/model/migration-support/) * the legacy store uses the [DelegatingSchemaService](/api/@warp-drive/legacy/model/migration-support/classes/DelegatingSchemaService) * [withDefaults](/api/@warp-drive/legacy/model/migration-support/functions/withDefaults) * [withRestoredDeprecatedModelRequestBehaviors](/api/@warp-drive/legacy/model/migration-support/functions/withRestoredDeprecatedModelRequestBehaviors) * [EmberObject Extension](/api/@warp-drive/legacy/compat/extensions/variables/EmberObjectExtension) * [EmberObject Extension for Arrays](/api/@warp-drive/legacy/compat/extensions/variables/EmberObjectArrayExtension) * [EmberArrayLike Extension](/api/@warp-drive/legacy/compat/extensions/variables/EmberArrayLikeExtension) * [Legacy Store Methods](/api/@warp-drive/legacy/store/functions/restoreDeprecatedStoreBehaviors) ### Step 5 - Convert + Profit Key concepts: * [LegacyResourceSchema](/api/@warp-drive/core/types/schema/fields/types/LegacyResourceSchema) * [LegacyModeFieldSchema](/api/@warp-drive/core/types/schema/fields/types/LegacyModeFieldSchema) * [registerTrait](/api/@warp-drive/core/types/schema/schema-service/types/SchemaService#registertrait) * [LegacyTrait](/api/@warp-drive/core/types/schema/fields/types/LegacyTrait) * [CAUTION\_MEGA\_DANGER\_ZONE\_registerExtension()](/api/@warp-drive/core/types/schema/schema-service/types/SchemaService#caution-mega-danger-zone-registerextension) * [CAUTION\_MEGA\_DANGER\_ZONE\_Extension](/api/@warp-drive/core/reactive/types/CAUTION_MEGA_DANGER_ZONE_Extension) *** A Model does four jobs at once: it is a TypeScript type, a schema, a reactive object, and a namespace for methods and computed properties. Migrating away from Model means handing each of those jobs to whichever new piece owns it. We don't expect you to do this by hand. The [migrate-to-schema codemod](./codemods.md) generates these files for you. The walkthrough below explains the output it generates. Here is a Model with a Mixin, and the files that replace it. :::tabs key:model-migration \== Before :::code-group ```ts [app/models/user.ts] import Model, { attr, belongsTo, hasMany, type AsyncHasMany } from '@ember-data/model'; import type { Type } from '@warp-drive/core-types/symbols'; import { cached } from '@glimmer/tracking'; import { computed } from '@ember/object'; import Timestamped from '../mixins/timestamped'; export default class User extends Model.extend(Timestamped) { declare [Type]: 'user'; @attr declare firstName: string; @attr declare lastName: string; @belongsTo('user', { async: false, inverse: null }) declare bestFriend: User | null; @hasMany('user', { async: true, inverse: null }) declare friends: AsyncHasMany; @cached get fullName(): string { return this.firstName + ' ' + this.lastName; } @computed('firstName') get greeting(): string { return 'Hello ' + this.firstName + '!'; } sayHi(): void { alert(this.greeting); } } ``` ```ts [app/mixins/timestamped.ts] import Mixin from '@ember/object/mixin'; import { attr } from '@ember-data/model'; export default Mixin.create({ createdAt: attr(), deletedAt: attr(), updatedAt: attr(), async softDelete(): Promise { const result = await fetch(`/api/${this.constructor.modelName}/${this.id}`, { method: 'DELETE' }); const newTimestamps = await result.json(); this.store.push({ data: { type: this.constructor.modelName, id: this.id, attributes: newTimestamps } }); } }); ``` ::: \== After :::code-group ```ts [app/data/user/schema.ts] import { withDefaults } from '@warp-drive-mirror/legacy/model/migration-support'; export const UserSchema = withDefaults({ type: 'user', fields: [ { kind: 'attribute', name: 'firstName' }, { kind: 'attribute', name: 'lastName' }, { kind: 'belongsTo', name: 'bestFriend', type: 'user', options: { async: false, inverse: null } }, { kind: 'hasMany', name: 'friends', type: 'user', options: { async: true, inverse: null } }, ], traits: ['timestamped'], objectExtensions: ['timestamped-extension', 'user-extension'] }); ``` ```ts [app/data/user/type.ts] import type { WithLegacy } from '@warp-drive-mirror/legacy/model/migration-support'; import type { AsyncHasMany } from '@warp-drive-mirror/legacy/model'; import type { Type } from '@warp-drive-mirror/core/types/symbols'; import type { Timestamped } from '../traits/timestamped/type.ts'; import type { TimestampedExtension } from '../traits/timestamped/ext.ts'; export interface User extends Timestamped { [Type]: 'user'; firstName: string; lastName: string; bestFriend: User | null; friends: AsyncHasMany; } export interface LegacyUser extends WithLegacy, TimestampedExtension {} ``` ```ts [app/data/user/ext.ts] import { cached } from '@glimmer/tracking'; import { computed } from '@ember/object'; import type { LegacyUser } from './type.ts'; export interface UserExtension extends LegacyUser {} export class UserExtension { @cached get fullName() { return this.firstName + ' ' + this.lastName; } @computed('firstName') get greeting() { return 'Hello ' + this.firstName + '!'; } sayHi() { alert(this.greeting); } } export const UserExtensionSchema = { name: 'user-extension', kind: 'object', features: UserExtension, } ``` ```ts [app/data/traits/timestamped/schema.ts] export const TimestampedTrait = { name: 'timestamped', mode: 'legacy', fields: [ { kind: 'attribute', name: 'createdAt' }, { kind: 'attribute', name: 'deletedAt' }, { kind: 'attribute', name: 'updatedAt' }, ], } ``` ```ts [app/data/traits/timestamped/type.ts] export interface Timestamped { createdAt: number; deletedAt: number | null; updatedAt: number; } ``` ```ts [app/data/traits/timestamped/ext.ts] import type { Timestamped } from './type.ts'; export interface TimestampedExtension extends Timestamped {} export class TimestampedExtension { async softDelete(): Promise { const result = await fetch(`/api/${this.constructor.modelName}/${this.id}`, { method: 'DELETE' }); const newTimestamps = await result.json(); this.store.push({ data: { type: this.constructor.modelName, id: this.id, attributes: newTimestamps } }); } } export const TimestampedExtensionSchema = { kind: 'object', name: 'timestamped-extension', features: TimestampedExtension, } ``` ::: Step by step, this is how the Model decomposes into those files. 1. The file-path based convention for defining the ResourceType is replaced with specifying a ResourceType on a [ResourceSchema](/api/@warp-drive/core/types/schema/fields/types/ResourceSchema). File paths are now purely organizational and discretionary. ```ts [app/data/user/schema.ts] // The ResourceSchema in this example is intentionally // incomplete, we will fill it out below // const UserSchema = { type: 'user', } ``` 2. We differentiate between schemas for embedded objects (which have no identity of their own) and schemas for resources (which do have their own identity) by specifying a primaryKey. On [`Model`](/api/@warp-drive/legacy/model/classes/Model) this was `id` (this is also added by `withDefaults` which we'll see next). ```ts [app/data/user/schema.ts] // The ResourceSchema in this example is intentionally // incomplete, we will fill it out below // const UserSchema = { type: 'user', identity: { kind: '@id', name: 'id' } // [!code ++] } ``` 3. We put the ResourceSchema in "LegacyMode" so that our ReactiveResources will behave in the same mutable manner as Model did. ```ts [app/data/user/schema.ts] // The ResourceSchema in this example is intentionally // incomplete, we will fill it out below // const UserSchema = { type: 'user', identity: { kind: '@id', name: 'id' }, legacy: true,// [!code ++] } ``` 4. We decorate our ResourceSchema with the default behaviors that Models had (fields like `isNew` `hasDirtyAttributes` or `currentState` as well as methods like `rollbackAttributes` and `save`). This also automatically sets us up in `LegacyMode` and adds the `id` field for identity, in effect this replaces `class User extends Model`. ```ts [app/data/user/schema.ts] import { withDefaults } from '@warp-drive-mirror/legacy/model/migration-support'; // The ResourceSchema in this example is intentionally // incomplete, we will fill it out below // const UserSchema = withDefaults({ // [!code ++] type: 'user', identity: { kind: '@id', name: 'id' }, // [!code --] legacy: true,// [!code --] }) // [!code ++] ``` 5. Schema properties from the Model (`hasMany` `belongsTo` and `attr`) become fields on the matching ResourceSchema ```ts [app/data/user/schema.ts] import { withDefaults } from '@warp-drive-mirror/legacy/model/migration-support'; // The ResourceSchema in this example is intentionally // incomplete, we will fill it out below // const UserSchema = withDefaults({ type: 'user', fields: [ // [!code ++:16] { kind: 'attribute', name: 'firstName' }, { kind: 'attribute', name: 'lastName' }, { kind: 'belongsTo', name: 'bestFriend', type: 'user', options: { async: false, inverse: null } }, { kind: 'hasMany', name: 'friends', type: 'user', options: { async: true, inverse: null } }, ], }) ``` 6. The Mixin's `attr` fields become a trait, and the ResourceSchema lists that trait by name. A trait is a reusable set of fields that any ResourceSchema can pull in. ```ts [app/data/user/schema.ts] const UserSchema = withDefaults({ type: 'user', fields: [ /* ... */ ], traits: ['timestamped'], // [!code ++] }) ``` 7. Everything left on the Model or Mixin that is not schema (computed properties, methods) moves to an object extension, and the ResourceSchema lists those by name too. An extension adds methods and getters to a LegacyMode record. ```ts [app/data/user/schema.ts] const UserSchema = withDefaults({ type: 'user', fields: [ /* ... */ ], traits: ['timestamped'], objectExtensions: ['timestamped-extension', 'user-extension'], // [!code ++] }) ``` 8. The Model's TypeScript shape becomes a plain interface, wrapped in [`WithLegacy`](/api/@warp-drive/legacy/model/migration-support/types/WithLegacy) to pick up the fields `withDefaults` added and intersected with any extension interfaces so `user.fullName` still type-checks. ## Post Migration * drop the old packages * drop config for the old packages * delete the store service * rename v2-store => store * rename packages and imports from `@warp-drive-mirror` to `@warp-drive` --- --- url: https://canary.warp-drive.io/upgrading/v5/two-store-migration.md description: >- Run a second WarpDrive store built from the -mirror packages beside your existing 4.x store so parts of an app can adopt 5.x incrementally, with the tradeoffs to expect. --- :::warning Legacy guide This guide covers a legacy setup. New apps should start from [Installation](/guides/installation/index.md) and [Setup](/guides/configuration/index.md) instead. ::: # Migrating Between Versions Using The Two Store Approach   authored 2023-06-10 Sometimes apps build over features, private APIs 🙈, or 3rd party libraries that later become deprecated and removed. Most deprecations are relatively easy to resolve, but sometimes APIs change that had been central to the way an app was built. A good example of a difficult to resolve change is the switch away from per-record caching internally, which should have been transparent to apps but left users of a popular 3rd party library (ModelFragments) stuck on the 4.6 release. An example of such a shift in public APIs is the move away from Ember's ArrayLike interface for collections of records and away from promise-proxy wrappers surrounding async relationships. While lots of new patterns exist to replace those APIs, users that made heavy use of these features have a harder time migrating from version 4 to version 5, and thus stop being able to adopt new features in newer parts of their application until a substantial cleanup has occurred. This is where the two-store-approach can be useful. In the two-store approach, an application configures a second store service under a different service name (for instance `v2-store`) enabling some portions of the app to use modern features without immediately being required to upgrade all of the existing application code to match. Any application can configure more than one store using whatever version of WarpDrive is installed, but to maximize this approach it is useful to be able to have the second store also use a more recent version of the library. This is why we publish **"mirror"** versions of every package. ## Mirror Versions Every package we publish has a **"mirror"** package equivalent. For packages that have an org name (e.g. `@ember-data/store` or `@warp-drive/ember`) we add `-mirror` to the org name. E.g. `@ember-data/store` has the mirror `@ember-data-mirror/store`. For packages without an org we add `-mirror` to the name e.g. `ember-data` has the mirror `ember-data-mirror`. Mirror packages are configured to work with other mirror packages as a wholly distinct package ecosystem. For instance, the mirror of `@ember-data/model` is `@ember-data-mirror/model` and instead of having a peer-dependency on `@ember-data/store` it has a peer-dependency on `@ember-data-mirror/store`. When importing code, you import from the mirror path e.g. `import Model, { attr } from '@ember-data-mirror/model';`. For convenience, some types, constants and symbols that are safe to interop between versions will do so if you have both mirror and non-mirror versions available. Mirror packages are available for versions `^4.13.0 | >=5.3.8`. ## TypeScript All mirror packages are also versions which ship their own types. To use those types, configure your `tsconfig.json` to be able to find them [as shown here](/guides/the-manual/typescript/configuration.md#using-native-types), adding the appropriate `-mirror` appendage to each package name (PS: you can have distinct types for both your older and your newer version!). ## Caveat Emptor Utilizing the two-store approach has a few tradeoffs: 1. If you want compatible type signatures for use by your components, you should upgrade your app to make use of native types first, likely using the [types-package approach](/guides/the-manual/typescript/installation.md#using-types-packages). In fact, it is likely that if you want TypeScript for the v2 store that you are *forced* to remove the `@types/ember*` packages from your project entirely and upgrade to using native types for ember-source and ember-data. This is because the native types for WarpDrive depend on ember's native types. 2. You should not use both `ember-data` and `ember-data-mirror` or there will be an unresolveable race condition for which one is the `store` service. Instead one of the stores, usually the mirror, MUST import and fully configure the store. The [4.x → 5.x guide](./index.md#step-4-configure-the-store) does this with [`useLegacyStore`](/api/@warp-drive/legacy/functions/useLegacyStore), which reproduces the store that `ember-data` configured "by default" historically. Its options let you drop pieces of that default you no longer want, such as adapters and serializers, or Model itself. 3. Due to (#2) above, your build MUST call [`setConfig`](/api/@warp-drive/core/build-config/functions/setConfig) from the mirror package so the mirror gets its own build config. See [Configure The Build](./index.md#step-2-configure-the-build) in the 4.x → 5.x guide. 4. Record instances created by one store may not be used by another store, this primarily means they cannot be set as values of relationships. The records (and data) of each store is a wholly distinct context. You may find [ember-provide-consume-context](https://github.com/customerio/ember-provide-consume-context) useful for helping to manage this. Migrating "leaf first" or well-encapsulated parts of your app will generally lead to the pit-of-success. --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy.md description: >- Opt-in support for features deprecated out of `@warp-drive/core`, such as Models, Adapters, Serializers and legacy store APIs, for apps that still need to migrate away from them. --- :::warning ⚠️ **CAUTION** This package provides support for older ***Warp*Drive** features that have been deprecated and removed from [@warp-drive/core](/api/@warp-drive/core/). **Projects using these features should refactor away from them with urgency** ::: You've probably heard old code patterns referred to as "legacy code" before. In ***Warp*Drive**, Legacy refers to older features to which we are giving a second, extended life. When features are deprecated in [@warp-drive/core](/api/@warp-drive/core/), they are added to `@warp-drive/legacy` in a way that allows apps to opt-in to bring them back. Legacy features will not live forever, but they will receive a second deprecation cycle before being deleted. Notably, **the decision to deprecate a legacy feature does not require an RFC**. This low-barrier to removal is because the motivations for deprecating and removing the feature were already enumerated in the original deprecation that removed the feature from core. Generally if code in legacy is being deprecated, it means an event has occurred that requires full removal of support for the feature in order for the project as a whole to continue to advance. There is no set schedule to when code in legacy might be deprecated. Sometimes it may become deprecated immediately after the feature is removed from core, other times it may last for several majors. Occasionally a deprecation in core won't be able to be restored from legacy at all. Our policy is to always attempt to provide restoration of a deprecated feature via @warp-drive/legacy, but the decision to provide this long-tail support ultimately depends on how easy a feature is to maintain weighed against the costs to the community and project of keeping it around. ## Guides * [Setup](/guides/configuration/#configure-the-store): create a Store with `useLegacyStore` in the LegacyMode tab. * [Legacy Feature Setup for Ember Apps](/guides/configuration/ember.md): which legacy features `@warp-drive/legacy` restores, and when you still need the `LegacyNetworkHandler`. * [LegacyMode](/guides/the-manual/schemas/resources/legacy-mode.md): emulate `Model` with a schema, using `withDefaults` and `registerDerivations` from this package. * [Relationships](/guides/the-manual/relational-data/): the relationship configuration pages show each relationship defined with `@warp-drive/legacy/model` as well as with schemas. * [Typing Models & Transforms](/guides/the-manual/typescript/typing-models.md): type `Model` classes, their fields and their transforms. * [Migrating 4.x to 5.x](/upgrading/v5/index.md): move an EmberData 4.x app to 5.x with `useLegacyStore`. * [Using Codemods](/upgrading/v5/codemods.md): convert Models into schemas that use `withDefaults` from this package. ## Classes * [ConfiguredStore](classes/ConfiguredStore.md) ## Functions * [useLegacyStore](functions/useLegacyStore.md) ## Types * [LegacyModelAndNetworkAndRequestStoreSetupOptions](types/LegacyModelAndNetworkAndRequestStoreSetupOptions.md) * [LegacyModelAndNetworkStoreSetupOptions](types/LegacyModelAndNetworkStoreSetupOptions.md) * [LegacyModelStoreSetupOptions](types/LegacyModelStoreSetupOptions.md) * [LegacyStoreSetupOptions](types/LegacyStoreSetupOptions.md) --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/classes/Adapter.md description: >- Legacy abstract base class for adapters that translate store requests such as `findRecord` and `updateRecord` into calls against a persistence layer. --- # Adapter Defined in: [warp-drive-packages/legacy/src/adapter.ts:293](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L293) An adapter is an object that receives requests from a store and translates them into the appropriate action to take against your persistence layer. The persistence layer is usually an HTTP API but may be anything, such as the browser's local storage. Typically the adapter is not invoked directly instead its functionality is accessed through the `store`. > ⚠️ CAUTION you likely want the docs for [MinimumAdapterInterface](../../compat/types/MinimumAdapterInterface.md) > as extending this abstract class is unnecessary. ### Creating an Adapter Create a new subclass of `Adapter` in the `app/adapters` folder: ```js [app/adapters/application.js] import { Adapter } from '@warp-drive/legacy/adapter'; export default class extends Adapter { // ...your code here } ``` Model-specific adapters can be created by putting your adapter class in an `app/adapters/` + `model-name` + `.js` file of the application. ```js [app/adapters/post.js] import { Adapter } from '@warp-drive/legacy/adapter'; export default class extends Adapter { // ...Post-specific adapter code goes here } ``` `Adapter` is an abstract base class that you should override in your application to customize it for your backend. The minimum set of methods that you should implement is: * `findRecord()` * `createRecord()` * `updateRecord()` * `deleteRecord()` * `findAll()` * `query()` To improve the network performance of your application, you can optimize your adapter by overriding these lower-level methods: * `findMany()` For an example of the implementation, see `RESTAdapter`, the included REST adapter. ## Extends * `EmberObject` ## Implements * [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md) ## Constructors ### Constructor ```ts new Adapter(owner?: Owner): Adapter; ``` #### Parameters ##### owner? `Owner` #### Returns `Adapter` #### Inherited from ```ts EmberObject.constructor ``` ## Methods ### createRecord() ```ts createRecord( store: Store$1, type: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:546](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L546) Implement this method in a subclass to handle the creation of new records. Serializes the record and sends it to the server. Example ```js [app/adapters/application.js] import { Adapter } from '@warp-drive/legacy/adapter'; import RSVP from 'RSVP'; import $ from 'jquery'; export default class ApplicationAdapter extends Adapter { createRecord(store, type, snapshot) { let data = this.serialize(snapshot, { includeId: true }); return new RSVP.Promise(function (resolve, reject) { $.ajax({ type: 'POST', url: `/${type.modelName}`, dataType: 'json', data: data }).then(function (data) { resolve(data); }, function (jqXHR) { jqXHR.then = null; // tame jQuery's ill mannered promises reject(jqXHR); }); }); } } ``` #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../compat/types/AdapterPayload.md)> #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`createRecord`](../../compat/types/MinimumAdapterInterface.md#createrecord) *** ### deleteRecord() ```ts deleteRecord( store: Store$1, type: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:650](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L650) Implement this method in a subclass to handle the deletion of a record. Sends a delete request for the record to the server. Example ```js [app/adapters/application.js] import { Adapter } from '@warp-drive/legacy/adapter'; import RSVP from 'RSVP'; import $ from 'jquery'; export default class ApplicationAdapter extends Adapter { deleteRecord(store, type, snapshot) { let data = this.serialize(snapshot, { includeId: true }); let id = snapshot.id; return new RSVP.Promise(function(resolve, reject) { $.ajax({ type: 'DELETE', url: `/${type.modelName}/${id}`, dataType: 'json', data: data }).then(function(data) { resolve(data) }, function(jqXHR) { jqXHR.then = null; // tame jQuery's ill mannered promises reject(jqXHR); }); }); } } ``` #### Parameters ##### store `Store$1` ##### type `ModelSchema` the Model class of the record ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../compat/types/AdapterPayload.md)> promise #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`deleteRecord`](../../compat/types/MinimumAdapterInterface.md#deleterecord) *** ### findAll() ```ts findAll( store: Store$1, type: ModelSchema, neverSet: null, snapshotRecordArray: SnapshotRecordArray ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:366](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L366) The `findAll()` method is used to retrieve all records for a given type. Example ```js [app/adapters/application.js] import { Adapter } from '@warp-drive/legacy/adapter'; import RSVP from 'RSVP'; import $ from 'jquery'; export default class ApplicationAdapter extends Adapter { findAll(store, type) { return new RSVP.Promise(function(resolve, reject) { $.getJSON(`/${type.modelName}`).then(function(data) { resolve(data); }, function(jqXHR) { reject(jqXHR); }); }); } } ``` #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### neverSet `null` a value is never provided to this argument ##### snapshotRecordArray `SnapshotRecordArray` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../compat/types/AdapterPayload.md)> #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`findAll`](../../compat/types/MinimumAdapterInterface.md#findall) *** ### findRecord() ```ts findRecord( store: Store$1, type: ModelSchema, id: string, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:334](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L334) The `findRecord()` method is invoked when the store is asked for a record that has not previously been loaded. In response to `findRecord()` being called, you should query your persistence layer for a record with the given ID. The `findRecord` method should return a promise that will resolve to a JavaScript object that will be normalized by the serializer. Here is an example of the `findRecord` implementation: ```js [app/adapters/application.js] import { Adapter } from '@warp-drive/legacy/adapter'; import RSVP from 'RSVP'; import $ from 'jquery'; export default class ApplicationAdapter extends Adapter { findRecord(store, type, id, snapshot) { return new RSVP.Promise(function(resolve, reject) { $.getJSON(`/${type.modelName}/${id}`).then(function(data) { resolve(data); }, function(jqXHR) { reject(jqXHR); }); }); } } ``` #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### id `string` ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../compat/types/AdapterPayload.md)> #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`findRecord`](../../compat/types/MinimumAdapterInterface.md#findrecord) *** ### groupRecordsForFindMany() ```ts groupRecordsForFindMany(store: Store$1, snapshots: Snapshot[]): Snapshot[][]; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:730](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L730) Organize records into groups, each of which is to be passed to separate calls to `findMany`. For example, if your API has nested URLs that depend on the parent, you will want to group records by their parent. The default implementation returns the records as a single group. #### Parameters ##### store `Store$1` ##### snapshots `Snapshot`<`unknown`>\[] #### Returns `Snapshot`<`unknown`>\[]\[] an array of arrays of records, each of which is to be loaded separately by `findMany`. #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`groupRecordsForFindMany`](../../compat/types/MinimumAdapterInterface.md#grouprecordsforfindmany) *** ### query() ```ts query( store: Store$1, type: ModelSchema, query: Record ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:404](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L404) This method is called when you call `query` on the store. Example ```js [app/adapters/application.js] import { Adapter } from '@warp-drive/legacy/adapter'; import RSVP from 'RSVP'; import $ from 'jquery'; export default class ApplicationAdapter extends Adapter { query(store, type, query) { return new RSVP.Promise(function(resolve, reject) { $.getJSON(`/${type.modelName}`, query).then(function(data) { resolve(data); }, function(jqXHR) { reject(jqXHR); }); }); } } ``` #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../compat/types/AdapterPayload.md)> #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`query`](../../compat/types/MinimumAdapterInterface.md#query) *** ### queryRecord() ```ts queryRecord( store: Store$1, type: ModelSchema, query: Record, adapterOptions: object ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:435](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L435) The `queryRecord()` method is invoked when the store is asked for a single record through a query object. In response to `queryRecord()` being called, you should always fetch fresh data. Once found, you can asynchronously call the store's `push()` method to push the record into the store. Here is an example `queryRecord` implementation: Example ```js [app/adapters/application.js] import { Adapter, BuildURLMixin } from '@warp-drive/legacy/adapter'; export default class ApplicationAdapter extends Adapter.extend(BuildURLMixin) { queryRecord(store, type, query) { return fetch(`/${type.modelName}`, { body: JSON.stringify(query) }) .then((response) => response.json()); } } ``` #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### adapterOptions `object` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../compat/types/AdapterPayload.md)> #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`queryRecord`](../../compat/types/MinimumAdapterInterface.md#queryrecord) *** ### serialize() ```ts serialize(snapshot: Snapshot, options: SerializerOptions): Record; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:500](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L500) Proxies to the serializer's `serialize` method. Example ```js [app/adapters/application.js] import { Adapter } from '@warp-drive/legacy/adapter'; export default class ApplicationAdapter extends Adapter { createRecord(store, type, snapshot) { let data = this.serialize(snapshot, { includeId: true }); let url = `/${type.modelName}`; // ... } } ``` #### Parameters ##### snapshot `Snapshot` ##### options [`SerializerOptions`](../../compat/types/SerializerOptions.md) #### Returns [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> *** ### shouldBackgroundReloadAll() ```ts shouldBackgroundReloadAll(store: Store$1, snapshotRecordArray: SnapshotRecordArray): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:907](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L907) This method is used by the store to determine if the store should reload a record array after the `store.findAll` method resolves with a cached record array. This method is *only* checked by the store when the store is returning a cached record array. If this method returns `true` the store will re-fetch all records from the adapter. For example, if you do not want to fetch complex data over a mobile connection, or if the network is down, you can implement `shouldBackgroundReloadAll` as follows: ```javascript shouldBackgroundReloadAll(store, snapshotArray) { let { downlink, effectiveType } = navigator.connection; return downlink > 0 && effectiveType === '4g'; } ``` By default this method returns `true`, indicating that a background reload should always be triggered. #### Parameters ##### store `Store$1` ##### snapshotRecordArray `SnapshotRecordArray` #### Returns `boolean` #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`shouldBackgroundReloadAll`](../../compat/types/MinimumAdapterInterface.md#shouldbackgroundreloadall) *** ### shouldBackgroundReloadRecord() ```ts shouldBackgroundReloadRecord(store: Store$1, snapshot: Snapshot): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:871](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L871) This method is used by the store to determine if the store should reload a record after the `store.findRecord` method resolves a cached record. This method is *only* checked by the store when the store is returning a cached record. If this method returns `true` the store will re-fetch a record from the adapter. For example, if you do not want to fetch complex data over a mobile connection, or if the network is down, you can implement `shouldBackgroundReloadRecord` as follows: ```javascript shouldBackgroundReloadRecord(store, snapshot) { let { downlink, effectiveType } = navigator.connection; return downlink > 0 && effectiveType === '4g'; } ``` By default, this hook returns `true` so the data for the record is updated in the background. #### Parameters ##### store `Store$1` ##### snapshot `Snapshot` #### Returns `boolean` #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`shouldBackgroundReloadRecord`](../../compat/types/MinimumAdapterInterface.md#shouldbackgroundreloadrecord) *** ### shouldReloadAll() ```ts shouldReloadAll(store: Store$1, snapshotRecordArray: SnapshotRecordArray): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:835](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L835) This method is used by the store to determine if the store should reload all records from the adapter when records are requested by `store.findAll`. If this method returns `true`, the store will re-fetch all records from the adapter. If this method returns `false`, the store will resolve immediately using the cached records. For example, if you are building an events ticketing system, in which users can only reserve tickets for 20 minutes at a time, and want to ensure that in each route you have data that is no more than 20 minutes old you could write: ```javascript shouldReloadAll(store, snapshotArray) { let snapshots = snapshotArray.snapshots(); return snapshots.any((ticketSnapshot) => { let lastAccessedAt = ticketSnapshot.attr('lastAccessedAt'); let timeDiff = moment().diff(lastAccessedAt, 'minutes'); if (timeDiff > 20) { return true; } else { return false; } }); } ``` This method would ensure that whenever you do `store.findAll('ticket')` you will always get a list of tickets that are no more than 20 minutes old. In case a cached version is more than 20 minutes old, `findAll` will not resolve until you fetched the latest versions. By default, this method returns `true` if the passed `snapshotRecordArray` is empty (meaning that there are no records locally available yet), otherwise, it returns `false`. Note that, with default settings, `shouldBackgroundReloadAll` will always re-fetch all the records in the background even if `shouldReloadAll` returns `false`. You can override `shouldBackgroundReloadAll` if this does not suit your use case. #### Parameters ##### store `Store$1` ##### snapshotRecordArray `SnapshotRecordArray` #### Returns `boolean` #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`shouldReloadAll`](../../compat/types/MinimumAdapterInterface.md#shouldreloadall) *** ### shouldReloadRecord() ```ts shouldReloadRecord(store: Store$1, snapshot: Snapshot): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:780](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L780) This method is used by the store to determine if the store should reload a record from the adapter when a record is requested by `store.findRecord`. If this method returns `true`, the store will re-fetch a record from the adapter. If this method returns `false`, the store will resolve immediately using the cached record. For example, if you are building an events ticketing system, in which users can only reserve tickets for 20 minutes at a time, and want to ensure that in each route you have data that is no more than 20 minutes old you could write: ```javascript shouldReloadRecord(store, ticketSnapshot) { let lastAccessedAt = ticketSnapshot.attr('lastAccessedAt'); let timeDiff = moment().diff(lastAccessedAt, 'minutes'); if (timeDiff > 20) { return true; } else { return false; } } ``` This method would ensure that whenever you do `store.findRecord('ticket', id)` you will always get a ticket that is no more than 20 minutes old. In case the cached version is more than 20 minutes old, `findRecord` will not resolve until you fetched the latest version. By default this hook returns `false`, as most UIs should not block user interactions while waiting on data update. Note that, with default settings, `shouldBackgroundReloadRecord` will always re-fetch the records in the background even if `shouldReloadRecord` returns `false`. You can override `shouldBackgroundReloadRecord` if this does not suit your use case. #### Parameters ##### store `Store$1` ##### snapshot `Snapshot` #### Returns `boolean` #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`shouldReloadRecord`](../../compat/types/MinimumAdapterInterface.md#shouldreloadrecord) *** ### updateRecord() ```ts updateRecord( store: Store$1, type: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:602](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L602) Implement this method in a subclass to handle the updating of a record. Serializes the record update and sends it to the server. The updateRecord method is expected to return a promise that will resolve with the serialized record. This allows the backend to inform the WarpDrive store the current state of this record after the update. If it is not possible to return a serialized record the updateRecord promise can also resolve with `undefined` and the WarpDrive store will assume all of the updates were successfully applied on the backend. Example ```js [app/adapters/application.js] import { Adapter } from '@warp-drive/legacy/adapter'; import RSVP from 'RSVP'; import $ from 'jquery'; export default class ApplicationAdapter extends Adapter { updateRecord(store, type, snapshot) { let data = this.serialize(snapshot, { includeId: true }); let id = snapshot.id; return new RSVP.Promise(function(resolve, reject) { $.ajax({ type: 'PUT', url: `/${type.modelName}/${id}`, dataType: 'json', data: data }).then(function(data) { resolve(data); }, function(jqXHR) { jqXHR.then = null; // tame jQuery's ill mannered promises reject(jqXHR); }); }); } } ``` #### Parameters ##### store `Store$1` ##### type `ModelSchema` the Model class of the record ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../compat/types/AdapterPayload.md)> promise #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`updateRecord`](../../compat/types/MinimumAdapterInterface.md#updaterecord) ## Properties ### store ```ts store: Store$1; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:297](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L297) The Store service instance that owns this Adapter. ### coalesceFindRequests #### Get Signature ```ts get coalesceFindRequests(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:666](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L666) By default the store will try to coalesce all `findRecord` calls within the same runloop into as few requests as possible by calling groupRecordsForFindMany and passing it into a findMany call. You can opt out of this behaviour by either not implementing the findMany hook or by setting coalesceFindRequests to false. ##### Returns `boolean` #### Set Signature ```ts set coalesceFindRequests(value: boolean): void; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:674](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L674) **`Optional`** If your adapter implements `findMany`, setting this to `true` will cause `findRecord` requests triggered within the same `runloop` to be coalesced into one or more calls to `adapter.findMany`. The number of calls made and the records contained in each call can be tuned by your adapter's `groupRecordsForHasMany` method. Implementing coalescing using this flag and the associated methods does not always offer the right level of correctness, timing control or granularity. If your application would be better suited coalescing across multiple types, coalescing for longer than a single runloop, or with a more custom request structure, coalescing within your application adapter may prove more effective. ##### Parameters ###### value `boolean` ##### Returns `void` **`Optional`** If your adapter implements `findMany`, setting this to `true` will cause `findRecord` requests triggered within the same `runloop` to be coalesced into one or more calls to `adapter.findMany`. The number of calls made and the records contained in each call can be tuned by your adapter's `groupRecordsForHasMany` method. Implementing coalescing using this flag and the associated methods does not always offer the right level of correctness, timing control or granularity. If your application would be better suited coalescing across multiple types, coalescing for longer than a single runloop, or with a more custom request structure, coalescing within your application adapter may prove more effective. #### Implementation of [`MinimumAdapterInterface`](../../compat/types/MinimumAdapterInterface.md).[`coalesceFindRequests`](../../compat/types/MinimumAdapterInterface.md#coalescefindrequests) --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error.md description: >- Legacy adapter errors, such as `AdapterError`, `InvalidError` and `NotFoundError`, that an adapter returns or throws to signal a failed API request. --- ## Variables * [AbortError](variables/AbortError.md) * [AdapterError](variables/AdapterError.md) * [ConflictError](variables/ConflictError.md) * [ForbiddenError](variables/ForbiddenError.md) * [InvalidError](variables/InvalidError.md) * [NotFoundError](variables/NotFoundError.md) * [ServerError](variables/ServerError.md) * [TimeoutError](variables/TimeoutError.md) * [UnauthorizedError](variables/UnauthorizedError.md) ## Types * [AdapterRequestError](types/AdapterRequestError.md) * [AdapterRequestErrorConstructor](types/AdapterRequestErrorConstructor.md) * [AbortError](types/AbortError.md) * [AdapterError](types/AdapterError.md) * [ConflictError](types/ConflictError.md) * [ForbiddenError](types/ForbiddenError.md) * [InvalidError](types/InvalidError.md) * [NotFoundError](types/NotFoundError.md) * [ServerError](types/ServerError.md) * [TimeoutError](types/TimeoutError.md) * [UnauthorizedError](types/UnauthorizedError.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/types/AbortError.md description: >- Legacy adapter error signaling that a request to the API was aborted before a response arrived. --- # AbortError ```ts type AbortError = AdapterRequestError<"AbortError">; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:334](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L334) The [AdapterRequestError](AdapterRequestError.md) shape thrown by the [AbortError](../variables/AbortError.md) constructor. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/types/AdapterError.md description: >- Legacy base error an adapter returns or throws to signal a failed API request; extend it to define app-specific error types. --- # AdapterError ```ts type AdapterError = AdapterRequestError<"AdapterError">; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:89](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L89) The [AdapterRequestError](AdapterRequestError.md) shape thrown by the [AdapterError](../variables/AdapterError.md) constructor. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/types/AdapterRequestError.md description: >- Legacy adapter error shape: an `Error` flagged `isAdapterError` with a `code` string and a {json:api} `errors` array, as thrown by `AdapterError` and its subclasses. --- # AdapterRequestError\ ```ts interface AdapterRequestError extends Error { code: T; errors: ApiError[]; isAdapterError: true; } ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:49](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L49) The shape of the errors thrown/returned by [AdapterError](../variables/AdapterError.md) and its subclasses. ## Extends * [`Error`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error) ## Type Parameters ### T `T` *extends* `string` = `string` ## Properties ### code ```ts code: T; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:57](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L57) A short code identifying the kind of error, e.g. `'NotFoundError'`. *** ### errors ```ts errors: ApiError[]; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:61](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L61) The {json:api} formatted errors associated with the request. *** ### isAdapterError ```ts isAdapterError: true; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:53](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L53) A property signifying that an Error uses the AdapterRequestError interface. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/types/AdapterRequestErrorConstructor.md description: >- Static side of the legacy adapter error constructors: `new (errors?, message?)` plus `extend({ message })` for creating further error subclasses. --- # AdapterRequestErrorConstructor\ ```ts interface AdapterRequestErrorConstructor { constructor: unknown; extend(options: { message: string }): AdapterRequestErrorConstructor; } ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:70](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L70) The static interface shared by [AdapterError](../variables/AdapterError.md) and its subclasses, allowing further subclassing via [extend](#extend). ## Type Parameters ### Instance `Instance` *extends* [`AdapterRequestError`](AdapterRequestError.md) = [`AdapterRequestError`](AdapterRequestError.md) ## Constructors ### Constructor ```ts new AdapterRequestErrorConstructor(errors?: unknown[], message?: string): Instance; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:71](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L71) #### Parameters ##### errors? `unknown`\[] ##### message? `string` #### Returns `Instance` ## Methods ### extend() ```ts extend(options: { message: string; }): AdapterRequestErrorConstructor; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:75](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L75) Creates a new AdapterRequestErrorConstructor that inherits from this one. #### Parameters ##### options ###### message `string` #### Returns `AdapterRequestErrorConstructor` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/types/ConflictError.md description: >- Legacy adapter error for an HTTP 409 response, signaling that the request conflicts with existing server state, such as a duplicate client-generated id. --- # ConflictError ```ts type ConflictError = AdapterRequestError<"ConflictError">; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:512](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L512) The [AdapterRequestError](AdapterRequestError.md) shape thrown by the [ConflictError](../variables/ConflictError.md) constructor. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/types/ForbiddenError.md description: >- Legacy adapter error for an HTTP 403 response, signaling that the server refused a valid request the user lacks permission for. --- # ForbiddenError ```ts type ForbiddenError = AdapterRequestError<"ForbiddenError">; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:421](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L421) The [AdapterRequestError](AdapterRequestError.md) shape thrown by the [ForbiddenError](../variables/ForbiddenError.md) constructor. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/types/InvalidError.md description: >- Instance type of the legacy `InvalidError`, the adapter error for a request the API rejected as semantically invalid. --- # InvalidError ```ts type InvalidError = AdapterRequestError<"InvalidError">; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:222](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L222) The [AdapterRequestError](AdapterRequestError.md) shape thrown by the [InvalidError](../variables/InvalidError.md) constructor. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/types/NotFoundError.md description: >- Legacy adapter error for an HTTP 404 response, signaling that the requested resource does not exist on the API. --- # NotFoundError ```ts type NotFoundError = AdapterRequestError<"NotFoundError">; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:466](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L466) The [AdapterRequestError](AdapterRequestError.md) shape thrown by the [NotFoundError](../variables/NotFoundError.md) constructor. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/types/ServerError.md description: >- Legacy adapter error for an HTTP 500 response, signaling that the API failed internally and an immediate retry is unlikely to succeed. --- # ServerError ```ts type ServerError = AdapterRequestError<"ServerError">; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:555](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L555) The [AdapterRequestError](AdapterRequestError.md) shape thrown by the [ServerError](../variables/ServerError.md) constructor. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/types/TimeoutError.md description: >- Legacy adapter error signaling that a request to the API timed out without receiving a response. --- # TimeoutError ```ts type TimeoutError = AdapterRequestError<"TimeoutError">; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:293](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L293) The [AdapterRequestError](AdapterRequestError.md) shape thrown by the [TimeoutError](../variables/TimeoutError.md) constructor. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/types/UnauthorizedError.md description: >- Legacy adapter error for an HTTP 401 response, signaling that authorization is required and failed or was not provided. --- # UnauthorizedError ```ts type UnauthorizedError = AdapterRequestError<"UnauthorizedError">; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:378](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L378) The [AdapterRequestError](AdapterRequestError.md) shape thrown by the [UnauthorizedError](../variables/UnauthorizedError.md) constructor. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/variables/AbortError.md description: >- Legacy adapter error constructor for signaling that a request to the API was aborted before a response arrived. --- # AbortError ```ts AbortError: AdapterRequestErrorConstructor; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:334](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L334) An `AbortError` is used by an adapter to signal that a request to the external API was aborted. For example, this can occur if the user navigates away from the current page after a request to the external API has been initiated but before a response has been received. Because an aborted request is typically expected (the user chose to navigate away, or a newer request superseded this one) rather than exceptional, an example use case would be to silently ignore it instead of surfacing an error to the user: ```js [app/routes/application.js] import { AbortError } from '@warp-drive/legacy/adapter/error'; export default class ApplicationRoute extends Route { @action error(error, transition) { if (error instanceof AbortError) { // the request was aborted, nothing to report return; } // ...other error handling logic } } ``` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/variables/AdapterError.md description: >- Legacy base error constructor an adapter uses to signal a failed API request; call `extend` on it to define app-specific error types. --- # AdapterError ```ts AdapterError: AdapterRequestErrorConstructor; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:89](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L89) :::danger ⚠️ **This is LEGACY documentation** for a feature that is no longer encouraged to be used. If starting a new app or thinking of implementing a new adapter, consider writing a Handler instead to be used with the [RequestManager](../../../../core/classes/RequestManager.md) ::: An `AdapterError` is used by an adapter to signal that an error occurred during a request to an external API. It indicates a generic error, and subclasses are used to indicate specific error states. To create a custom error to signal a specific error state in communicating with an external API, extend the `AdapterError`. For example, if the external API exclusively used HTTP `503 Service Unavailable` to indicate it was closed for maintenance: ```js [app/adapters/maintenance-error.js] import AdapterError from '@warp-drive/legacy/adapter/error'; export default AdapterError.extend({ message: "Down for maintenance." }); ``` This error would then be returned by an adapter's `handleResponse` method: ```js [app/adapters/application.js] import JSONAPIAdapter from '@warp-drive/legacy/adapter/json-api'; import MaintenanceError from './maintenance-error'; export default class ApplicationAdapter extends JSONAPIAdapter { handleResponse(status) { if (503 === status) { return new MaintenanceError(); } return super.handleResponse(...arguments); } } ``` And can then be detected in an application and used to send the user to an `under-maintenance` route: ```js [app/routes/application.js] import MaintenanceError from '../adapters/maintenance-error'; export default class ApplicationRoute extends Route { actions: { error(error, transition) { if (error instanceof MaintenanceError) { this.transitionTo('under-maintenance'); return; } // ...other error handling logic } } } ``` ### Signaling an Error Without Extending `AdapterError` Extending `AdapterError` (or one of its subclasses) is a convenience, not a requirement. WarpDrive only inspects an error for the [AdapterRequestError](../types/AdapterRequestError.md) shape: an `isAdapterError` flag, a `code`, and an {json:api}-formatted `errors` array. Any object satisfying that shape — including a plain `Error` with those properties attached — will be handled identically to an instance created via `new AdapterError()` or one of its subclasses. This is useful when you'd rather not introduce a class hierarchy, or when the error needs to be constructed from data you don't control (for example, re-throwing an error surfaced by a third-party library): ```js [app/adapters/application.js] import JSONAPIAdapter from '@warp-drive/legacy/adapter/json-api'; export default class ApplicationAdapter extends JSONAPIAdapter { handleResponse(status, headers, payload) { if (status === 503) { const error = new Error('Down for maintenance.'); error.isAdapterError = true; error.code = 'MaintenanceError'; error.errors = [{ title: 'Service Unavailable', detail: 'Down for maintenance.' }]; return error; } return super.handleResponse(status, headers, payload); } } ``` Because `code` is just a string you control, `error instanceof AdapterError` checks won't match a plain object built this way — consumers should instead branch on `error.isAdapterError && error.code === 'MaintenanceError'`, or on whichever of the AdapterError subclasses' `code` values (e.g. `'InvalidError'`, `'NotFoundError'`) the error's `code` matches. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/variables/ConflictError.md description: >- Legacy adapter error constructor for an HTTP 409 response, signaling that the request conflicts with existing server state, such as a duplicate client-generated id. --- # ConflictError ```ts ConflictError: AdapterRequestErrorConstructor; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:512](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L512) A `ConflictError` equates to an HTTP `409 Conflict` response status. It is used by an adapter to indicate that the request could not be processed because of a conflict in the request. An example scenario would be when creating a record with a client-generated ID but that ID is already known to the external API. An example use case would be to surface a conflict-specific message so the user can retry with different input: ```js [app/routes/application.js] import { ConflictError } from '@warp-drive/legacy/adapter/error'; export default class ApplicationRoute extends Route { @action error(error, transition) { if (error instanceof ConflictError) { alert('That identifier is already in use, please choose another.'); return; } // ...other error handling logic } } ``` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/variables/ForbiddenError.md description: >- Legacy adapter error constructor for an HTTP 403 response, signaling that the server refused a valid request the user lacks permission for. --- # ForbiddenError ```ts ForbiddenError: AdapterRequestErrorConstructor; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:421](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L421) A `ForbiddenError` equates to an HTTP `403 Forbidden` response status. It is used by an adapter to signal that a request to the external API was valid but the server is refusing to respond to it. If authorization was provided and is valid, then the authenticated user does not have the necessary permissions for the request. Unlike an [UnauthorizedError](UnauthorizedError.md), retrying the request with different credentials will not help; the currently authenticated user simply lacks permission. An example use case would be to show the user a "you don't have access to this" message rather than redirecting them to log in: ```js [app/routes/application.js] import { ForbiddenError } from '@warp-drive/legacy/adapter/error'; export default class ApplicationRoute extends Route { @action error(error, transition) { if (error instanceof ForbiddenError) { this.transitionTo('forbidden'); return; } // ...other error handling logic } } ``` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/variables/InvalidError.md description: >- Legacy adapter error signaling that the API rejected a request as semantically invalid, typically failed server-side validation, putting the record in the `invalid` state. --- # InvalidError ```ts InvalidError: AdapterRequestErrorConstructor; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:222](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L222) An `InvalidError` is used by an adapter to signal that the external API was unable to process a request because the content was not semantically correct or meaningful per the API. Usually, this means a record failed some form of server-side validation. When a promise from an adapter is rejected with an `InvalidError` the record will transition to the `invalid` state and the errors will be set to the `errors` property on the record. For WarpDrive to correctly map errors to their corresponding properties on the model, WarpDrive expects each error to be a valid {json:api} error object with a `source.pointer` that matches the property name. For example, if you had a `Post` model that looked like this: ```js [app/models/post.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class PostModel extends Model { @attr('string') title; @attr('string') content; } ``` To show an error from the server related to the `title` and `content` properties your adapter could return a promise that rejects with an `InvalidError` that looks like this: ```js [app/adapters/post.js] import RSVP from 'RSVP'; import RESTAdapter from '@warp-drive/legacy/adapter/rest'; import { InvalidError } from '@warp-drive/legacy/adapter/error'; export default class ApplicationAdapter extends RESTAdapter { updateRecord() { // Fictional adapter that always rejects return RSVP.reject(new InvalidError([ { detail: 'Must be unique', source: { pointer: '/data/attributes/title' } }, { detail: 'Must not be blank', source: { pointer: '/data/attributes/content' } } ])); } } ``` Your backend may use different property names for your records; the store will attempt to extract and normalize the errors using the serializer's `extractErrors` method before the errors get added to the model. As a result, it is safe for the `InvalidError` to wrap the error payload unaltered. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/variables/NotFoundError.md description: >- Legacy adapter error constructor for an HTTP 404 response, signaling that the requested resource does not exist on the API. --- # NotFoundError ```ts NotFoundError: AdapterRequestErrorConstructor; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:466](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L466) A `NotFoundError` equates to an HTTP `404 Not Found` response status. It is used by an adapter to signal that a request to the external API was rejected because the resource could not be found on the API. An example use case would be to detect if the user has entered a route for a specific model that does not exist. For example: ```js [app/routes/post.js] import { NotFoundError } from '@warp-drive/legacy/adapter/error'; export default class PostRoute extends Route { @service store; model(params) { return this.store.findRecord('post', params.post_id); } @action error(error, transition) { if (error instanceof NotFoundError) { // redirect to a list of all posts instead this.transitionTo('posts'); } else { // otherwise let the error bubble return true; } } } ``` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/variables/ServerError.md description: >- Legacy adapter error constructor for an HTTP 500 response, signaling that the API failed internally and an immediate retry is unlikely to succeed. --- # ServerError ```ts ServerError: AdapterRequestErrorConstructor; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:555](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L555) A `ServerError` equates to an HTTP `500 Internal Server Error` response status. It is used by the adapter to indicate that a request has failed because of an error in the external API, and is unlikely to succeed if retried immediately. An example use case would be to show a generic "something went wrong on our end" message rather than one implying the user made a mistake: ```js [app/routes/application.js] import { ServerError } from '@warp-drive/legacy/adapter/error'; export default class ApplicationRoute extends Route { @action error(error, transition) { if (error instanceof ServerError) { alert('Something went wrong on our end. Please try again later.'); return; } // ...other error handling logic } } ``` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/variables/TimeoutError.md description: >- Legacy adapter error constructor for signaling that a request to the API timed out without receiving a response. --- # TimeoutError ```ts TimeoutError: AdapterRequestErrorConstructor; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:293](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L293) A `TimeoutError` is used by an adapter to signal that a request to the external API has timed out, i.e. no response was received from the external API within an allowed time period. An example use case would be to warn the user to check their internet connection if an adapter operation has timed out: ```js [app/routes/application.js] import { TimeoutError } from '@warp-drive/legacy/adapter/error'; export default class ApplicationRoute extends Route { @action error(error, transition) { if (error instanceof TimeoutError) { // alert the user alert('Are you still connected to the Internet?'); return; } // ...other error handling logic } } ``` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/error/variables/UnauthorizedError.md description: >- Legacy adapter error constructor for an HTTP 401 response, signaling that authorization is required and failed or was not provided. --- # UnauthorizedError ```ts UnauthorizedError: AdapterRequestErrorConstructor; ``` Defined in: [warp-drive-packages/legacy/src/adapter/error.ts:378](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/error.ts#L378) A `UnauthorizedError` equates to an HTTP `401 Unauthorized` response status. It is used by an adapter to signal that a request to the external API was rejected because authorization is required and has failed or has not yet been provided. An example use case would be to redirect the user to a login route if a request is unauthorized: ```js [app/routes/application.js] import { UnauthorizedError } from '@warp-drive/legacy/adapter/error'; export default class ApplicationRoute extends Route { @action error(error, transition) { if (error instanceof UnauthorizedError) { // go to the login route this.transitionTo('login'); return; } // ...other error handling logic } } ``` --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/adapter.md description: >- Legacy adapter layer through which the store fetches and saves data from an API, superseded by `RequestManager` handlers. --- ## Overview :::danger ⚠️ **This is LEGACY documentation** for a feature that is no longer encouraged to be used. If starting a new app or thinking of implementing a new adapter, consider writing a Handler instead to be used with the [RequestManager](../../core/classes/RequestManager.md) :::: In order to properly fetch and update data, @warp-drive/legacy needs to understand how to connect to your API. `Adapters` accept various kinds of requests from the store and manage fulfillment of the request from your API. ### Why It's Legacy The Adapter pattern was designed for class-based architectures in which each resource type could have its own data-fetching logic: * `store.adapterFor` resolves an adapter by resource type at runtime, looking up `adapter:` and then `adapter:application` through Ember's owner. * Each request is fulfilled by a single adapter, so sharing behavior across resource types means extending a common base class rather than composing request logic. * The provided adapter classes extend `EmberObject`, which, together with the owner lookup, ties the pattern to Ember. * Adapter methods resolve with an untyped `AdapterPayload`, so nothing ties the response's type to the request that produced it. ### Modern Alternative Use [Handlers](/api/@warp-drive/core/request/types/Handler) with the [RequestManager](../../core/classes/RequestManager.md). Each request passes through a chain of handlers, any of which can fulfill it, modify it or pass it along. Handlers support: * request builders, which return a request typed with its expected response, so `store.request` resolves with that type * composition: `RequestManager.use` takes a list of handlers, such as the built-in `Fetch` handler, and wrappers such as `Gate` from `@warp-drive/utilities/handlers` run another handler only for the requests it accepts * explicit imports rather than lookup by name at runtime * any framework ***Warp*Drive** supports, since `@warp-drive/core` has no runtime dependency on Ember (see [Installation](/guides/installation/)) For an alternative modern pattern to Adapters, see the [Request Handlers Guide](/guides/the-manual/requests/handlers). ### Request Flow When the store decides it needs to issue a request it uses the following flow to manage the request and process the data. * find the appropriate adapter * issue the request to the adapter * await the adapter's response * if an error occurs reject with the error * if no error * if there is response data * pass the response data to the appropriate serializer * update the cache using the JSON:API formatted data from the serializer's response * return the primary record(s) associated with the request ### Request Errors When a request errors and your adapter does not have the ability to recover from the error, you may either reject the promise returned by your adapter method with the error or simply throw the error. If the request was for a `createRecord` `updateRecord` or `deleteRecord` special rules apply to how this error will affect the state of the store and additional properties on the `Error` class may be used. See the documentation for these methods in [MinimumAdapterInterface](../compat/types/MinimumAdapterInterface.md) for more information. ### Implementing an Adapter There are seven required adapter methods, one for each of the primary request types that @warp-drive/legacy issues. They are: * findRecord * findAll * queryRecord * query * createRecord * updateRecord * deleteRecord Each of these request types has a matching store method that triggers it and matching `requestType` that is passed to the serializer's `normalizeResponse` method. If your app only reads data but never writes data, it is not necessary to implement the methods for create, update, and delete. This extends to all of the store's find methods with the exception of `findRecord` (`findAll`, `query`, `queryRecord`): if you do not use the store method in your app then your Adapter does not need the method. ```ts async function fetchData(url, options = {}) { let response = await fetch(url, options); return response.toJSON(); } export default class ApplicationAdapter { findRecord(_, { modelName }, id) { return fetchData(`./${modelName}s/${id}`); } static create() { return new this(); } } ``` ### Adapter Resolution `store.adapterFor(name)` will lookup adapters defined in `app/adapters/` and return an instance. `adapterFor` first attempts to find an adapter with an exact match on `name`, then falls back to checking for the presence of an adapter named `application`. If no adapter is found, an error will be thrown. ```ts store.adapterFor('author'); // lookup paths (in order) => // app/adapters/author.js // app/adapters/application.js ``` Most requests in @warp-drive/legacy are made with respect to a particular `type` (or `modelName`) (e.g., "get me the full collection of **books**" or "get me the **employee** whose id is 37"). We refer to this as the **primary** resource `type`. `adapterFor` is used by the store to find an adapter with a name matching that of the primary resource `type` for the request, which then falls back to the `application` adapter. It is recommended that applications define only a single `application` adapter and serializer where possible, only implementing an adapter specific to the `type` when absolutely necessary. If you need to support multiple API versions for the same type, the per-type strategy for defining adapters might not be adequate. If you have multiple APIs or multiple API versions and the single application adapter and per-type strategy does not suite your needs, one strategy is to write an `application` adapter and serializer that make use of `options` to specify the desired format when making a request, then forwards to the request to the desired adapter or serializer as needed. ```js [app/adapters/application.js] export default class Adapter extends EmberObject { findRecord(store, schema, id, snapshot) { let { apiVersion } = snapshot.adapterOptions; return this.adapterFor(`-api-${apiVersion}`).findRecord(store, schema, id, snapshot); } } ``` ### Overriding `Store.adapterFor` ```js import Store from '@ember-data/store'; import Adapter from '@ember-data/adapter/json-api'; class extends Store { #adapter = new Adapter(); adapterFor() { return this.#adapter; } } ``` Note: If you are using Ember and would like to make use of `service` injections in your adapter, you will want to additionally `setOwner` for the Adapter. ```js import Store from '@ember-data/store'; import Adapter from '@ember-data/adapter/json-api'; import { getOwner, setOwner } from '@ember/owner'; class extends Store { #adapter = null; adapterFor() { let adapter = this.#adapter; if (!adapter) { const owner = getOwner(this); adapter = new Adapter(); setOwner(adapter, owner); this.#adapter = adapter; } return adapter; } } ``` By default when using with Ember you only need to implement this hook if you want your adapter usage to be statically analyzeable. *Ember***Data** will attempt to resolve adapters using Ember's resolver. To provide a single Adapter for your application like the above you would provide it as the default export of the file `app/adapters/application.{js/ts}` ### Using an Adapter Any adapter in `app/adapters/` can be looked up by `name` using `store.adapterFor(name)`. ### Default Adapters Applications whose API's structure endpoint URLs *very close to* or *exactly* the **REST** or **JSON:API** convention, the `@ember-data/adapter` package contains implementations these applications can extend. Many applications will find writing their own adapter to be allow greater flexibility, customization, and maintenance than attempting to override methods in these adapters. ## Classes * [Adapter](classes/Adapter.md) ## Variables * [BuildURLMixin](variables/BuildURLMixin.md) ## Types * [BuildURLMixin](types/BuildURLMixin.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/json-api/classes/JSONAPIAdapter.md description: >- Legacy adapter that turns store requests into HTTP requests following JSON:API URL, verb, and `application/vnd.api+json` conventions. --- # JSONAPIAdapter Defined in: [warp-drive-packages/legacy/src/adapter/json-api.ts:164](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/json-api.ts#L164) ## Overview :::danger ⚠️ **This is LEGACY documentation** for a feature that is no longer encouraged to be used. If starting a new app or thinking of implementing a new adapter, consider writing a Handler instead to be used with the [RequestManager](../../../../core/classes/RequestManager.md) ::: The `JSONAPIAdapter` is an adapter which transforms the store's requests into HTTP requests that follow the [JSON API format](http://jsonapi.org/format/). ## JSON API Conventions The JSONAPIAdapter uses JSON API conventions for building the URL for a record and selecting the HTTP verb to use with a request. The actions you can take on a record map onto the following URLs in the JSON API adapter: ## Success and failure The JSONAPIAdapter will consider a success any response with a status code of the 2xx family ("Success"), as well as 304 ("Not Modified"). Any other status code will be considered a failure. On success, the request promise will be resolved with the full response payload. Failed responses with status code 422 ("Unprocessable Entity") will be considered "invalid". The response will be discarded, except for the `errors` key. The request promise will be rejected with a `InvalidError`. This error object will encapsulate the saved `errors` value. Any other status codes will be treated as an adapter error. The request promise will be rejected, similarly to the invalid case, but with an instance of `AdapterError` instead. ### Endpoint path customization Endpoint paths can be prefixed with a `namespace` by setting the namespace property on the adapter: ```js [app/adapters/application.js] import { JSONAPIAdapter } from '@warp-drive/legacy/adapter/json-api'; export default class ApplicationAdapter extends JSONAPIAdapter { namespace = 'api/1'; } ``` Requests for the `person` model would now target `/api/1/people/1`. ### Host customization An adapter can target other hosts by setting the `host` property. ```js [app/adapters/application.js] import JSONAPIAdapter from '@warp-drive/legacy/adapter/json-api'; export default class ApplicationAdapter extends JSONAPIAdapter { host = 'https://api.example.com'; } ``` Requests for the `person` model would now target `https://api.example.com/people/1`. ## Extends * [`RESTAdapter`](../../rest/classes/RESTAdapter.md) ## Constructors ### Constructor ```ts new JSONAPIAdapter(owner?: Owner): JSONAPIAdapter; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:139](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L139) #### Parameters ##### owner? `Owner` #### Returns `JSONAPIAdapter` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`constructor`](../../rest/classes/RESTAdapter.md#constructor) ## Methods ### buildQuery() ```ts buildQuery(snapshot: Snapshot | SnapshotRecordArray): QueryState; ``` Defined in: [warp-drive-packages/legacy/src/adapter/json-api.ts:295](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/json-api.ts#L295) Used by `findAll` and `findRecord` to build the query's `data` hash supplied to the ajax method. #### Parameters ##### snapshot `Snapshot`<`unknown`> | `SnapshotRecordArray` #### Returns [`QueryState`](../../rest/types/QueryState.md) #### Overrides [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildQuery`](../../rest/classes/RESTAdapter.md#buildquery) *** ### buildURL() ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: SnapshotRecordArray, requestType: "findAll" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "query", query: Record ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "queryRecord", query: Record ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string[], snapshot: Snapshot[], requestType: "findMany" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findHasMany" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findBelongsTo" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string | null, snapshot: Snapshot, requestType: "createRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "updateRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "deleteRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot ): string; ``` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:44](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L44) Builds a URL for a given type and optional ID. By default, it pluralizes the type's name (for example, 'post' becomes 'posts' and 'person' becomes 'people'). To override the pluralization see [pathForType](../../types/BuildURLMixin.md#pathfortype). If an ID is specified, it adds the ID to the path generated for the type, separated by a `/`. This overload builds the URL for a `store.findRecord(type, id)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"findRecord"` ##### Returns `string` ##### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildURL`](../../rest/classes/RESTAdapter.md#buildurl) #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: SnapshotRecordArray, requestType: "findAll" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:56](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L56) Builds the URL for a `store.findAll(type)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `null` ###### snapshot `SnapshotRecordArray` ###### requestType `"findAll"` ##### Returns `string` ##### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildURL`](../../rest/classes/RESTAdapter.md#buildurl) #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "query", query: Record ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:68](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L68) Builds the URL for a `store.query(type, query)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `null` ###### snapshot `null` ###### requestType `"query"` ###### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### Returns `string` ##### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildURL`](../../rest/classes/RESTAdapter.md#buildurl) #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "queryRecord", query: Record ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:81](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L81) Builds the URL for a `store.queryRecord(type, query)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `null` ###### snapshot `null` ###### requestType `"queryRecord"` ###### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### Returns `string` ##### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildURL`](../../rest/classes/RESTAdapter.md#buildurl) #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string[], snapshot: Snapshot[], requestType: "findMany" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:97](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L97) Builds the URL for coalescing multiple `store.findRecord(type, id)` records into 1 request when the adapter's `coalesceFindRequests` property is `true`. The `id` and `snapshot` parameters will be arrays of ids and snapshots. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string`\[] ###### snapshot `Snapshot`<`unknown`>\[] ###### requestType `"findMany"` ##### Returns `string` ##### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildURL`](../../rest/classes/RESTAdapter.md#buildurl) #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findHasMany" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:110](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L110) Builds the URL for fetching an async `hasMany` relationship when a URL is not provided by the server. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"findHasMany"` ##### Returns `string` ##### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildURL`](../../rest/classes/RESTAdapter.md#buildurl) #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findBelongsTo" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:123](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L123) Builds the URL for fetching an async `belongsTo` relationship when a URL is not provided by the server. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"findBelongsTo"` ##### Returns `string` ##### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildURL`](../../rest/classes/RESTAdapter.md#buildurl) #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string | null, snapshot: Snapshot, requestType: "createRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:136](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L136) Builds the URL for a `record.save()` call when the record was created locally using `store.createRecord()`. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` | `null` ###### snapshot `Snapshot` ###### requestType `"createRecord"` ##### Returns `string` ##### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildURL`](../../rest/classes/RESTAdapter.md#buildurl) #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "updateRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:149](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L149) Builds the URL for a `record.save()` call when the record has been updated locally. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"updateRecord"` ##### Returns `string` ##### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildURL`](../../rest/classes/RESTAdapter.md#buildurl) #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "deleteRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:162](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L162) Builds the URL for a `record.save()` call when the record has been deleted locally. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"deleteRecord"` ##### Returns `string` ##### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildURL`](../../rest/classes/RESTAdapter.md#buildurl) #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:174](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L174) Builds a URL for a given type and ID without a specific request type. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ##### Returns `string` ##### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`buildURL`](../../rest/classes/RESTAdapter.md#buildurl) *** ### createRecord() ```ts createRecord( store: Store$1, type: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:818](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L818) Called by the store when a newly created record is saved via the `save` method on a model record instance. The `createRecord` method serializes the record and makes an Ajax (HTTP POST) request to a URL computed by `buildURL`. See `serialize` for information on how to customize the serialized form of a record. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`createRecord`](../../rest/classes/RESTAdapter.md#createrecord) *** ### deleteRecord() ```ts deleteRecord( store: Store$1, schema: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:855](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L855) Called by the store when a record is deleted. The `deleteRecord` method makes an Ajax (HTTP DELETE) request to a URL computed by `buildURL`. #### Parameters ##### store `Store$1` ##### schema `ModelSchema` ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`deleteRecord`](../../rest/classes/RESTAdapter.md#deleterecord) *** ### findAll() ```ts findAll( store: Store$1, type: ModelSchema, neverUsed: null, snapshotRecordArray: SnapshotRecordArray ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:617](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L617) Called by the store in order to fetch a JSON array for all of the records for a given type. The `findAll` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a promise for the resulting payload. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### neverUsed `null` ##### snapshotRecordArray `SnapshotRecordArray` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`findAll`](../../rest/classes/RESTAdapter.md#findall) *** ### findBelongsTo() ```ts findBelongsTo( store: Store$1, snapshot: Snapshot, url: string, relationship: unknown ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:794](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L794) Called by the store in order to fetch the JSON for the unloaded record in a belongs-to relationship that was originally specified as a URL (inside of `links`). For example, if your original payload looks like this: ```js { "person": { "id": 1, "name": "Tom Dale", "links": { "group": "/people/1/group" } } } ``` This method will be called with the parent record and `/people/1/group`. The `findBelongsTo` method will make an Ajax (HTTP GET) request to the originally specified URL. The format of your `links` value will influence the final request URL via the `urlPrefix` method: * Links beginning with `//`, `http://`, `https://`, will be used as is, with no further manipulation. * Links beginning with a single `/` will have the current adapter's `host` value prepended to it. * Links with no beginning `/` will have a parentURL prepended to it, via the current adapter's `buildURL`. #### Parameters ##### store `Store$1` ##### snapshot `Snapshot` ##### url `string` ##### relationship `unknown` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`findBelongsTo`](../../rest/classes/RESTAdapter.md#findbelongsto) *** ### findHasMany() ```ts findHasMany( store: Store$1, snapshot: Snapshot, url: string, relationship: Record ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:745](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L745) Called by the store in order to fetch a JSON array for the unloaded records in a has-many relationship that were originally specified as a URL (inside of `links`). For example, if your original payload looks like this: ```js { "post": { "id": 1, "title": "Rails is omakase", "links": { "comments": "/posts/1/comments" } } } ``` This method will be called with the parent record and `/posts/1/comments`. The `findHasMany` method will make an Ajax (HTTP GET) request to the originally specified URL. The format of your `links` value will influence the final request URL via the `urlPrefix` method: * Links beginning with `//`, `http://`, `https://`, will be used as is, with no further manipulation. * Links beginning with a single `/` will have the current adapter's `host` value prepended to it. * Links with no beginning `/` will have a parentURL prepended to it, via the current adapter's `buildURL`. #### Parameters ##### store `Store$1` ##### snapshot `Snapshot` ##### url `string` ##### relationship [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`findHasMany`](../../rest/classes/RESTAdapter.md#findhasmany) *** ### findMany() ```ts findMany( store: Store$1, type: ModelSchema, ids: string[], snapshots: Snapshot[] ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/json-api.ts:258](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/json-api.ts#L258) Called by the store in order to fetch several records together if `coalesceFindRequests` is true For example, if the original payload looks like: ```js { "id": 1, "title": "Rails is omakase", "comments": [ 1, 2, 3 ] } ``` The IDs will be passed as a URL-encoded Array of IDs, in this form: ``` ids[]=1&ids[]=2&ids[]=3 ``` Many servers, such as Rails and PHP, will automatically convert this URL-encoded array into an Array for you on the server-side. If you want to encode the IDs, differently, just override this (one-line) method. The `findMany` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a promise for the resulting payload. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### ids `string`\[] ##### snapshots `Snapshot`<`unknown`>\[] #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Overrides [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`findMany`](../../rest/classes/RESTAdapter.md#findmany) *** ### findRecord() ```ts findRecord( store: Store$1, type: ModelSchema, id: string, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:601](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L601) Called by the store in order to fetch the JSON for a given type and ID. The `findRecord` method makes an Ajax request to a URL computed by `buildURL`, and returns a promise for the resulting payload. This method performs an HTTP `GET` request with the id provided as part of the query string. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### id `string` ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`findRecord`](../../rest/classes/RESTAdapter.md#findrecord) *** ### groupRecordsForFindMany() ```ts groupRecordsForFindMany(store: Store$1, snapshots: Snapshot[]): Snapshot[][]; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:922](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L922) Organize records into groups, each of which is to be passed to separate calls to `findMany`. This implementation groups together records that have the same base URL but differing ids. For example `/comments/1` and `/comments/2` will be grouped together because we know findMany can coalesce them together as `/comments?ids[]=1&ids[]=2` It also supports urls where ids are passed as a query param, such as `/comments?id=1` but not those where there is more than 1 query param such as `/comments?id=2&name=David` Currently only the query param of `id` is supported. If you need to support others, please override this or the `_stripIDFromURL` method. It does not group records that have differing base urls, such as for example: `/posts/1/comments/2` and `/posts/2/comments/3` #### Parameters ##### store `Store$1` ##### snapshots `Snapshot`<`unknown`>\[] #### Returns `Snapshot`<`unknown`>\[]\[] an array of arrays of records, each of which is to be loaded separately by `findMany`. #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`groupRecordsForFindMany`](../../rest/classes/RESTAdapter.md#grouprecordsforfindmany) *** ### handleResponse() ```ts handleResponse( status: number, headers: Record, payload: Payload, requestData: RequestData ): | AdapterRequestErrorConstructor | Payload; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:970](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L970) Takes an ajax response, and returns the json payload or an error. By default this hook just returns the json payload passed to it. You might want to override it in two cases: 1. Your API might return useful results in the response headers. Response headers are passed in as the second argument. 2. Your API might return errors as successful responses with status code 200 and an Errors text or object. You can return a `InvalidError` or a `AdapterError` (or a sub class) from this hook and it will automatically reject the promise and put your record into the invalid or error state. Returning a `InvalidError` from this method will cause the record to transition into the `invalid` state and make the `errors` object available on the record. When returning an `InvalidError` the store will attempt to normalize the error data returned from the server using the serializer's `extractErrors` method. #### Parameters ##### status `number` ##### headers [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `string`> ##### payload `Payload` ##### requestData [`RequestData`](../../rest/types/RequestData.md) #### Returns | [`AdapterRequestErrorConstructor`](../../error/types/AdapterRequestErrorConstructor.md)<[`AdapterError`](../../error/types/AdapterError.md)> | `Payload` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`handleResponse`](../../rest/classes/RESTAdapter.md#handleresponse) *** ### isInvalid() ```ts isInvalid( status: number, _headers: Record, _payload: Payload ): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:1024](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L1024) Default `handleResponse` implementation uses this hook to decide if the response is an invalid error. #### Parameters ##### status `number` ##### \_headers [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### \_payload `Payload` #### Returns `boolean` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`isInvalid`](../../rest/classes/RESTAdapter.md#isinvalid) *** ### isSuccess() ```ts isSuccess( status: number, _headers: Record, _payload: Payload ): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:1013](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L1013) Default `handleResponse` implementation uses this hook to decide if the response is a success. #### Parameters ##### status `number` ##### \_headers [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### \_payload `Payload` #### Returns `boolean` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`isSuccess`](../../rest/classes/RESTAdapter.md#issuccess) *** ### pathForType() ```ts pathForType(modelName: string): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/json-api.ts:270](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/json-api.ts#L270) Determines the pathname for a given type. Unlike the base `BuildURLMixin` implementation, dasherizes (rather than camelizes) the type name before pluralizing it, per the {json:api} convention for member names. #### Parameters ##### modelName `string` #### Returns `string` #### Overrides [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`pathForType`](../../rest/classes/RESTAdapter.md#pathfortype) *** ### query() ```ts query( store: Store$1, type: ModelSchema, query: Record ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:642](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L642) Called by the store in order to fetch a JSON array for the records that match a particular query. The `query` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a promise for the resulting payload. The `query` argument is a simple JavaScript object that will be passed directly to the server as parameters. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`query`](../../rest/classes/RESTAdapter.md#query) *** ### queryRecord() ```ts queryRecord( store: Store$1, type: ModelSchema, query: Record, adapterOptions: Record ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:666](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L666) Called by the store in order to fetch a JSON object for the record that matches a particular query. The `queryRecord` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a promise for the resulting payload. The `query` argument is a simple JavaScript object that will be passed directly to the server as parameters. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### adapterOptions [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`queryRecord`](../../rest/classes/RESTAdapter.md#queryrecord) *** ### serialize() ```ts serialize(snapshot: Snapshot, options: SerializerOptions): Record; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:500](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L500) Proxies to the serializer's `serialize` method. Example ```js [app/adapters/application.js] import { Adapter } from '@warp-drive/legacy/adapter'; export default class ApplicationAdapter extends Adapter { createRecord(store, type, snapshot) { let data = this.serialize(snapshot, { includeId: true }); let url = `/${type.modelName}`; // ... } } ``` #### Parameters ##### snapshot `Snapshot` ##### options [`SerializerOptions`](../../../compat/types/SerializerOptions.md) #### Returns [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`serialize`](../../rest/classes/RESTAdapter.md#serialize) *** ### shouldBackgroundReloadAll() ```ts shouldBackgroundReloadAll(store: Store$1, snapshotRecordArray: SnapshotRecordArray): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:907](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L907) This method is used by the store to determine if the store should reload a record array after the `store.findAll` method resolves with a cached record array. This method is *only* checked by the store when the store is returning a cached record array. If this method returns `true` the store will re-fetch all records from the adapter. For example, if you do not want to fetch complex data over a mobile connection, or if the network is down, you can implement `shouldBackgroundReloadAll` as follows: ```javascript shouldBackgroundReloadAll(store, snapshotArray) { let { downlink, effectiveType } = navigator.connection; return downlink > 0 && effectiveType === '4g'; } ``` By default this method returns `true`, indicating that a background reload should always be triggered. #### Parameters ##### store `Store$1` ##### snapshotRecordArray `SnapshotRecordArray` #### Returns `boolean` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`shouldBackgroundReloadAll`](../../rest/classes/RESTAdapter.md#shouldbackgroundreloadall) *** ### shouldBackgroundReloadRecord() ```ts shouldBackgroundReloadRecord(store: Store$1, snapshot: Snapshot): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:871](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L871) This method is used by the store to determine if the store should reload a record after the `store.findRecord` method resolves a cached record. This method is *only* checked by the store when the store is returning a cached record. If this method returns `true` the store will re-fetch a record from the adapter. For example, if you do not want to fetch complex data over a mobile connection, or if the network is down, you can implement `shouldBackgroundReloadRecord` as follows: ```javascript shouldBackgroundReloadRecord(store, snapshot) { let { downlink, effectiveType } = navigator.connection; return downlink > 0 && effectiveType === '4g'; } ``` By default, this hook returns `true` so the data for the record is updated in the background. #### Parameters ##### store `Store$1` ##### snapshot `Snapshot` #### Returns `boolean` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`shouldBackgroundReloadRecord`](../../rest/classes/RESTAdapter.md#shouldbackgroundreloadrecord) *** ### shouldReloadAll() ```ts shouldReloadAll(store: Store$1, snapshotRecordArray: SnapshotRecordArray): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:835](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L835) This method is used by the store to determine if the store should reload all records from the adapter when records are requested by `store.findAll`. If this method returns `true`, the store will re-fetch all records from the adapter. If this method returns `false`, the store will resolve immediately using the cached records. For example, if you are building an events ticketing system, in which users can only reserve tickets for 20 minutes at a time, and want to ensure that in each route you have data that is no more than 20 minutes old you could write: ```javascript shouldReloadAll(store, snapshotArray) { let snapshots = snapshotArray.snapshots(); return snapshots.any((ticketSnapshot) => { let lastAccessedAt = ticketSnapshot.attr('lastAccessedAt'); let timeDiff = moment().diff(lastAccessedAt, 'minutes'); if (timeDiff > 20) { return true; } else { return false; } }); } ``` This method would ensure that whenever you do `store.findAll('ticket')` you will always get a list of tickets that are no more than 20 minutes old. In case a cached version is more than 20 minutes old, `findAll` will not resolve until you fetched the latest versions. By default, this method returns `true` if the passed `snapshotRecordArray` is empty (meaning that there are no records locally available yet), otherwise, it returns `false`. Note that, with default settings, `shouldBackgroundReloadAll` will always re-fetch all the records in the background even if `shouldReloadAll` returns `false`. You can override `shouldBackgroundReloadAll` if this does not suit your use case. #### Parameters ##### store `Store$1` ##### snapshotRecordArray `SnapshotRecordArray` #### Returns `boolean` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`shouldReloadAll`](../../rest/classes/RESTAdapter.md#shouldreloadall) *** ### shouldReloadRecord() ```ts shouldReloadRecord(store: Store$1, snapshot: Snapshot): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:780](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L780) This method is used by the store to determine if the store should reload a record from the adapter when a record is requested by `store.findRecord`. If this method returns `true`, the store will re-fetch a record from the adapter. If this method returns `false`, the store will resolve immediately using the cached record. For example, if you are building an events ticketing system, in which users can only reserve tickets for 20 minutes at a time, and want to ensure that in each route you have data that is no more than 20 minutes old you could write: ```javascript shouldReloadRecord(store, ticketSnapshot) { let lastAccessedAt = ticketSnapshot.attr('lastAccessedAt'); let timeDiff = moment().diff(lastAccessedAt, 'minutes'); if (timeDiff > 20) { return true; } else { return false; } } ``` This method would ensure that whenever you do `store.findRecord('ticket', id)` you will always get a ticket that is no more than 20 minutes old. In case the cached version is more than 20 minutes old, `findRecord` will not resolve until you fetched the latest version. By default this hook returns `false`, as most UIs should not block user interactions while waiting on data update. Note that, with default settings, `shouldBackgroundReloadRecord` will always re-fetch the records in the background even if `shouldReloadRecord` returns `false`. You can override `shouldBackgroundReloadRecord` if this does not suit your use case. #### Parameters ##### store `Store$1` ##### snapshot `Snapshot` #### Returns `boolean` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`shouldReloadRecord`](../../rest/classes/RESTAdapter.md#shouldreloadrecord) *** ### sortQueryParams() ```ts sortQueryParams(obj: Record): Record; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:460](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L460) By default, the RESTAdapter will send the query params sorted alphabetically to the server. For example: ```js store.query('posts', { sort: 'price', category: 'pets' }); ``` will generate a requests like this `/posts?category=pets&sort=price`, even if the parameters were specified in a different order. That way the generated URL will be deterministic and that simplifies caching mechanisms in the backend. Setting `sortQueryParams` to a falsey value will respect the original order. In case you want to sort the query parameters with a different criteria, set `sortQueryParams` to your custom sort function. ```js [app/adapters/application.js] import { RESTAdapter } from '@warp-drive/legacy/adapter/rest'; export default class ApplicationAdapter extends RESTAdapter { sortQueryParams(params) { let sortedKeys = Object.keys(params).sort().reverse(); let len = sortedKeys.length, newParams = {}; for (let i = 0; i < len; i++) { newParams[sortedKeys[i]] = params[sortedKeys[i]]; } return newParams; } } ``` #### Parameters ##### obj [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`sortQueryParams`](../../rest/classes/RESTAdapter.md#sortqueryparams) *** ### updateRecord() ```ts updateRecord( store: Store$1, schema: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/json-api.ts:275](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/json-api.ts#L275) Called by the store when an existing record is saved via the `save` method on a model record instance. The `updateRecord` method serializes the record and makes an Ajax (HTTP PUT) request to a URL computed by `buildURL`. See `serialize` for information on how to customize the serialized form of a record. #### Parameters ##### store `Store$1` ##### schema `ModelSchema` ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Overrides [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`updateRecord`](../../rest/classes/RESTAdapter.md#updaterecord) *** ### urlForCreateRecord() ```ts urlForCreateRecord( this: MixtBuildURLMixin, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:231](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L231) Builds a URL for a `record.save()` call when the record was created locally using `store.createRecord()`. #### Parameters ##### this `MixtBuildURLMixin` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`urlForCreateRecord`](../../rest/classes/RESTAdapter.md#urlforcreaterecord) *** ### urlForDeleteRecord() ```ts urlForDeleteRecord( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:245](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L245) Builds a URL for a `record.save()` call when the record has been deleted locally. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`urlForDeleteRecord`](../../rest/classes/RESTAdapter.md#urlfordeleterecord) *** ### urlForFindAll() ```ts urlForFindAll( this: MixtBuildURLMixin, modelName: string, snapshots: SnapshotRecordArray ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:190](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L190) Builds a URL for a `store.findAll(type)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### modelName `string` ##### snapshots `SnapshotRecordArray` #### Returns `string` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`urlForFindAll`](../../rest/classes/RESTAdapter.md#urlforfindall) *** ### urlForFindBelongsTo() ```ts urlForFindBelongsTo( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:224](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L224) Builds a URL for fetching an async `belongsTo` relationship when a URL is not provided by the server. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`urlForFindBelongsTo`](../../rest/classes/RESTAdapter.md#urlforfindbelongsto) *** ### urlForFindHasMany() ```ts urlForFindHasMany( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:217](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L217) Builds a URL for fetching an async `hasMany` relationship when a URL is not provided by the server. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`urlForFindHasMany`](../../rest/classes/RESTAdapter.md#urlforfindhasmany) *** ### urlForFindMany() ```ts urlForFindMany( this: MixtBuildURLMixin, ids: string[], modelName: string, snapshots: Snapshot[] ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:210](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L210) Builds a URL for coalescing multiple `store.findRecord(type, id)` records into 1 request when the adapter's `coalesceFindRequests` property is `true`. #### Parameters ##### this `MixtBuildURLMixin` ##### ids `string`\[] ##### modelName `string` ##### snapshots `Snapshot`<`unknown`>\[] #### Returns `string` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`urlForFindMany`](../../rest/classes/RESTAdapter.md#urlforfindmany) *** ### urlForFindRecord() ```ts urlForFindRecord( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:184](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L184) Builds a URL for a `store.findRecord(type, id)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`urlForFindRecord`](../../rest/classes/RESTAdapter.md#urlforfindrecord) *** ### urlForQuery() ```ts urlForQuery( this: MixtBuildURLMixin, query: Record, modelName: string ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:202](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L202) Builds a URL for a `store.query(type, query)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### modelName `string` #### Returns `string` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`urlForQuery`](../../rest/classes/RESTAdapter.md#urlforquery) *** ### urlForQueryRecord() ```ts urlForQueryRecord( this: MixtBuildURLMixin, query: Record, modelName: string ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:196](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L196) Builds a URL for a `store.queryRecord(type, query)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### modelName `string` #### Returns `string` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`urlForQueryRecord`](../../rest/classes/RESTAdapter.md#urlforqueryrecord) *** ### urlForUpdateRecord() ```ts urlForUpdateRecord( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:238](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L238) Builds a URL for a `record.save()` call when the record has been updated locally. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`urlForUpdateRecord`](../../rest/classes/RESTAdapter.md#urlforupdaterecord) ## Properties ### \_defaultContentType ```ts _defaultContentType: string = 'application/vnd.api+json'; ``` Defined in: [warp-drive-packages/legacy/src/adapter/json-api.ts:169](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/json-api.ts#L169) The `Content-Type` header used when serializing request bodies that don't otherwise specify one. #### Overrides [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`_defaultContentType`](../../rest/classes/RESTAdapter.md#_defaultcontenttype) *** ### headers ```ts headers: | Record | undefined; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:587](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L587) Some APIs require HTTP headers, e.g. to provide an API key. Arbitrary headers can be set as key/value pairs on the `RESTAdapter`'s `headers` object and WarpDrive will send them along with each ajax request.. ```js [app/adapters/application.js] import { RESTAdapter } from '@warp-drive/legacy/adapter/rest'; export default class ApplicationAdapter extends RESTAdapter { get headers() { return { 'API_KEY': 'secret key', 'ANOTHER_HEADER': 'Some header value' }; } } ``` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`headers`](../../rest/classes/RESTAdapter.md#headers) *** ### host ```ts host: string | null; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:378](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L378) See "Host customization" above. #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`host`](../../rest/classes/RESTAdapter.md#host) *** ### maxURLLength ```ts maxURLLength: number = 2048; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:900](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L900) The maximum URL length to allow when coalescing `findRecord` requests into a single `findMany` request via [groupRecordsForFindMany](../../rest/classes/RESTAdapter.md#grouprecordsforfindmany). Requests that would exceed this length are split into multiple groups. See http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`maxURLLength`](../../rest/classes/RESTAdapter.md#maxurllength) *** ### namespace ```ts namespace: string | null; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:382](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L382) See "Namespace customization" above. #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`namespace`](../../rest/classes/RESTAdapter.md#namespace) *** ### store ```ts store: Store$1; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:297](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L297) The Store service instance that owns this Adapter. #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`store`](../../rest/classes/RESTAdapter.md#store) *** ### useFetch ```ts useFetch: boolean = true; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:390](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L390) This property allows ajax to still be used instead when `false`. #### Default ```ts true @public ``` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`useFetch`](../../rest/classes/RESTAdapter.md#usefetch) ### coalesceFindRequests #### Get Signature ```ts get coalesceFindRequests(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter/json-api.ts:246](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/json-api.ts#L246) By default the JSONAPIAdapter will send each find request coming from a `store.find` or from accessing a relationship separately to the server. If your server supports passing ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests within a single runloop. For example, if you have an initial payload of: ```javascript { data: { id: 1, type: 'post', relationship: { comments: { data: [ { id: 1, type: 'comment' }, { id: 2, type: 'comment' } ] } } } } ``` By default calling `post.comments` will trigger the following requests(assuming the comments haven't been loaded before): ``` GET /comments/1 GET /comments/2 ``` If you set coalesceFindRequests to `true` it will instead trigger the following request: ``` GET /comments?filter[id]=1,2 ``` Setting coalesceFindRequests to `true` also works for `store.find` requests and `belongsTo` relationships accessed within the same runloop. If you set `coalesceFindRequests: true` ```javascript store.findRecord('comment', 1); store.findRecord('comment', 2); ``` will also send a request to: `GET /comments?filter[id]=1,2` Note: Requests coalescing rely on URL building strategy. So if you override `buildURL` in your app `groupRecordsForFindMany` more likely should be overridden as well in order for coalescing to work. ##### Returns `boolean` #### Set Signature ```ts set coalesceFindRequests(value: boolean): void; ``` Defined in: [warp-drive-packages/legacy/src/adapter/json-api.ts:254](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/json-api.ts#L254) By default the RESTAdapter will send each find request coming from a `store.find` or from accessing a relationship separately to the server. If your server supports passing ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests within a single runloop. For example, if you have an initial payload of: ```javascript { post: { id: 1, comments: [1, 2] } } ``` By default calling `post.comments` will trigger the following requests(assuming the comments haven't been loaded before): ``` GET /comments/1 GET /comments/2 ``` If you set coalesceFindRequests to `true` it will instead trigger the following request: ``` GET /comments?ids[]=1&ids[]=2 ``` Setting coalesceFindRequests to `true` also works for `store.find` requests and `belongsTo` relationships accessed within the same runloop. If you set `coalesceFindRequests: true` ```javascript store.findRecord('comment', 1); store.findRecord('comment', 2); ``` will also send a request to: `GET /comments?ids[]=1&ids[]=2` Note: Requests coalescing rely on URL building strategy. So if you override `buildURL` in your app `groupRecordsForFindMany` more likely should be overridden as well in order for coalescing to work. ##### Parameters ###### value `boolean` ##### Returns `void` #### Overrides [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`coalesceFindRequests`](../../rest/classes/RESTAdapter.md#coalescefindrequests) *** ### fastboot #### Get Signature ```ts get fastboot(): FastBoot; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:403](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L403) The FastBoot service instance, if running in a FastBoot environment. Lazily looked up on first access. ##### Returns `FastBoot` #### Set Signature ```ts set fastboot(value: FastBoot): void; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:416](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L416) Sets the FastBoot service instance to use. ##### Parameters ###### value `FastBoot` ##### Returns `void` #### Inherited from [`RESTAdapter`](../../rest/classes/RESTAdapter.md).[`fastboot`](../../rest/classes/RESTAdapter.md#fastboot) --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/json-api.md description: >- Legacy `JSONAPIAdapter`, which turns store requests into HTTP requests following JSON:API URL, verb and header conventions. --- ## Classes * [JSONAPIAdapter](classes/JSONAPIAdapter.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/rest/classes/RESTAdapter.md description: >- Legacy adapter that exchanges conventional REST-style JSON with an HTTP server, building URLs from model names and ids. --- # RESTAdapter Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:366](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L366) :::danger ⚠️ **This is LEGACY documentation** for a feature that is no longer encouraged to be used. If starting a new app or thinking of implementing a new adapter, consider writing a Handler instead to be used with the [RequestManager](../../../../core/classes/RequestManager.md) ::: The REST adapter allows your store to communicate with an HTTP server by transmitting JSON via XHR. This adapter is designed around the idea that the JSON exchanged with the server should be conventional. It builds URLs in a manner that follows the structure of most common REST-style web services. ## Success and failure The REST adapter will consider a success any response with a status code of the 2xx family ("Success"), as well as 304 ("Not Modified"). Any other status code will be considered a failure. On success, the request promise will be resolved with the full response payload. Failed responses with status code 422 ("Unprocessable Entity") will be considered "invalid". The response will be discarded, except for the `errors` key. The request promise will be rejected with a `InvalidError`. This error object will encapsulate the saved `errors` value. Any other status codes will be treated as an "adapter error". The request promise will be rejected, similarly to the "invalid" case, but with an instance of `AdapterError` instead. ## JSON Structure The REST adapter expects the JSON returned from your server to follow these conventions. ### Object Root The JSON payload should be an object that contains the record inside a root property. For example, in response to a `GET` request for `/posts/1`, the JSON should look like this: ```js { "posts": { "id": 1, "title": "I'm Running to Reform the W3C", "author": "Yehuda Katz" } } ``` Similarly, in response to a `GET` request for `/posts`, the JSON should look like this: ```js { "posts": [ { "id": 1, "title": "I'm Running to Reform the W3C", "author": "Yehuda Katz" }, { "id": 2, "title": "Rails is omakase", "author": "D2H" } ] } ``` Note that the object root can be pluralized for both a single-object response and an array response: the REST adapter is not strict on this. Further, if the HTTP server responds to a `GET` request to `/posts/1` (e.g. the response to a `findRecord` query) with more than one object in the array, WarpDrive will only display the object with the matching ID. ### Conventional Names Attribute names in your JSON payload should be the camelCased versions of the attributes in your Ember.js models. For example, if you have a `Person` model: ```js [app/models/person.js] import { Model, attr } from '@warp-drive/legacy/model'; export default Model.extend({ firstName: attr('string'), lastName: attr('string'), occupation: attr('string') }); ``` The JSON returned should look like this: ```js { "people": { "id": 5, "firstName": "Zaphod", "lastName": "Beeblebrox", "occupation": "President" } } ``` #### Relationships Relationships are usually represented by ids to the record in the relationship. The related records can then be sideloaded in the response under a key for the type. ```js { "posts": { "id": 5, "title": "I'm Running to Reform the W3C", "author": "Yehuda Katz", "comments": [1, 2] }, "comments": [{ "id": 1, "author": "User 1", "message": "First!", }, { "id": 2, "author": "User 2", "message": "Good Luck!", }] } ``` If the records in the relationship are not known when the response is serialized it's also possible to represent the relationship as a URL using the `links` key in the response. WarpDrive will fetch this URL to resolve the relationship when it is accessed for the first time. ```js { "posts": { "id": 5, "title": "I'm Running to Reform the W3C", "author": "Yehuda Katz", "links": { "comments": "/posts/5/comments" } } } ``` ### Errors If a response is considered a failure, the JSON payload is expected to include a top-level key `errors`, detailing any specific issues. For example: ```js { "errors": { "msg": "Something went wrong" } } ``` This adapter does not make any assumptions as to the format of the `errors` object. It will simply be passed along as is, wrapped in an instance of `InvalidError` or `AdapterError`. The serializer can interpret it afterwards. ## Customization ### Endpoint path customization Endpoint paths can be prefixed with a `namespace` by setting the namespace property on the adapter: ```js [app/adapters/application.js] import { RESTAdapter } from '@warp-drive/legacy/adapter/rest'; export default class ApplicationAdapter extends RESTAdapter { namespace = 'api/1'; } ``` Requests for the `Person` model would now target `/api/1/people/1`. ### Host customization An adapter can target other hosts by setting the `host` property. ```js [app/adapters/application.js] import { RESTAdapter } from '@warp-drive/legacy/adapter/rest'; export default class ApplicationAdapter extends RESTAdapter { host = 'https://api.example.com'; } ``` ### Headers customization Some APIs require HTTP headers, e.g. to provide an API key. Arbitrary headers can be set as key/value pairs on the `RESTAdapter`'s `headers` object and WarpDrive will send them along with each ajax request. ```js [app/adapters/application.js] import { RESTAdapter } from '@warp-drive/legacy/adapter/rest'; export default class ApplicationAdapter extends RESTAdapter { get headers() { return { 'API_KEY': 'secret key', 'ANOTHER_HEADER': 'Some header value' }; } } ``` ## Extends * `AdapterWithBuildURLMixin`.`MixtBuildURLMixin` ## Extended by * [`JSONAPIAdapter`](../../json-api/classes/JSONAPIAdapter.md) ## Constructors ### Constructor ```ts new RESTAdapter(owner?: Owner): RESTAdapter; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:139](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L139) #### Parameters ##### owner? `Owner` #### Returns `RESTAdapter` #### Inherited from ```ts AdapterWithBuildURLMixin.constructor ``` ## Methods ### buildQuery() ```ts buildQuery(snapshot: Snapshot | SnapshotRecordArray): QueryState; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:1259](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L1259) Used by `findAll` and `findRecord` to build the query's `data` hash supplied to the ajax method. #### Parameters ##### snapshot `Snapshot`<`unknown`> | `SnapshotRecordArray` #### Returns [`QueryState`](../types/QueryState.md) *** ### buildURL() ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: SnapshotRecordArray, requestType: "findAll" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "query", query: Record ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "queryRecord", query: Record ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string[], snapshot: Snapshot[], requestType: "findMany" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findHasMany" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findBelongsTo" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string | null, snapshot: Snapshot, requestType: "createRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "updateRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "deleteRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot ): string; ``` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:44](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L44) Builds a URL for a given type and optional ID. By default, it pluralizes the type's name (for example, 'post' becomes 'posts' and 'person' becomes 'people'). To override the pluralization see [pathForType](../../types/BuildURLMixin.md#pathfortype). If an ID is specified, it adds the ID to the path generated for the type, separated by a `/`. This overload builds the URL for a `store.findRecord(type, id)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"findRecord"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: SnapshotRecordArray, requestType: "findAll" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:56](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L56) Builds the URL for a `store.findAll(type)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `null` ###### snapshot `SnapshotRecordArray` ###### requestType `"findAll"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "query", query: Record ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:68](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L68) Builds the URL for a `store.query(type, query)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `null` ###### snapshot `null` ###### requestType `"query"` ###### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "queryRecord", query: Record ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:81](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L81) Builds the URL for a `store.queryRecord(type, query)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `null` ###### snapshot `null` ###### requestType `"queryRecord"` ###### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string[], snapshot: Snapshot[], requestType: "findMany" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:97](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L97) Builds the URL for coalescing multiple `store.findRecord(type, id)` records into 1 request when the adapter's `coalesceFindRequests` property is `true`. The `id` and `snapshot` parameters will be arrays of ids and snapshots. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string`\[] ###### snapshot `Snapshot`<`unknown`>\[] ###### requestType `"findMany"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findHasMany" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:110](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L110) Builds the URL for fetching an async `hasMany` relationship when a URL is not provided by the server. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"findHasMany"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findBelongsTo" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:123](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L123) Builds the URL for fetching an async `belongsTo` relationship when a URL is not provided by the server. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"findBelongsTo"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string | null, snapshot: Snapshot, requestType: "createRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:136](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L136) Builds the URL for a `record.save()` call when the record was created locally using `store.createRecord()`. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` | `null` ###### snapshot `Snapshot` ###### requestType `"createRecord"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "updateRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:149](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L149) Builds the URL for a `record.save()` call when the record has been updated locally. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"updateRecord"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "deleteRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:162](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L162) Builds the URL for a `record.save()` call when the record has been deleted locally. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"deleteRecord"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:174](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L174) Builds a URL for a given type and ID without a specific request type. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ##### Returns `string` *** ### createRecord() ```ts createRecord( store: Store$1, type: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:818](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L818) Called by the store when a newly created record is saved via the `save` method on a model record instance. The `createRecord` method serializes the record and makes an Ajax (HTTP POST) request to a URL computed by `buildURL`. See `serialize` for information on how to customize the serialized form of a record. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Overrides ```ts AdapterWithBuildURLMixin.createRecord ``` *** ### deleteRecord() ```ts deleteRecord( store: Store$1, schema: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:855](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L855) Called by the store when a record is deleted. The `deleteRecord` method makes an Ajax (HTTP DELETE) request to a URL computed by `buildURL`. #### Parameters ##### store `Store$1` ##### schema `ModelSchema` ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Overrides ```ts AdapterWithBuildURLMixin.deleteRecord ``` *** ### findAll() ```ts findAll( store: Store$1, type: ModelSchema, neverUsed: null, snapshotRecordArray: SnapshotRecordArray ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:617](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L617) Called by the store in order to fetch a JSON array for all of the records for a given type. The `findAll` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a promise for the resulting payload. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### neverUsed `null` ##### snapshotRecordArray `SnapshotRecordArray` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Overrides ```ts AdapterWithBuildURLMixin.findAll ``` *** ### findBelongsTo() ```ts findBelongsTo( store: Store$1, snapshot: Snapshot, url: string, relationship: unknown ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:794](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L794) Called by the store in order to fetch the JSON for the unloaded record in a belongs-to relationship that was originally specified as a URL (inside of `links`). For example, if your original payload looks like this: ```js { "person": { "id": 1, "name": "Tom Dale", "links": { "group": "/people/1/group" } } } ``` This method will be called with the parent record and `/people/1/group`. The `findBelongsTo` method will make an Ajax (HTTP GET) request to the originally specified URL. The format of your `links` value will influence the final request URL via the `urlPrefix` method: * Links beginning with `//`, `http://`, `https://`, will be used as is, with no further manipulation. * Links beginning with a single `/` will have the current adapter's `host` value prepended to it. * Links with no beginning `/` will have a parentURL prepended to it, via the current adapter's `buildURL`. #### Parameters ##### store `Store$1` ##### snapshot `Snapshot` ##### url `string` ##### relationship `unknown` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> *** ### findHasMany() ```ts findHasMany( store: Store$1, snapshot: Snapshot, url: string, relationship: Record ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:745](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L745) Called by the store in order to fetch a JSON array for the unloaded records in a has-many relationship that were originally specified as a URL (inside of `links`). For example, if your original payload looks like this: ```js { "post": { "id": 1, "title": "Rails is omakase", "links": { "comments": "/posts/1/comments" } } } ``` This method will be called with the parent record and `/posts/1/comments`. The `findHasMany` method will make an Ajax (HTTP GET) request to the originally specified URL. The format of your `links` value will influence the final request URL via the `urlPrefix` method: * Links beginning with `//`, `http://`, `https://`, will be used as is, with no further manipulation. * Links beginning with a single `/` will have the current adapter's `host` value prepended to it. * Links with no beginning `/` will have a parentURL prepended to it, via the current adapter's `buildURL`. #### Parameters ##### store `Store$1` ##### snapshot `Snapshot` ##### url `string` ##### relationship [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> *** ### findMany() ```ts findMany( store: Store$1, type: ModelSchema, ids: string[], snapshots: Snapshot[] ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:709](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L709) Called by the store in order to fetch several records together if `coalesceFindRequests` is true For example, if the original payload looks like: ```js { "id": 1, "title": "Rails is omakase", "comments": [ 1, 2, 3 ] } ``` The IDs will be passed as a URL-encoded Array of IDs, in this form: ``` ids[]=1&ids[]=2&ids[]=3 ``` Many servers, such as Rails and PHP, will automatically convert this URL-encoded array into an Array for you on the server-side. If you want to encode the IDs, differently, just override this (one-line) method. The `findMany` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a promise for the resulting payload. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### ids `string`\[] ##### snapshots `Snapshot`<`unknown`>\[] #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> *** ### findRecord() ```ts findRecord( store: Store$1, type: ModelSchema, id: string, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:601](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L601) Called by the store in order to fetch the JSON for a given type and ID. The `findRecord` method makes an Ajax request to a URL computed by `buildURL`, and returns a promise for the resulting payload. This method performs an HTTP `GET` request with the id provided as part of the query string. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### id `string` ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Overrides ```ts AdapterWithBuildURLMixin.findRecord ``` *** ### groupRecordsForFindMany() ```ts groupRecordsForFindMany(store: Store$1, snapshots: Snapshot[]): Snapshot[][]; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:922](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L922) Organize records into groups, each of which is to be passed to separate calls to `findMany`. This implementation groups together records that have the same base URL but differing ids. For example `/comments/1` and `/comments/2` will be grouped together because we know findMany can coalesce them together as `/comments?ids[]=1&ids[]=2` It also supports urls where ids are passed as a query param, such as `/comments?id=1` but not those where there is more than 1 query param such as `/comments?id=2&name=David` Currently only the query param of `id` is supported. If you need to support others, please override this or the `_stripIDFromURL` method. It does not group records that have differing base urls, such as for example: `/posts/1/comments/2` and `/posts/2/comments/3` #### Parameters ##### store `Store$1` ##### snapshots `Snapshot`<`unknown`>\[] #### Returns `Snapshot`<`unknown`>\[]\[] an array of arrays of records, each of which is to be loaded separately by `findMany`. #### Overrides ```ts AdapterWithBuildURLMixin.groupRecordsForFindMany ``` *** ### handleResponse() ```ts handleResponse( status: number, headers: Record, payload: Payload, requestData: RequestData ): | AdapterRequestErrorConstructor | Payload; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:970](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L970) Takes an ajax response, and returns the json payload or an error. By default this hook just returns the json payload passed to it. You might want to override it in two cases: 1. Your API might return useful results in the response headers. Response headers are passed in as the second argument. 2. Your API might return errors as successful responses with status code 200 and an Errors text or object. You can return a `InvalidError` or a `AdapterError` (or a sub class) from this hook and it will automatically reject the promise and put your record into the invalid or error state. Returning a `InvalidError` from this method will cause the record to transition into the `invalid` state and make the `errors` object available on the record. When returning an `InvalidError` the store will attempt to normalize the error data returned from the server using the serializer's `extractErrors` method. #### Parameters ##### status `number` ##### headers [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `string`> ##### payload `Payload` ##### requestData [`RequestData`](../types/RequestData.md) #### Returns | [`AdapterRequestErrorConstructor`](../../error/types/AdapterRequestErrorConstructor.md)<[`AdapterError`](../../error/types/AdapterError.md)> | `Payload` *** ### isInvalid() ```ts isInvalid( status: number, _headers: Record, _payload: Payload ): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:1024](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L1024) Default `handleResponse` implementation uses this hook to decide if the response is an invalid error. #### Parameters ##### status `number` ##### \_headers [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### \_payload `Payload` #### Returns `boolean` *** ### isSuccess() ```ts isSuccess( status: number, _headers: Record, _payload: Payload ): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:1013](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L1013) Default `handleResponse` implementation uses this hook to decide if the response is a success. #### Parameters ##### status `number` ##### \_headers [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### \_payload `Payload` #### Returns `boolean` *** ### pathForType() ```ts pathForType(this: MixtBuildURLMixin, modelName: string): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:258](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L258) Determines the pathname for a given type. By default, it pluralizes the type's name (for example, 'post' becomes 'posts' and 'person' becomes 'people'). #### Parameters ##### this `MixtBuildURLMixin` ##### modelName `string` #### Returns `string` *** ### query() ```ts query( store: Store$1, type: ModelSchema, query: Record ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:642](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L642) Called by the store in order to fetch a JSON array for the records that match a particular query. The `query` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a promise for the resulting payload. The `query` argument is a simple JavaScript object that will be passed directly to the server as parameters. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Overrides ```ts AdapterWithBuildURLMixin.query ``` *** ### queryRecord() ```ts queryRecord( store: Store$1, type: ModelSchema, query: Record, adapterOptions: Record ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:666](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L666) Called by the store in order to fetch a JSON object for the record that matches a particular query. The `queryRecord` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a promise for the resulting payload. The `query` argument is a simple JavaScript object that will be passed directly to the server as parameters. #### Parameters ##### store `Store$1` ##### type `ModelSchema` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### adapterOptions [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Overrides ```ts AdapterWithBuildURLMixin.queryRecord ``` *** ### serialize() ```ts serialize(snapshot: Snapshot, options: SerializerOptions): Record; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:500](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L500) Proxies to the serializer's `serialize` method. Example ```js [app/adapters/application.js] import { Adapter } from '@warp-drive/legacy/adapter'; export default class ApplicationAdapter extends Adapter { createRecord(store, type, snapshot) { let data = this.serialize(snapshot, { includeId: true }); let url = `/${type.modelName}`; // ... } } ``` #### Parameters ##### snapshot `Snapshot` ##### options [`SerializerOptions`](../../../compat/types/SerializerOptions.md) #### Returns [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Inherited from ```ts AdapterWithBuildURLMixin.serialize ``` *** ### shouldBackgroundReloadAll() ```ts shouldBackgroundReloadAll(store: Store$1, snapshotRecordArray: SnapshotRecordArray): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:907](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L907) This method is used by the store to determine if the store should reload a record array after the `store.findAll` method resolves with a cached record array. This method is *only* checked by the store when the store is returning a cached record array. If this method returns `true` the store will re-fetch all records from the adapter. For example, if you do not want to fetch complex data over a mobile connection, or if the network is down, you can implement `shouldBackgroundReloadAll` as follows: ```javascript shouldBackgroundReloadAll(store, snapshotArray) { let { downlink, effectiveType } = navigator.connection; return downlink > 0 && effectiveType === '4g'; } ``` By default this method returns `true`, indicating that a background reload should always be triggered. #### Parameters ##### store `Store$1` ##### snapshotRecordArray `SnapshotRecordArray` #### Returns `boolean` #### Inherited from ```ts AdapterWithBuildURLMixin.shouldBackgroundReloadAll ``` *** ### shouldBackgroundReloadRecord() ```ts shouldBackgroundReloadRecord(store: Store$1, snapshot: Snapshot): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:871](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L871) This method is used by the store to determine if the store should reload a record after the `store.findRecord` method resolves a cached record. This method is *only* checked by the store when the store is returning a cached record. If this method returns `true` the store will re-fetch a record from the adapter. For example, if you do not want to fetch complex data over a mobile connection, or if the network is down, you can implement `shouldBackgroundReloadRecord` as follows: ```javascript shouldBackgroundReloadRecord(store, snapshot) { let { downlink, effectiveType } = navigator.connection; return downlink > 0 && effectiveType === '4g'; } ``` By default, this hook returns `true` so the data for the record is updated in the background. #### Parameters ##### store `Store$1` ##### snapshot `Snapshot` #### Returns `boolean` #### Inherited from ```ts AdapterWithBuildURLMixin.shouldBackgroundReloadRecord ``` *** ### shouldReloadAll() ```ts shouldReloadAll(store: Store$1, snapshotRecordArray: SnapshotRecordArray): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:835](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L835) This method is used by the store to determine if the store should reload all records from the adapter when records are requested by `store.findAll`. If this method returns `true`, the store will re-fetch all records from the adapter. If this method returns `false`, the store will resolve immediately using the cached records. For example, if you are building an events ticketing system, in which users can only reserve tickets for 20 minutes at a time, and want to ensure that in each route you have data that is no more than 20 minutes old you could write: ```javascript shouldReloadAll(store, snapshotArray) { let snapshots = snapshotArray.snapshots(); return snapshots.any((ticketSnapshot) => { let lastAccessedAt = ticketSnapshot.attr('lastAccessedAt'); let timeDiff = moment().diff(lastAccessedAt, 'minutes'); if (timeDiff > 20) { return true; } else { return false; } }); } ``` This method would ensure that whenever you do `store.findAll('ticket')` you will always get a list of tickets that are no more than 20 minutes old. In case a cached version is more than 20 minutes old, `findAll` will not resolve until you fetched the latest versions. By default, this method returns `true` if the passed `snapshotRecordArray` is empty (meaning that there are no records locally available yet), otherwise, it returns `false`. Note that, with default settings, `shouldBackgroundReloadAll` will always re-fetch all the records in the background even if `shouldReloadAll` returns `false`. You can override `shouldBackgroundReloadAll` if this does not suit your use case. #### Parameters ##### store `Store$1` ##### snapshotRecordArray `SnapshotRecordArray` #### Returns `boolean` #### Inherited from ```ts AdapterWithBuildURLMixin.shouldReloadAll ``` *** ### shouldReloadRecord() ```ts shouldReloadRecord(store: Store$1, snapshot: Snapshot): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:780](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L780) This method is used by the store to determine if the store should reload a record from the adapter when a record is requested by `store.findRecord`. If this method returns `true`, the store will re-fetch a record from the adapter. If this method returns `false`, the store will resolve immediately using the cached record. For example, if you are building an events ticketing system, in which users can only reserve tickets for 20 minutes at a time, and want to ensure that in each route you have data that is no more than 20 minutes old you could write: ```javascript shouldReloadRecord(store, ticketSnapshot) { let lastAccessedAt = ticketSnapshot.attr('lastAccessedAt'); let timeDiff = moment().diff(lastAccessedAt, 'minutes'); if (timeDiff > 20) { return true; } else { return false; } } ``` This method would ensure that whenever you do `store.findRecord('ticket', id)` you will always get a ticket that is no more than 20 minutes old. In case the cached version is more than 20 minutes old, `findRecord` will not resolve until you fetched the latest version. By default this hook returns `false`, as most UIs should not block user interactions while waiting on data update. Note that, with default settings, `shouldBackgroundReloadRecord` will always re-fetch the records in the background even if `shouldReloadRecord` returns `false`. You can override `shouldBackgroundReloadRecord` if this does not suit your use case. #### Parameters ##### store `Store$1` ##### snapshot `Snapshot` #### Returns `boolean` #### Inherited from ```ts AdapterWithBuildURLMixin.shouldReloadRecord ``` *** ### sortQueryParams() ```ts sortQueryParams(obj: Record): Record; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:460](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L460) By default, the RESTAdapter will send the query params sorted alphabetically to the server. For example: ```js store.query('posts', { sort: 'price', category: 'pets' }); ``` will generate a requests like this `/posts?category=pets&sort=price`, even if the parameters were specified in a different order. That way the generated URL will be deterministic and that simplifies caching mechanisms in the backend. Setting `sortQueryParams` to a falsey value will respect the original order. In case you want to sort the query parameters with a different criteria, set `sortQueryParams` to your custom sort function. ```js [app/adapters/application.js] import { RESTAdapter } from '@warp-drive/legacy/adapter/rest'; export default class ApplicationAdapter extends RESTAdapter { sortQueryParams(params) { let sortedKeys = Object.keys(params).sort().reverse(); let len = sortedKeys.length, newParams = {}; for (let i = 0; i < len; i++) { newParams[sortedKeys[i]] = params[sortedKeys[i]]; } return newParams; } } ``` #### Parameters ##### obj [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> *** ### updateRecord() ```ts updateRecord( store: Store$1, schema: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:838](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L838) Called by the store when an existing record is saved via the `save` method on a model record instance. The `updateRecord` method serializes the record and makes an Ajax (HTTP PUT) request to a URL computed by `buildURL`. See `serialize` for information on how to customize the serialized form of a record. #### Parameters ##### store `Store$1` ##### schema `ModelSchema` ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](../../../compat/types/AdapterPayload.md)> #### Overrides ```ts AdapterWithBuildURLMixin.updateRecord ``` *** ### urlForCreateRecord() ```ts urlForCreateRecord( this: MixtBuildURLMixin, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:231](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L231) Builds a URL for a `record.save()` call when the record was created locally using `store.createRecord()`. #### Parameters ##### this `MixtBuildURLMixin` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` *** ### urlForDeleteRecord() ```ts urlForDeleteRecord( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:245](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L245) Builds a URL for a `record.save()` call when the record has been deleted locally. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` *** ### urlForFindAll() ```ts urlForFindAll( this: MixtBuildURLMixin, modelName: string, snapshots: SnapshotRecordArray ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:190](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L190) Builds a URL for a `store.findAll(type)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### modelName `string` ##### snapshots `SnapshotRecordArray` #### Returns `string` *** ### urlForFindBelongsTo() ```ts urlForFindBelongsTo( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:224](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L224) Builds a URL for fetching an async `belongsTo` relationship when a URL is not provided by the server. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` *** ### urlForFindHasMany() ```ts urlForFindHasMany( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:217](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L217) Builds a URL for fetching an async `hasMany` relationship when a URL is not provided by the server. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` *** ### urlForFindMany() ```ts urlForFindMany( this: MixtBuildURLMixin, ids: string[], modelName: string, snapshots: Snapshot[] ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:210](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L210) Builds a URL for coalescing multiple `store.findRecord(type, id)` records into 1 request when the adapter's `coalesceFindRequests` property is `true`. #### Parameters ##### this `MixtBuildURLMixin` ##### ids `string`\[] ##### modelName `string` ##### snapshots `Snapshot`<`unknown`>\[] #### Returns `string` *** ### urlForFindRecord() ```ts urlForFindRecord( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:184](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L184) Builds a URL for a `store.findRecord(type, id)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` *** ### urlForQuery() ```ts urlForQuery( this: MixtBuildURLMixin, query: Record, modelName: string ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:202](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L202) Builds a URL for a `store.query(type, query)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### modelName `string` #### Returns `string` *** ### urlForQueryRecord() ```ts urlForQueryRecord( this: MixtBuildURLMixin, query: Record, modelName: string ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:196](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L196) Builds a URL for a `store.queryRecord(type, query)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### modelName `string` #### Returns `string` *** ### urlForUpdateRecord() ```ts urlForUpdateRecord( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:238](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L238) Builds a URL for a `record.save()` call when the record has been updated locally. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` ## Properties ### \_defaultContentType ```ts _defaultContentType: string = 'application/json; charset=utf-8'; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:396](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L396) The `Content-Type` header used when serializing request bodies that don't otherwise specify one. *** ### headers ```ts headers: | Record | undefined; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:587](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L587) Some APIs require HTTP headers, e.g. to provide an API key. Arbitrary headers can be set as key/value pairs on the `RESTAdapter`'s `headers` object and WarpDrive will send them along with each ajax request.. ```js [app/adapters/application.js] import { RESTAdapter } from '@warp-drive/legacy/adapter/rest'; export default class ApplicationAdapter extends RESTAdapter { get headers() { return { 'API_KEY': 'secret key', 'ANOTHER_HEADER': 'Some header value' }; } } ``` *** ### host ```ts host: string | null; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:378](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L378) See "Host customization" above. *** ### maxURLLength ```ts maxURLLength: number = 2048; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:900](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L900) The maximum URL length to allow when coalescing `findRecord` requests into a single `findMany` request via [groupRecordsForFindMany](#grouprecordsforfindmany). Requests that would exceed this length are split into multiple groups. See http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers *** ### namespace ```ts namespace: string | null; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:382](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L382) See "Namespace customization" above. *** ### store ```ts store: Store$1; ``` Defined in: [warp-drive-packages/legacy/src/adapter.ts:297](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter.ts#L297) The Store service instance that owns this Adapter. #### Inherited from ```ts AdapterWithBuildURLMixin.store ``` *** ### useFetch ```ts useFetch: boolean = true; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:390](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L390) This property allows ajax to still be used instead when `false`. #### Default ```ts true @public ``` ### coalesceFindRequests #### Get Signature ```ts get coalesceFindRequests(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:521](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L521) By default the RESTAdapter will send each find request coming from a `store.find` or from accessing a relationship separately to the server. If your server supports passing ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests within a single runloop. For example, if you have an initial payload of: ```javascript { post: { id: 1, comments: [1, 2] } } ``` By default calling `post.comments` will trigger the following requests(assuming the comments haven't been loaded before): ``` GET /comments/1 GET /comments/2 ``` If you set coalesceFindRequests to `true` it will instead trigger the following request: ``` GET /comments?ids[]=1&ids[]=2 ``` Setting coalesceFindRequests to `true` also works for `store.find` requests and `belongsTo` relationships accessed within the same runloop. If you set `coalesceFindRequests: true` ```javascript store.findRecord('comment', 1); store.findRecord('comment', 2); ``` will also send a request to: `GET /comments?ids[]=1&ids[]=2` Note: Requests coalescing rely on URL building strategy. So if you override `buildURL` in your app `groupRecordsForFindMany` more likely should be overridden as well in order for coalescing to work. ##### Returns `boolean` #### Set Signature ```ts set coalesceFindRequests(value: boolean): void; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:529](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L529) By default the store will try to coalesce all `findRecord` calls within the same runloop into as few requests as possible by calling groupRecordsForFindMany and passing it into a findMany call. You can opt out of this behaviour by either not implementing the findMany hook or by setting coalesceFindRequests to false. ##### Parameters ###### value `boolean` ##### Returns `void` #### Overrides ```ts AdapterWithBuildURLMixin.coalesceFindRequests ``` *** ### fastboot #### Get Signature ```ts get fastboot(): FastBoot; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:403](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L403) The FastBoot service instance, if running in a FastBoot environment. Lazily looked up on first access. ##### Returns `FastBoot` #### Set Signature ```ts set fastboot(value: FastBoot): void; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:416](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L416) Sets the FastBoot service instance to use. ##### Parameters ###### value `FastBoot` ##### Returns `void` --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/rest.md description: >- Legacy `RESTAdapter`, which exchanges conventional REST-style JSON with an HTTP server, plus the request types it builds. --- ## Classes * [RESTAdapter](classes/RESTAdapter.md) ## Types * [FetchRequestInit](types/FetchRequestInit.md) * [JQueryRequestInit](types/JQueryRequestInit.md) * [QueryState](types/QueryState.md) * [RequestData](types/RequestData.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/rest/types/FetchRequestInit.md description: >- `fetch` options plus `url`, `method`, and `type` that the legacy `RESTAdapter` builds for a request sent with the native `fetch` API. --- # FetchRequestInit ```ts interface FetchRequestInit extends RequestInit { method: HTTPMethod; type: HTTPMethod; url: string; } ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:75](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L75) The options passed to the native `fetch` API by RESTAdapter.\_fetchRequest | \_fetchRequest. ## Extends * `RequestInit` ## Properties ### method ```ts method: HTTPMethod; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:83](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L83) the HTTP method to use #### Overrides ```ts RequestInit.method ``` *** ### type ```ts type: HTTPMethod; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:87](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L87) the HTTP method to use, duplicated for jQuery/fetch option compatibility *** ### url ```ts url: string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:79](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L79) the url to request --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/rest/types/JQueryRequestInit.md description: >- jQuery `$.ajax` settings plus `url`, `method`, and `type` that the legacy `RESTAdapter` builds when it sends a request through jQuery. --- # JQueryRequestInit ```ts interface JQueryRequestInit extends JQueryAjaxSettings { method: HTTPMethod; type: HTTPMethod; url: string; } ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:96](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L96) The options passed to jQuery's `$.ajax` by RESTAdapter.\_ajaxRequest | \_ajaxRequest. ## Extends * `JQueryAjaxSettings` ## Properties ### method ```ts method: HTTPMethod; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:104](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L104) the HTTP method to use #### Overrides ```ts JQueryAjaxSettings.method ``` *** ### type ```ts type: HTTPMethod; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:108](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L108) the HTTP method to use, duplicated for jQuery/fetch option compatibility #### Overrides ```ts JQueryAjaxSettings.type ``` *** ### url ```ts url: string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:100](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L100) the url to request #### Overrides ```ts JQueryAjaxSettings.url ``` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/rest/types/QueryState.md description: >- Query params the legacy `RESTAdapter.buildQuery` adds to `findRecord` and `findAll` URLs, such as the `include` paths to sideload. --- # QueryState ```ts type QueryState = { include?: unknown; since?: unknown; }; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:58](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L58) The query params built by [buildQuery](../classes/RESTAdapter.md#buildquery) for a `findAll`/`findRecord` request. ## Properties ### include? ```ts optional include?: unknown; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:62](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L62) the relationship paths to sideload *** ### since? ```ts optional since?: unknown; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:66](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L66) a value used to request only records updated since the given value --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/rest/types/RequestData.md description: >- The url and HTTP method of a legacy `RESTAdapter` request, used to build error messages when that request fails. --- # RequestData ```ts type RequestData = { [key: string]: unknown; method: HTTPMethod; url: string; }; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:118](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L118) A minimal description of an in-flight request, used for building error messages when a request fails. ## Indexable ```ts [key: string]: unknown ``` ## Properties ### method ```ts method: HTTPMethod; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:126](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L126) the HTTP method that was used *** ### url ```ts url: string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/rest.ts:122](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/rest.ts#L122) the url that was requested --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/types/BuildURLMixin.md description: >- Legacy adapter mixin providing `buildURL` and the `urlFor*` hooks that turn a model name, id, snapshot, and request type into a request URL. --- # BuildURLMixin ```ts interface BuildURLMixin { buildURL(this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findRecord"): string; buildURL(this: MixtBuildURLMixin, modelName: string, id: null, snapshot: SnapshotRecordArray, requestType: "findAll"): string; buildURL(this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "query", query: Record): string; buildURL(this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "queryRecord", query: Record): string; buildURL(this: MixtBuildURLMixin, modelName: string, id: string[], snapshot: Snapshot[], requestType: "findMany"): string; buildURL(this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findHasMany"): string; buildURL(this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findBelongsTo"): string; buildURL(this: MixtBuildURLMixin, modelName: string, id: string | null, snapshot: Snapshot, requestType: "createRecord"): string; buildURL(this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "updateRecord"): string; buildURL(this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "deleteRecord"): string; buildURL(this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot): string; pathForType(this: MixtBuildURLMixin, modelName: string): string; urlForCreateRecord(this: MixtBuildURLMixin, modelName: string, snapshot: Snapshot): string; urlForDeleteRecord(this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot): string; urlForFindAll(this: MixtBuildURLMixin, modelName: string, snapshots: SnapshotRecordArray): string; urlForFindBelongsTo(this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot): string; urlForFindHasMany(this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot): string; urlForFindMany(this: MixtBuildURLMixin, ids: string[], modelName: string, snapshots: Snapshot[]): string; urlForFindRecord(this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot): string; urlForQuery(this: MixtBuildURLMixin, query: Record, modelName: string): string; urlForQueryRecord(this: MixtBuildURLMixin, query: Record, modelName: string): string; urlForUpdateRecord(this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot): string; } ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:29](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L29) The methods provided by the `BuildURLMixin` mixin (see the exported `BuildURLMixin` Mixin below). See also MixtBuildURLMixin, the interface used to type `this` within these methods. ## Methods ### buildURL() ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: SnapshotRecordArray, requestType: "findAll" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "query", query: Record ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "queryRecord", query: Record ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string[], snapshot: Snapshot[], requestType: "findMany" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findHasMany" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findBelongsTo" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string | null, snapshot: Snapshot, requestType: "createRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "updateRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "deleteRecord" ): string; buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot ): string; ``` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:44](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L44) Builds a URL for a given type and optional ID. By default, it pluralizes the type's name (for example, 'post' becomes 'posts' and 'person' becomes 'people'). To override the pluralization see [pathForType](#pathfortype). If an ID is specified, it adds the ID to the path generated for the type, separated by a `/`. This overload builds the URL for a `store.findRecord(type, id)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"findRecord"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: SnapshotRecordArray, requestType: "findAll" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:56](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L56) Builds the URL for a `store.findAll(type)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `null` ###### snapshot `SnapshotRecordArray` ###### requestType `"findAll"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "query", query: Record ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:68](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L68) Builds the URL for a `store.query(type, query)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `null` ###### snapshot `null` ###### requestType `"query"` ###### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: null, snapshot: null, requestType: "queryRecord", query: Record ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:81](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L81) Builds the URL for a `store.queryRecord(type, query)` call. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `null` ###### snapshot `null` ###### requestType `"queryRecord"` ###### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string[], snapshot: Snapshot[], requestType: "findMany" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:97](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L97) Builds the URL for coalescing multiple `store.findRecord(type, id)` records into 1 request when the adapter's `coalesceFindRequests` property is `true`. The `id` and `snapshot` parameters will be arrays of ids and snapshots. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string`\[] ###### snapshot `Snapshot`<`unknown`>\[] ###### requestType `"findMany"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findHasMany" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:110](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L110) Builds the URL for fetching an async `hasMany` relationship when a URL is not provided by the server. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"findHasMany"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "findBelongsTo" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:123](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L123) Builds the URL for fetching an async `belongsTo` relationship when a URL is not provided by the server. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"findBelongsTo"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string | null, snapshot: Snapshot, requestType: "createRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:136](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L136) Builds the URL for a `record.save()` call when the record was created locally using `store.createRecord()`. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` | `null` ###### snapshot `Snapshot` ###### requestType `"createRecord"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "updateRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:149](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L149) Builds the URL for a `record.save()` call when the record has been updated locally. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"updateRecord"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot, requestType: "deleteRecord" ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:162](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L162) Builds the URL for a `record.save()` call when the record has been deleted locally. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ###### requestType `"deleteRecord"` ##### Returns `string` #### Call Signature ```ts buildURL( this: MixtBuildURLMixin, modelName: string, id: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:174](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L174) Builds a URL for a given type and ID without a specific request type. ##### Parameters ###### this `MixtBuildURLMixin` ###### modelName `string` ###### id `string` ###### snapshot `Snapshot` ##### Returns `string` *** ### pathForType() ```ts pathForType(this: MixtBuildURLMixin, modelName: string): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:258](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L258) Determines the pathname for a given type. By default, it pluralizes the type's name (for example, 'post' becomes 'posts' and 'person' becomes 'people'). #### Parameters ##### this `MixtBuildURLMixin` ##### modelName `string` #### Returns `string` *** ### urlForCreateRecord() ```ts urlForCreateRecord( this: MixtBuildURLMixin, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:231](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L231) Builds a URL for a `record.save()` call when the record was created locally using `store.createRecord()`. #### Parameters ##### this `MixtBuildURLMixin` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` *** ### urlForDeleteRecord() ```ts urlForDeleteRecord( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:245](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L245) Builds a URL for a `record.save()` call when the record has been deleted locally. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` *** ### urlForFindAll() ```ts urlForFindAll( this: MixtBuildURLMixin, modelName: string, snapshots: SnapshotRecordArray ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:190](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L190) Builds a URL for a `store.findAll(type)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### modelName `string` ##### snapshots `SnapshotRecordArray` #### Returns `string` *** ### urlForFindBelongsTo() ```ts urlForFindBelongsTo( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:224](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L224) Builds a URL for fetching an async `belongsTo` relationship when a URL is not provided by the server. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` *** ### urlForFindHasMany() ```ts urlForFindHasMany( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:217](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L217) Builds a URL for fetching an async `hasMany` relationship when a URL is not provided by the server. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` *** ### urlForFindMany() ```ts urlForFindMany( this: MixtBuildURLMixin, ids: string[], modelName: string, snapshots: Snapshot[] ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:210](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L210) Builds a URL for coalescing multiple `store.findRecord(type, id)` records into 1 request when the adapter's `coalesceFindRequests` property is `true`. #### Parameters ##### this `MixtBuildURLMixin` ##### ids `string`\[] ##### modelName `string` ##### snapshots `Snapshot`<`unknown`>\[] #### Returns `string` *** ### urlForFindRecord() ```ts urlForFindRecord( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:184](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L184) Builds a URL for a `store.findRecord(type, id)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` *** ### urlForQuery() ```ts urlForQuery( this: MixtBuildURLMixin, query: Record, modelName: string ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:202](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L202) Builds a URL for a `store.query(type, query)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### modelName `string` #### Returns `string` *** ### urlForQueryRecord() ```ts urlForQueryRecord( this: MixtBuildURLMixin, query: Record, modelName: string ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:196](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L196) Builds a URL for a `store.queryRecord(type, query)` call. #### Parameters ##### this `MixtBuildURLMixin` ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### modelName `string` #### Returns `string` *** ### urlForUpdateRecord() ```ts urlForUpdateRecord( this: MixtBuildURLMixin, id: string, modelName: string, snapshot: Snapshot ): string; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:238](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L238) Builds a URL for a `record.save()` call when the record has been updated locally. #### Parameters ##### this `MixtBuildURLMixin` ##### id `string` ##### modelName `string` ##### snapshot `Snapshot` #### Returns `string` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/adapter/variables/BuildURLMixin.md description: >- Legacy `Mixin` that adds `buildURL` and the `urlFor*` hooks to an adapter so it can turn a model name, id, snapshot, and request type into a request URL. --- # BuildURLMixin ```ts BuildURLMixin: Mixin; ``` Defined in: [warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts:29](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/adapter/-private/build-url-mixin.ts#L29) The `Mixin` implementation of BuildURLMixin, ready to be applied to an `EmberObject` subclass such as an `Adapter`. --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/classes/ConfiguredStore.md --- # ConfiguredStore\ Defined in: [warp-drive-packages/legacy/src/index.ts:170](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L170) ## Extends * `Store$1` ## Type Parameters ### T `T` *extends* { `cache`: `Cache`; } ## Indexable ```ts [key: string]: any ``` ## Methods ### createCache() ```ts createCache(capabilities: CacheCapabilitiesManager$1): T["cache"]; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:179](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L179) Instantiation hook allowing applications or addons to configure the store to utilize a custom Cache implementation. This hook should not be called directly by consuming applications or libraries. Use `Store.cache` to access the Cache instance. #### Parameters ##### capabilities `CacheCapabilitiesManager$1` #### Returns `T`\[`"cache"`] #### Overrides ```ts Store.createCache ``` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/builders/functions/findAll.md description: >- Deprecated legacy builder for a `store.request` config that behaves like `store.findAll`, easing migration off adapters and serializers. --- # ~~findAll()~~ ```ts function findAll(type: TypeFromInstance, options?: BaseFinderOptions): FindAllRequestInput, T[]>; function findAll(type: string, options?: BaseFinderOptions): FindAllRequestInput; ``` ## Call Signature ```ts function findAll(type: TypeFromInstance, options?: BaseFinderOptions): FindAllRequestInput, T[]>; ``` Defined in: [warp-drive-packages/legacy/src/compat/builders/find-all.ts:38](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/builders/find-all.ts#L38) This function builds a request config to perform a `findAll` request for the given type. When passed to `store.request`, this config will result in the same behavior as a `store.findAll` request. Additionally, it takes the same options as `store.findAll`. All `@warp-drive/legacy/compat` builders exist to enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of WarpDrive. ### Type Parameters #### T `T` *extends* [`TypedRecordInstance`](../../../../core/types/record/types/TypedRecordInstance.md) ### Parameters #### type [`TypeFromInstance`](../../../../core/types/record/types/TypeFromInstance.md)<`T`> the name of the resource #### options? `BaseFinderOptions` optional, may include `adapterOptions` hash which will be passed to adapter.findAll ### Returns `FindAllRequestInput`<[`TypeFromInstance`](../../../../core/types/record/types/TypeFromInstance.md)<`T`>, `T`\[]> request config ### Deprecated ## Call Signature ```ts function findAll(type: string, options?: BaseFinderOptions): FindAllRequestInput; ``` Defined in: [warp-drive-packages/legacy/src/compat/builders/find-all.ts:42](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/builders/find-all.ts#L42) This function builds a request config to perform a `findAll` request for the given type. When passed to `store.request`, this config will result in the same behavior as a `store.findAll` request. Additionally, it takes the same options as `store.findAll`. All `@warp-drive/legacy/compat` builders exist to enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of WarpDrive. ### Parameters #### type `string` the name of the resource #### options? `BaseFinderOptions` optional, may include `adapterOptions` hash which will be passed to adapter.findAll ### Returns `FindAllRequestInput` request config ### Deprecated --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/builders/functions/findRecord.md description: >- Deprecated legacy builder for a `store.request` config that behaves like `store.findRecord`, taking a type and id or a resource identifier. --- # ~~findRecord()~~ ```ts function findRecord( type: TypeFromInstance, id: string, options?: FindRecordBuilderOptions ): FindRecordRequestInput, T>; function findRecord( type: string, id: string, options?: FindRecordBuilderOptions ): FindRecordRequestInput; function findRecord(resource: ResourceIdentifierObject>, options?: FindRecordBuilderOptions): FindRecordRequestInput, T>; function findRecord(resource: ResourceIdentifierObject, options?: FindRecordBuilderOptions): FindRecordRequestInput; ``` ## Call Signature ```ts function findRecord( type: TypeFromInstance, id: string, options?: FindRecordBuilderOptions ): FindRecordRequestInput, T>; ``` Defined in: [warp-drive-packages/legacy/src/compat/builders/find-record.ts:59](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/builders/find-record.ts#L59) This function builds a request config to find the record for a given identifier or type and id combination. When passed to `store.request`, this config will result in the same behavior as a `store.findRecord` request. Additionally, it takes the same options as `store.findRecord`, with the exception of `preload` (which is unsupported). **Example 1** ```ts import { findRecord } from '@warp-drive/legacy/compat/builders'; const { content: post } = await store.request(findRecord('post', '1')); ``` **Example 2** `findRecord` can be called with a single identifier argument instead of the combination of `type` (modelName) and `id` as separate arguments. You may recognize this combo as the typical pairing from [JSON:API](https://jsonapi.org/format/#document-resource-object-identification) ```ts import { findRecord } from '@warp-drive/legacy/compat/builders'; const { content: post } = await store.request(findRecord({ type: 'post', id })); ``` All `@warp-drive/legacy/compat` builders exist to enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of Warp Drive. ### Type Parameters #### T `T` *extends* [`TypedRecordInstance`](../../../../core/types/record/types/TypedRecordInstance.md) ### Parameters #### type [`TypeFromInstance`](../../../../core/types/record/types/TypeFromInstance.md)<`T`> #### id `string` optional object with options for the request only if the first param is a ResourceIdentifier, else the string id of the record to be retrieved #### options? `FindRecordBuilderOptions` if the first param is a string this will be the optional options for the request. See examples for available options. ### Returns `FindRecordRequestInput`<[`TypeFromInstance`](../../../../core/types/record/types/TypeFromInstance.md)<`T`>, `T`> request config ### Deprecated ## Call Signature ```ts function findRecord( type: string, id: string, options?: FindRecordBuilderOptions ): FindRecordRequestInput; ``` Defined in: [warp-drive-packages/legacy/src/compat/builders/find-record.ts:64](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/builders/find-record.ts#L64) This function builds a request config to find the record for a given identifier or type and id combination. When passed to `store.request`, this config will result in the same behavior as a `store.findRecord` request. Additionally, it takes the same options as `store.findRecord`, with the exception of `preload` (which is unsupported). **Example 1** ```ts import { findRecord } from '@warp-drive/legacy/compat/builders'; const { content: post } = await store.request(findRecord('post', '1')); ``` **Example 2** `findRecord` can be called with a single identifier argument instead of the combination of `type` (modelName) and `id` as separate arguments. You may recognize this combo as the typical pairing from [JSON:API](https://jsonapi.org/format/#document-resource-object-identification) ```ts import { findRecord } from '@warp-drive/legacy/compat/builders'; const { content: post } = await store.request(findRecord({ type: 'post', id })); ``` All `@warp-drive/legacy/compat` builders exist to enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of Warp Drive. ### Parameters #### type `string` #### id `string` optional object with options for the request only if the first param is a ResourceIdentifier, else the string id of the record to be retrieved #### options? `FindRecordBuilderOptions` if the first param is a string this will be the optional options for the request. See examples for available options. ### Returns `FindRecordRequestInput` request config ### Deprecated ## Call Signature ```ts function findRecord(resource: ResourceIdentifierObject>, options?: FindRecordBuilderOptions): FindRecordRequestInput, T>; ``` Defined in: [warp-drive-packages/legacy/src/compat/builders/find-record.ts:65](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/builders/find-record.ts#L65) This function builds a request config to find the record for a given identifier or type and id combination. When passed to `store.request`, this config will result in the same behavior as a `store.findRecord` request. Additionally, it takes the same options as `store.findRecord`, with the exception of `preload` (which is unsupported). **Example 1** ```ts import { findRecord } from '@warp-drive/legacy/compat/builders'; const { content: post } = await store.request(findRecord('post', '1')); ``` **Example 2** `findRecord` can be called with a single identifier argument instead of the combination of `type` (modelName) and `id` as separate arguments. You may recognize this combo as the typical pairing from [JSON:API](https://jsonapi.org/format/#document-resource-object-identification) ```ts import { findRecord } from '@warp-drive/legacy/compat/builders'; const { content: post } = await store.request(findRecord({ type: 'post', id })); ``` All `@warp-drive/legacy/compat` builders exist to enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of Warp Drive. ### Type Parameters #### T `T` *extends* [`TypedRecordInstance`](../../../../core/types/record/types/TypedRecordInstance.md) ### Parameters #### resource [`ResourceIdentifierObject`](../../../../core/types/spec/json-api-raw/types/ResourceIdentifierObject.md)<[`TypeFromInstance`](../../../../core/types/record/types/TypeFromInstance.md)<`T`>> either a string representing the name of the resource or a ResourceIdentifier object containing both the type (a string) and the id (a string) for the record or an lid (a string) of an existing record #### options? `FindRecordBuilderOptions` if the first param is a string this will be the optional options for the request. See examples for available options. ### Returns `FindRecordRequestInput`<[`TypeFromInstance`](../../../../core/types/record/types/TypeFromInstance.md)<`T`>, `T`> request config ### Deprecated ## Call Signature ```ts function findRecord(resource: ResourceIdentifierObject, options?: FindRecordBuilderOptions): FindRecordRequestInput; ``` Defined in: [warp-drive-packages/legacy/src/compat/builders/find-record.ts:69](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/builders/find-record.ts#L69) This function builds a request config to find the record for a given identifier or type and id combination. When passed to `store.request`, this config will result in the same behavior as a `store.findRecord` request. Additionally, it takes the same options as `store.findRecord`, with the exception of `preload` (which is unsupported). **Example 1** ```ts import { findRecord } from '@warp-drive/legacy/compat/builders'; const { content: post } = await store.request(findRecord('post', '1')); ``` **Example 2** `findRecord` can be called with a single identifier argument instead of the combination of `type` (modelName) and `id` as separate arguments. You may recognize this combo as the typical pairing from [JSON:API](https://jsonapi.org/format/#document-resource-object-identification) ```ts import { findRecord } from '@warp-drive/legacy/compat/builders'; const { content: post } = await store.request(findRecord({ type: 'post', id })); ``` All `@warp-drive/legacy/compat` builders exist to enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of Warp Drive. ### Parameters #### resource [`ResourceIdentifierObject`](../../../../core/types/spec/json-api-raw/types/ResourceIdentifierObject.md) either a string representing the name of the resource or a ResourceIdentifier object containing both the type (a string) and the id (a string) for the record or an lid (a string) of an existing record #### options? `FindRecordBuilderOptions` if the first param is a string this will be the optional options for the request. See examples for available options. ### Returns `FindRecordRequestInput` request config ### Deprecated --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/builders/functions/query.md description: >- Deprecated legacy builder for a `store.request` config that behaves like `store.query`, returning the records matching a query object. --- # ~~query()~~ ```ts function query( type: TypeFromInstance, query: LegacyResourceQuery, options?: QueryOptions ): QueryRequestInput, T[]>; function query( type: string, query: LegacyResourceQuery, options?: QueryOptions ): QueryRequestInput; ``` ## Call Signature ```ts function query( type: TypeFromInstance, query: LegacyResourceQuery, options?: QueryOptions ): QueryRequestInput, T[]>; ``` Defined in: [warp-drive-packages/legacy/src/compat/builders/query.ts:40](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/builders/query.ts#L40) This function builds a request config for a given type and query object. When passed to `store.request`, this config will result in the same behavior as a `store.query` request. Additionally, it takes the same options as `store.query`. All `@warp-drive/legacy/compat` builders exist to enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of WarpDrive. ### Type Parameters #### T `T` *extends* [`TypedRecordInstance`](../../../../core/types/record/types/TypedRecordInstance.md) ### Parameters #### type [`TypeFromInstance`](../../../../core/types/record/types/TypeFromInstance.md)<`T`> the name of the resource #### query `LegacyResourceQuery` a query to be used by the adapter #### options? `QueryOptions` optional, may include `adapterOptions` hash which will be passed to adapter.query ### Returns `QueryRequestInput`<[`TypeFromInstance`](../../../../core/types/record/types/TypeFromInstance.md)<`T`>, `T`\[]> request config ### Deprecated ## Call Signature ```ts function query( type: string, query: LegacyResourceQuery, options?: QueryOptions ): QueryRequestInput; ``` Defined in: [warp-drive-packages/legacy/src/compat/builders/query.ts:45](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/builders/query.ts#L45) This function builds a request config for a given type and query object. When passed to `store.request`, this config will result in the same behavior as a `store.query` request. Additionally, it takes the same options as `store.query`. All `@warp-drive/legacy/compat` builders exist to enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of WarpDrive. ### Parameters #### type `string` the name of the resource #### query `LegacyResourceQuery` a query to be used by the adapter #### options? `QueryOptions` optional, may include `adapterOptions` hash which will be passed to adapter.query ### Returns `QueryRequestInput` request config ### Deprecated --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/builders/functions/queryRecord.md description: >- Deprecated legacy builder for a `store.request` config that behaves like `store.queryRecord`, returning a single record or `null` for a query object. --- # ~~queryRecord()~~ ```ts function queryRecord( type: TypeFromInstance, query: LegacyResourceQuery, options?: QueryOptions ): QueryRecordRequestInput, T | null>; function queryRecord( type: string, query: LegacyResourceQuery, options?: QueryOptions ): QueryRecordRequestInput; ``` ## Call Signature ```ts function queryRecord( type: TypeFromInstance, query: LegacyResourceQuery, options?: QueryOptions ): QueryRecordRequestInput, T | null>; ``` Defined in: [warp-drive-packages/legacy/src/compat/builders/query.ts:101](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/builders/query.ts#L101) This function builds a request config for a given type and query object. When passed to `store.request`, this config will result in the same behavior as a `store.queryRecord` request. Additionally, it takes the same options as `store.queryRecord`. All `@warp-drive/legacy/compat` builders exist to enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of WarpDrive. ### Type Parameters #### T `T` *extends* [`TypedRecordInstance`](../../../../core/types/record/types/TypedRecordInstance.md) ### Parameters #### type [`TypeFromInstance`](../../../../core/types/record/types/TypeFromInstance.md)<`T`> the name of the resource #### query `LegacyResourceQuery` a query to be used by the adapter #### options? `QueryOptions` optional, may include `adapterOptions` hash which will be passed to adapter.query ### Returns `QueryRecordRequestInput`<[`TypeFromInstance`](../../../../core/types/record/types/TypeFromInstance.md)<`T`>, `T` | `null`> request config ### Deprecated ## Call Signature ```ts function queryRecord( type: string, query: LegacyResourceQuery, options?: QueryOptions ): QueryRecordRequestInput; ``` Defined in: [warp-drive-packages/legacy/src/compat/builders/query.ts:106](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/builders/query.ts#L106) This function builds a request config for a given type and query object. When passed to `store.request`, this config will result in the same behavior as a `store.queryRecord` request. Additionally, it takes the same options as `store.queryRecord`. All `@warp-drive/legacy/compat` builders exist to enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of WarpDrive. ### Parameters #### type `string` the name of the resource #### query `LegacyResourceQuery` a query to be used by the adapter #### options? `QueryOptions` optional, may include `adapterOptions` hash which will be passed to adapter.query ### Returns `QueryRecordRequestInput` request config ### Deprecated --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/builders/functions/saveRecord.md description: >- Deprecated legacy builder for a `store.request` config that creates, updates, or deletes a record through adapters, like the legacy `store.saveRecord`. --- # ~~saveRecord()~~ ```ts function saveRecord(record: T, options?: Record): SaveRecordRequestInput, T>; ``` Defined in: [warp-drive-packages/legacy/src/compat/builders/save-record.ts:48](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/builders/save-record.ts#L48) This function builds a request config for saving the given record (e.g. creating, updating, or deleting the record). When passed to `store.request`, this config will result in the same behavior as a legacy `store.saveRecord` request. Additionally, it takes the same options as `store.saveRecord`. All `@ember-data/legacy-compat` builders exist to enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of Ember Data. ## Type Parameters ### T `T` *extends* [`TypedRecordInstance`](../../../../core/types/record/types/TypedRecordInstance.md) ## Parameters ### record `T` a record to save ### options? [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> = `{}` optional, may include `adapterOptions` hash which will be passed to adapter.saveRecord ## Returns `SaveRecordRequestInput`<[`TypeFromInstance`](../../../../core/types/record/types/TypeFromInstance.md)<`T`>, `T`> request config ## Deprecated --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/compat/builders.md description: >- Deprecated request builders that move `findRecord`, `query`, and `saveRecord` calls to `store.request` while still using adapters and serializers. --- Builders for migrating from `store` methods to `store.request`. These builders enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of Ember Data. ## Deprecated ## Functions * [~~findAll~~](functions/findAll.md) * [~~findRecord~~](functions/findRecord.md) * [~~query~~](functions/query.md) * [~~queryRecord~~](functions/queryRecord.md) * [~~saveRecord~~](functions/saveRecord.md) --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/compat/extensions.md description: >- Legacy schema extensions that give reactive objects and arrays the classic `EmberObject` and Ember array APIs, such as `get`, `set` and `mapBy`, plus matching types. --- ## Variables * [EmberArrayLikeExtension](variables/EmberArrayLikeExtension.md) * [EmberObjectArrayExtension](variables/EmberObjectArrayExtension.md) * [EmberObjectExtension](variables/EmberObjectExtension.md) ## Types * [ArrayType](types/ArrayType.md) * [WithArrayLike](types/WithArrayLike.md) * [WithEmberObject](types/WithEmberObject.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/extensions/types/ArrayType.md description: >- Type utility resolving to the element type of an array type, or `never` for non-arrays. --- # ArrayType\ ```ts type ArrayType = T extends ReadonlyArray ? U : never; ``` Defined in: [warp-drive-packages/legacy/src/compat/extensions.ts:393](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/extensions.ts#L393) Extracts the element type of an array type, or `never` if `T` is not an array. ## Type Parameters ### T `T` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/extensions/types/WithArrayLike.md description: >- Legacy type that adds Ember array methods such as `mapBy` and `firstObject` to a reactive array type using `EmberArrayLikeExtension`. --- # WithArrayLike\ ```ts type WithArrayLike = T extends infer U[] ? U & Omit & { firstObject: T | undefined; lastObject: T | undefined; } : T[] & Omit & { firstObject: T | undefined; lastObject: T | undefined; }; ``` Defined in: [warp-drive-packages/legacy/src/compat/extensions.ts:410](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/extensions.ts#L410) Adds Ember's classic array-like API (as registered by [EmberArrayLikeExtension](../variables/EmberArrayLikeExtension.md)) to the type of a reactive array resource. ## Type Parameters ### T `T` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/extensions/types/WithEmberObject.md description: >- Legacy type that adds the classic `EmberObject` methods to a reactive resource type using `EmberObjectExtension` or `EmberObjectArrayExtension`. --- # WithEmberObject\ ```ts type WithEmberObject = T & Pick>; ``` Defined in: [warp-drive-packages/legacy/src/compat/extensions.ts:401](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/extensions.ts#L401) Adds the classic `EmberObject` API (as registered by [EmberObjectExtension](../variables/EmberObjectExtension.md)/ [EmberObjectArrayExtension](../variables/EmberObjectArrayExtension.md)) to the type of a reactive resource. ## Type Parameters ### T `T` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/extensions/variables/EmberArrayLikeExtension.md description: >- Legacy schema extension that gives reactive arrays Ember array methods such as `pushObject`, `mapBy`, `filterBy`, and `firstObject`. --- # EmberArrayLikeExtension ```ts const EmberArrayLikeExtension: CAUTION_MEGA_DANGER_ZONE_Extension; ``` Defined in: [warp-drive-packages/legacy/src/compat/extensions.ts:382](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/extensions.ts#L382) A schema extension that adds Ember's classic `MutableArray`/`Enumerable` style methods (`pushObject`, `removeObject`, `mapBy`, `filterBy`, `sortBy`, `firstObject`, `lastObject`, etc.) to reactive array resources. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/extensions/variables/EmberObjectArrayExtension.md description: >- Legacy schema extension that gives reactive arrays the classic `EmberObject` API such as `get`, `set`, and observers, to ease migration from Ember objects. --- # EmberObjectArrayExtension ```ts const EmberObjectArrayExtension: CAUTION_MEGA_DANGER_ZONE_Extension; ``` Defined in: [warp-drive-packages/legacy/src/compat/extensions.ts:91](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/extensions.ts#L91) A schema extension that adds the classic `EmberObject` API (`get`, `set`, `getProperties`, `setProperties`, `incrementProperty`, `decrementProperty`, `toggleProperty`, `notifyPropertyChange`, `addObserver`, `removeObserver`) to reactive array resources. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/extensions/variables/EmberObjectExtension.md description: >- Legacy schema extension that gives reactive objects the classic `EmberObject` API such as `get`, `set`, and observers, to ease migration from Ember objects. --- # EmberObjectExtension ```ts const EmberObjectExtension: CAUTION_MEGA_DANGER_ZONE_Extension; ``` Defined in: [warp-drive-packages/legacy/src/compat/extensions.ts:105](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/extensions.ts#L105) A schema extension that adds the classic `EmberObject` API (`get`, `set`, `getProperties`, `setProperties`, `incrementProperty`, `decrementProperty`, `toggleProperty`, `notifyPropertyChange`, `addObserver`, `removeObserver`) to reactive object resources. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/functions/adapterFor.md description: >- Legacy store method that returns the cached adapter for a model type, falling back to the `application` adapter. --- # adapterFor() ```ts function adapterFor(this: Store$1, modelName: string): MinimumAdapterInterface; function adapterFor( this: Store$1, modelName: string, _allowMissing: true ): | MinimumAdapterInterface | undefined; ``` ## Call Signature ```ts function adapterFor(this: Store$1, modelName: string): MinimumAdapterInterface; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:145](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L145) Returns an instance of the adapter for a given type. For example, `adapterFor('person')` will return an instance of the adapter located at `app/adapters/person.js` If no `person` adapter is found, this method will look for an `application` adapter (the default adapter for your entire application). ### Parameters #### this `Store$1` #### modelName `string` ### Returns [`MinimumAdapterInterface`](../types/MinimumAdapterInterface.md) ## Call Signature ```ts function adapterFor( this: Store$1, modelName: string, _allowMissing: true ): | MinimumAdapterInterface | undefined; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:146](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L146) Returns an instance of the adapter for a given type. For example, `adapterFor('person')` will return an instance of the adapter located at `app/adapters/person.js` If no `person` adapter is found, this method will look for an `application` adapter (the default adapter for your entire application). ### Parameters #### this `Store$1` #### modelName `string` #### \_allowMissing `true` ### Returns | [`MinimumAdapterInterface`](../types/MinimumAdapterInterface.md) | `undefined` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/functions/cleanup.md description: >- Legacy store teardown hook that destroys every adapter and serializer instance the store has cached. --- # cleanup() ```ts function cleanup(this: Store$1): void; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:398](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L398) Destroys any adapters/serializers the legacy network layer has created for this store, invoked when the store itself is destroyed. ## Parameters ### this `Store$1` ## Returns `void` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/functions/normalize.md description: >- Legacy store method that converts a raw payload into the normalized document `store.push` expects, using the serializer for the given model type. --- # normalize() ```ts function normalize( this: Store$1, modelName: string, payload: ObjectValue ): SingleResourceDocument; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:278](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L278) **`Legacy`** `normalize` converts a json payload into the normalized form expected by Store.push | push using the serializer specified by `modelName` :::warning Generally it would be better to invoke the serializer yourself directly, or write a more specialized normalization utility. ::: Example ```js socket.on('message', function(message) { let modelName = message.model; let data = message.data; store.push(store.normalize(modelName, data)); }); ``` ## Parameters ### this `Store$1` ### modelName `string` The name of the model type for this payload ### payload [`ObjectValue`](../../../core/types/json/raw/types/ObjectValue.md) ## Returns [`SingleResourceDocument`](../../../core/types/spec/json-api-raw/types/SingleResourceDocument.md) The normalized payload --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/functions/pushPayload.md description: >- Legacy store method that pushes a raw payload into the store after the application serializer, or the given model type's serializer, normalizes it. --- # pushPayload() ```ts function pushPayload( this: Store$1, modelName: string, inputPayload: ObjectValue ): void; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:357](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L357) Push some raw data into the store. This method can be used both to push in brand new records, as well as to update existing records. You can push in more than one type of object at once. All objects should be in the format expected by the serializer. ```js [app/serializers/application.js] import RESTSerializer from '@warp-drive/legacy/serializer/rest'; export default class ApplicationSerializer extends RESTSerializer; ``` ```js let pushData = { posts: [ { id: 1, postTitle: "Great post", commentIds: [2] } ], comments: [ { id: 2, commentBody: "Insightful comment" } ] } store.pushPayload(pushData); ``` By default, the data will be deserialized using a default serializer (the application serializer if it exists). Alternatively, `pushPayload` will accept a model type which will determine which serializer will process the payload. ```js [app/serializers/application.js] import RESTSerializer from '@warp-drive/legacy/serializer/rest'; export default class ApplicationSerializer extends RESTSerializer; ``` ```js [app/serializers/post.js] import JSONSerializer from '@warp-drive/legacy/serializer/json'; export default JSONSerializer; ``` ```js store.pushPayload(pushData); // Will use the application serializer store.pushPayload('post', pushData); // Will use the post serializer ``` ## Parameters ### this `Store$1` ### modelName `string` Optionally, a model type used to determine which serializer will be used ### inputPayload [`ObjectValue`](../../../core/types/json/raw/types/ObjectValue.md) ## Returns `void` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/functions/serializeRecord.md description: >- Legacy store method that serializes a record into a payload using its model type's serializer. --- # serializeRecord() ```ts function serializeRecord( this: Store$1, record: unknown, options?: SerializerOptions ): unknown; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:382](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L382) Serializes a record using the store's legacy network layer, as with [store.serializeRecord](../types/LegacyStoreCompat.md#serializerecord). ## Parameters ### this `Store$1` ### record `unknown` ### options? [`SerializerOptions`](../types/SerializerOptions.md) ## Returns `unknown` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/functions/serializerFor.md description: >- Legacy store method that returns the cached serializer for a model type, falling back to the `application` serializer, or `null` if neither exists. --- # serializerFor() ```ts function serializerFor(this: Store$1, modelName: string): | MinimumSerializerInterface | null; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:209](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L209) Returns an instance of the serializer for a given type. For example, `serializerFor('person')` will return an instance of `App.PersonSerializer`. If no `App.PersonSerializer` is found, this method will look for an `App.ApplicationSerializer` (the default serializer for your entire application). If a serializer cannot be found on the adapter, it will fall back to an instance of `JSONSerializer`. ## Parameters ### this `Store$1` ### modelName `string` the record to serialize ## Returns | [`MinimumSerializerInterface`](../types/MinimumSerializerInterface.md) | `null` --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/compat.md description: >- Legacy store support for adapters and serializers: the `LegacyNetworkHandler` plus store methods such as `adapterFor`, `serializerFor`, `normalize` and `pushPayload`. --- Helps an app migrate incrementally from legacy EmberData patterns to modern ***Warp*Drive**. ## Why it exists While migrating, you may need to: * keep Adapters and Serializers working on a Store whose requests go through the [RequestManager](../../core/classes/RequestManager.md) * keep the deprecated request methods such as `store.findRecord` and `store.query`, which Adapters fulfill, working while you move calls to `store.request` * adopt modern patterns one piece at a time rather than all at once ## What it provides * [LegacyNetworkHandler](variables/LegacyNetworkHandler.md), a request handler that fulfills those legacy requests through the store's Adapters and Serializers and passes every other request along * [adapterFor](functions/adapterFor.md), [serializerFor](functions/serializerFor.md), [normalize](functions/normalize.md), [pushPayload](functions/pushPayload.md) and [serializeRecord](functions/serializeRecord.md), the store methods for working with Adapters and Serializers, and [LegacyStoreCompat](types/LegacyStoreCompat.md), the Store type that includes them The Store that [useLegacyStore](/api/@warp-drive/legacy/functions/useLegacyStore) produces adds `LegacyNetworkHandler` to its RequestManager unless `linksMode` is `true`. The hooks that present `Model` instances live in [@warp-drive/legacy/model](/api/@warp-drive/legacy/model/), not here. ## When to use it Only during a migration from legacy EmberData to modern ***Warp*Drive**. It lets you adopt modern patterns incrementally while your existing Adapters and Serializers keep working. For incremental migration strategies, see the [Migration Guide](/upgrading/v5/) and the [Two Store Migration Strategy](/upgrading/v5/two-store-migration). ## Variables * [LegacyNetworkHandler](variables/LegacyNetworkHandler.md) ## Functions * [adapterFor](functions/adapterFor.md) * [cleanup](functions/cleanup.md) * [normalize](functions/normalize.md) * [pushPayload](functions/pushPayload.md) * [serializeRecord](functions/serializeRecord.md) * [serializerFor](functions/serializerFor.md) ## Types * [LegacyStoreCompat](types/LegacyStoreCompat.md) * [MinimumAdapterInterface](types/MinimumAdapterInterface.md) * [MinimumSerializerInterface](types/MinimumSerializerInterface.md) * [AdapterPayload](types/AdapterPayload.md) * [~~CompatStore~~](types/CompatStore.md) * [SerializerOptions](types/SerializerOptions.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/types/AdapterPayload.md description: >- Raw object or array payload a legacy adapter resolves with, before a serializer normalizes it into a JSON:API document. --- # AdapterPayload ```ts type AdapterPayload = | Record | unknown[]; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:27](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L27) The raw payload shape returned by a legacy adapter's request methods, prior to being normalized by a [MinimumSerializerInterface](MinimumSerializerInterface.md). --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/types/CompatStore.md description: >- Deprecated alias of `LegacyStoreCompat`, the `Store` type extended with legacy adapter and serializer methods. --- # ~~CompatStore~~ ```ts type CompatStore = LegacyStoreCompat; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:129](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L129) ## Deprecated * use [LegacyStoreCompat](LegacyStoreCompat.md) instead --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/types/LegacyStoreCompat.md description: >- Legacy `Store` type extended with `adapterFor`, `serializerFor`, `normalize`, `pushPayload`, and `serializeRecord` from the adapter and serializer network layer. --- # LegacyStoreCompat ```ts interface LegacyStoreCompat extends Store$1 { [key: string]: any; adapterFor(this: Store$1, modelName: string): MinimumAdapterInterface; adapterFor(this: Store$1, modelName: string, _allowMissing: true): MinimumAdapterInterface | undefined; normalize(modelName: string, payload: ObjectValue): ObjectValue; pushPayload(modelName: string, payload: ObjectValue): void; serializeRecord(record: unknown, options?: SerializerOptions): unknown; serializerFor(modelName: K, _allowMissing?: boolean): MinimumSerializerInterface | null; } ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:73](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L73) **`No Inherit Doc`** **`Legacy`** Extends the signature of Store with additional methods available when using the legacy network layer. ## Extends * `Store$1` ## Indexable ```ts [key: string]: any ``` ## Methods ### adapterFor() ```ts adapterFor(this: Store$1, modelName: string): MinimumAdapterInterface; adapterFor( this: Store$1, modelName: string, _allowMissing: true ): MinimumAdapterInterface | undefined; ``` #### Call Signature ```ts adapterFor(this: Store$1, modelName: string): MinimumAdapterInterface; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:83](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L83) Returns the adapter instance for the given model type, instantiating it (and caching the instance) if necessary. See [adapterFor](../functions/adapterFor.md). ##### Parameters ###### this `Store$1` ###### modelName `string` ##### Returns [`MinimumAdapterInterface`](MinimumAdapterInterface.md) #### Call Signature ```ts adapterFor( this: Store$1, modelName: string, _allowMissing: true ): MinimumAdapterInterface | undefined; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:89](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L89) Same as the single-argument overload, but returns `undefined` instead of throwing/asserting when `_allowMissing` is `true` and no adapter is found. ##### Parameters ###### this `Store$1` ###### modelName `string` ###### \_allowMissing `true` ##### Returns [`MinimumAdapterInterface`](MinimumAdapterInterface.md) | `undefined` *** ### normalize() ```ts normalize(modelName: string, payload: ObjectValue): ObjectValue; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:101](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L101) Normalizes a payload for the given model type using its serializer. See [normalize](../functions/normalize.md). #### Parameters ##### modelName `string` ##### payload [`ObjectValue`](../../../core/types/json/raw/types/ObjectValue.md) #### Returns [`ObjectValue`](../../../core/types/json/raw/types/ObjectValue.md) *** ### pushPayload() ```ts pushPayload(modelName: string, payload: ObjectValue): void; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:107](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L107) Pushes a payload into the store using the appropriate serializer to normalize it first. See [pushPayload](../functions/pushPayload.md). #### Parameters ##### modelName `string` ##### payload [`ObjectValue`](../../../core/types/json/raw/types/ObjectValue.md) #### Returns `void` *** ### serializeRecord() ```ts serializeRecord(record: unknown, options?: SerializerOptions): unknown; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:112](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L112) Serializes a record using its serializer. See [serializeRecord](../functions/serializeRecord.md). #### Parameters ##### record `unknown` ##### options? [`SerializerOptions`](SerializerOptions.md) #### Returns `unknown` *** ### serializerFor() ```ts serializerFor(modelName: K, _allowMissing?: boolean): MinimumSerializerInterface | null; ``` Defined in: [warp-drive-packages/legacy/src/compat.ts:95](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat.ts#L95) Returns the serializer instance for the given model type, instantiating it (and caching the instance) if necessary. See [serializerFor](../functions/serializerFor.md). #### Type Parameters ##### K `K` *extends* `string` #### Parameters ##### modelName `K` ##### \_allowMissing? `boolean` #### Returns [`MinimumSerializerInterface`](MinimumSerializerInterface.md) | `null` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/types/MinimumAdapterInterface.md description: >- Legacy contract for adapters: the `findRecord`, `query`, `createRecord`, and other methods the store calls to load and save data, and which are optional. (Interface) Adapter --- # MinimumAdapterInterface ```ts interface MinimumAdapterInterface { coalesceFindRequests?: boolean; createRecord(store: Store$1, schema: ModelSchema, snapshot: Snapshot): Promise; deleteRecord(store: Store$1, schema: ModelSchema, snapshot: Snapshot): Promise; destroy?(): void; findAll(store: Store$1, schema: ModelSchema, sinceToken: null, snapshotRecordArray: SnapshotRecordArray): Promise; findBelongsTo?(store: Store$1, snapshot: Snapshot, relatedLink: string, relationship: LegacyRelationshipField): Promise; findHasMany?(store: Store$1, snapshot: Snapshot, relatedLink: string, relationship: LegacyRelationshipField): Promise; findMany?(store: Store$1, schema: ModelSchema, ids: string[], snapshots: Snapshot[]): Promise; findRecord(store: Store$1, schema: ModelSchema, id: string, snapshot: Snapshot): Promise; generateIdForRecord?(store: Store$1, type: string, properties: unknown): string; groupRecordsForFindMany?(store: Store$1, snapshots: Snapshot[]): Group[]; query(store: Store$1, schema: ModelSchema, query: Record, recordArray: LegacyQueryArray, options: { adapterOptions?: unknown }): Promise; queryRecord(store: Store$1, schema: ModelSchema, query: Record, options: { adapterOptions?: unknown }): Promise; shouldBackgroundReloadAll?(store: Store$1, snapshotArray: SnapshotRecordArray): boolean; shouldBackgroundReloadRecord?(store: Store$1, snapshot: Snapshot): boolean; shouldReloadAll?(store: Store$1, snapshotArray: SnapshotRecordArray): boolean; shouldReloadRecord?(store: Store$1, snapshot: Snapshot): boolean; updateRecord(store: Store$1, schema: ModelSchema, snapshot: Snapshot): Promise; } ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:47](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L47) :::danger ⚠️ **This is LEGACY documentation** for a feature that is no longer encouraged to be used. If starting a new app or thinking of implementing a new adapter, consider writing a Handler instead to be used with the [RequestManager](../../../core/classes/RequestManager.md) ::: The following documentation describes the methods an adapter should implement with descriptions around when an application might expect these methods to be called. Methods that are not required are marked as **optional**. ## Methods ### createRecord() ```ts createRecord( store: Store$1, schema: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:229](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L229) `adapter.createRecord` takes a request to create a resource of a given `type` and should return a `Promise` which fulfills with data for the newly created resource. The response will be fed to the associated serializer's `normalizeResponse` method with the `requestType` set to `createRecord`, which should return a `JSON:API` document. The final result after normalization to `JSON:API` will be added to store via `store.push` where it will merge with any existing data for the record. ⚠️ If the adapter's response resolves to a false-y value, the associated `serializer.normalizeResponse` call will NOT be made. In this scenario you may need to do at least a minimum amount of response processing within the adapter. If the adapter rejects or throws an error the record will enter an error state and the attributes that had attempted to be saved will still be considered dirty. ### InvalidErrors When rejecting a `createRecord` request due to validation issues during save (typically a 422 status code), you may throw an `InvalidError`. Throwing an `InvalidError` makes per-attribute errors available for records to use in the UI as needed. Records can also use this information to mark themselves as being in an `invalid` state. For more reading [see the RecordData Errors RFC](https://emberjs.github.io/rfcs/0465-record-data-errors.html) ```js let error = new Error(errorMessage); // these two properties combined // alert WarpDrive to this error being for // invalid properties on the record during // the request error.isAdapterError = true; error.code = 'InvalidError'; // A JSON:API formatted array of errors // See https://jsonapi.org/format/#errors error.errors = []; throw error; ``` #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### schema `ModelSchema` An object with methods for accessing information about the type, attributes and relationships of the primary type associated with the request. ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](AdapterPayload.md)> a promise resolving with resource data to feed to the associated serializer *** ### deleteRecord() ```ts deleteRecord( store: Store$1, schema: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:307](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L307) `adapter.deleteRecord` takes a request to delete a resource of a given `type` and should return a `Promise` which resolves when that deletion is complete. Usually the response will be empty, but you may include additional updates in the response. The response will be fed to the associated serializer's `normalizeResponse` method with the `requestType` set to `deleteRecord`, which should return a `JSON:API` document. The final result after normalization to `JSON:API` will be added to store via `store.push` where it will merge with any existing data. ⚠️ If the adapter's response resolves to a false-y value, the associated `serializer.normalizeResponse` call will NOT be made. In this scenario you may need to do at least a minimum amount of response processing within the adapter. If the adapter rejects or errors the record will need to be saved again once the reason for the error is addressed in order to persist the deleted state. #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### schema `ModelSchema` An object with methods for accessing information about the type, attributes and relationships of the primary type associated with the request. ##### snapshot `Snapshot` A Snapshot containing the record's current data #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](AdapterPayload.md)> *** ### destroy()? ```ts optional destroy(): void; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:583](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L583) **`Optional`** In some situations the adapter may need to perform cleanup when destroyed, that cleanup can be done in `destroy`. If not implemented, the store does not inform the adapter of destruction. #### Returns `void` *** ### findAll() ```ts findAll( store: Store$1, schema: ModelSchema, sinceToken: null, snapshotRecordArray: SnapshotRecordArray ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:105](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L105) `adapter.findAll` takes a request for resources of a given `type` and should return a `Promise` which fulfills with a collection of resource data matching that `type`. The response will be fed to the associated serializer's `normalizeResponse` method with the `requestType` set to `findAll`, which should return a `JSON:API` document. The final result after normalization to `JSON:API` will be added to store via `store.push` where it will merge with any existing records for `type`. Existing records for the `type` will not be removed. ⚠️ If the adapter's response resolves to a false-y value, the associated `serializer.normalizeResponse` call will NOT be made. In this scenario you may need to do at least a minimum amount of response processing within the adapter. `adapter.findAll` is called whenever `store.findAll` is asked to reload or backgroundReload. The records in the response are merged with the contents of the store. Existing records for the `type` will not be removed. See also `shouldReloadAll` and `shouldBackgroundReloadAll` #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### schema `ModelSchema` An object with methods for accessing information about the type, attributes and relationships of the primary type associated with the request. ##### sinceToken `null` This parameter is no longer used and will always be null. ##### snapshotRecordArray `SnapshotRecordArray` an object containing any passed in options, adapterOptions, and the ability to access a snapshot for each existing record of the type. #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](AdapterPayload.md)> a promise resolving with resource data to feed to the associated serializer *** ### findBelongsTo()? ```ts optional findBelongsTo( store: Store$1, snapshot: Snapshot, relatedLink: string, relationship: LegacyRelationshipField ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:338](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L338) **`Optional`** `adapter.findBelongsTo` takes a request to fetch a related resource located at a `relatedLink` and should return a `Promise` which fulfills with data for a single resource. ⚠️ This method is only called if the store previously received relationship information for a resource containing a [related link](https://jsonapi.org/format/#document-resource-object-related-resource-links). If the cache does not have a `link` for the relationship then `findRecord` will be used if a `type` and `id` for the related resource is known. The response will be fed to the associated serializer's `normalizeResponse` method with the `requestType` set to `findBelongsTo`, which should return a `JSON:API` document. The final result after normalization to `JSON:API` will be added to store via `store.push` where it will merge with any existing data. ⚠️ If the adapter's response resolves to a false-y value, the associated `serializer.normalizeResponse` call will NOT be made. In this scenario you may need to do at least a minimum amount of response processing within the adapter. #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### snapshot `Snapshot` A Snapshot containing the parent record's current data ##### relatedLink `string` The link at which the associated resource might be found ##### relationship [`LegacyRelationshipField`](../../../core/types/schema/fields/types/LegacyRelationshipField.md) #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](AdapterPayload.md)> a promise resolving with resource data to feed to the associated serializer *** ### findHasMany()? ```ts optional findHasMany( store: Store$1, snapshot: Snapshot, relatedLink: string, relationship: LegacyRelationshipField ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:375](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L375) **`Optional`** `adapter.findHasMany` takes a request to fetch a related resource collection located at a `relatedLink` and should return a `Promise` which fulfills with data for that collection. ⚠️ This method is only called if the store previously received relationship information for a resource containing a [related link](https://jsonapi.org/format/#document-resource-object-related-resource-links). If the cache does not have a `link` for the relationship but the `type` and `id` of related resources are known then `findRecord` will be used for each individual related resource. The response will be fed to the associated serializer's `normalizeResponse` method with the `requestType` set to `findHasMany`, which should return a `JSON:API` document. The final result after normalization to `JSON:API` will be added to store via `store.push` where it will merge with any existing data. ⚠️ If the adapter's response resolves to a false-y value, the associated `serializer.normalizeResponse` call will NOT be made. In this scenario you may need to do at least a minimum amount of response processing within the adapter. #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### snapshot `Snapshot` A Snapshot containing the parent record's current data ##### relatedLink `string` The link at which the associated resource collection might be found ##### relationship [`LegacyRelationshipField`](../../../core/types/schema/fields/types/LegacyRelationshipField.md) #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](AdapterPayload.md)> a promise resolving with resource data to feed to the associated serializer *** ### findMany()? ```ts optional findMany( store: Store$1, schema: ModelSchema, ids: string[], snapshots: Snapshot[] ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:410](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L410) **`Optional`** ⚠️ This Method is only called if `coalesceFindRequests` is `true`. The array passed to it is determined by the adapter's `groupRecordsForFindMany` method, and will be called once per group returned. `adapter.findMany` takes a request to fetch a collection of resources and should return a `Promise` which fulfills with data for that collection. The response will be fed to the associated serializer's `normalizeResponse` method with the `requestType` set to `findMany`, which should return a `JSON:API` document. The final result after normalization to `JSON:API` will be added to store via `store.push` where it will merge with any existing data. ⚠️ If the adapter's response resolves to a false-y value, the associated `serializer.normalizeResponse` call will NOT be made. In this scenario you may need to do at least a minimum amount of response processing within the adapter. See also `groupRecordsForFindMany` and `coalesceFindRequests` #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### schema `ModelSchema` An object with methods for accessing information about the type, attributes and relationships of the primary type associated with the request. ##### ids `string`\[] An array of the ids of the resources to fetch ##### snapshots `Snapshot`<`unknown`>\[] An array of snapshots of the available data for the resources to fetch #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](AdapterPayload.md)> a promise resolving with resource data to feed to the associated serializer *** ### findRecord() ```ts findRecord( store: Store$1, schema: ModelSchema, id: string, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:74](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L74) `adapter.findRecord` takes a request for a resource of a given `type` and `id` combination and should return a `Promise` which fulfills with data for a single resource matching that `type` and `id`. The response will be fed to the associated serializer's `normalizeResponse` method with the `requestType` set to `findRecord`, which should return a `JSON:API` document. The final result after normalization to `JSON:API` will be added to store via `store.push` where it will merge with any existing data for the record. ⚠️ If the adapter's response resolves to a false-y value, the associated `serializer.normalizeResponse` call will NOT be made. In this scenario you may need to do at least a minimum amount of response processing within the adapter. `adapter.findRecord` is called whenever the `store` needs to load, reload, or backgroundReload the resource data for a given `type` and `id`. #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### schema `ModelSchema` An object with methods for accessing information about the type, attributes and relationships of the primary type associated with the request. ##### id `string` ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](AdapterPayload.md)> a promise resolving with resource data to feed to the associated serializer *** ### generateIdForRecord()? ```ts optional generateIdForRecord( store: Store$1, type: string, properties: unknown ): string; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:430](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L430) **`Optional`** This method provides the ability to generate an ID to assign to a new record whenever `store.createRecord` is called if no `id` was provided. Alternatively you can pass an id into the call to `store.createRecord` directly. ```js let id = generateNewId(type); let newRecord = store.createRecord(type, { id }); ``` #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### type `string` The type (or modelName) of record being created ##### properties `unknown` the properties passed as the second arg to `store.createRecord` #### Returns `string` a string ID that should be unique (no other models of `type` in the cache should have this `id`) *** ### groupRecordsForFindMany()? ```ts optional groupRecordsForFindMany(store: Store$1, snapshots: Snapshot[]): Group[]; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:472](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L472) **`Optional`** ⚠️ This Method is only called if `coalesceFindRequests` is `true`. This method allows for you to split pending requests for records into multiple `findMany` requests. It receives an array of snapshots where each snapshot represents a unique record requested via `store.findRecord` during the most recent `runloop` that was not found in the cache or needs to be reloaded. It should return an array of groups. A group is an array of snapshots meant to be fetched together by a single `findMany` request. By default if this method is not implemented WarpDrive will call `findMany` once with all requested records as a single group when `coalesceFindRequests` is `true`. See also `findMany` and `coalesceFindRequests` #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### snapshots `Snapshot`<`unknown`>\[] An array of snapshots #### Returns `Group`\[] An array of Snapshot arrays *** ### query() ```ts query( store: Store$1, schema: ModelSchema, query: Record, recordArray: LegacyQueryArray, options: { adapterOptions?: unknown; } ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:142](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L142) `adapter.query` takes a request for resources of a given `type` and should return a `Promise` which fulfills with a collection of resource data matching that `type`. The response will be fed to the associated serializer's `normalizeResponse` method with the `requestType` set to `query`, which should return a `JSON:API` document. As with `findAll`, the final result after normalization to `JSON:API` will be added to store via `store.push` where it will merge with any existing records for `type`. ⚠️ If the adapter's response resolves to a false-y value, the associated `serializer.normalizeResponse` call will NOT be made. In this scenario you may need to do at least a minimum amount of response processing within the adapter. `adapter.query` is called whenever `store.query` is called or a previous query result is asked to reload. Existing records for the `type` will not be removed. The key difference is in the result returned by the `store`. For `findAll` the result is all known records of the `type`, while for `query` it will only be the records returned from `adapter.query`. #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### schema `ModelSchema` An object with methods for accessing information about the type, attributes and relationships of the primary type associated with the request. ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### recordArray `LegacyQueryArray` ##### options ###### adapterOptions? `unknown` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](AdapterPayload.md)> a promise resolving with resource data to feed to the associated serializer *** ### queryRecord() ```ts queryRecord( store: Store$1, schema: ModelSchema, query: Record, options: { adapterOptions?: unknown; } ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:172](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L172) `adapter.queryRecord` takes a request for resource of a given `type` and should return a `Promise` which fulfills with data for a single resource matching that `type`. The response will be fed to the associated serializer's `normalizeResponse` method with the `requestType` set to `queryRecord`, which should return a `JSON:API` document. The final result after normalization to `JSON:API` will be added to store via `store.push` where it will merge with any existing data for the returned record. ⚠️ If the adapter's response resolves to a false-y value, the associated `serializer.normalizeResponse` call will NOT be made. In this scenario you may need to do at least a minimum amount of response processing within the adapter. #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### schema `ModelSchema` An object with methods for accessing information about the type, attributes and relationships of the primary type associated with the request. ##### query [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> ##### options ###### adapterOptions? `unknown` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](AdapterPayload.md)> a promise resolving with resource data to feed to the associated serializer *** ### shouldBackgroundReloadAll()? ```ts optional shouldBackgroundReloadAll(store: Store$1, snapshotArray: SnapshotRecordArray): boolean; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:572](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L572) **`Optional`** When `store.findAll()` is called and a `reload` is not initiated, the adapter is presented the opportunity to trigger a new non-blocking (background) request for records of that type Users may explicitly declare that this background request should/should not occur by passing `backgroundReload: true` or `backgroundReload: false` as an option to the request respectively. ```js store.findAll('user', { backgroundReload: false }) ``` The default behavior if this method is not implemented and the option is not specified is to perform a reload, the same as a return of `true`. #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### snapshotArray `SnapshotRecordArray` #### Returns `boolean` true if the a new request for all records of the type in SnapshotRecordArray should be made in the background, false otherwise *** ### shouldBackgroundReloadRecord()? ```ts optional shouldBackgroundReloadRecord(store: Store$1, snapshot: Snapshot): boolean; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:549](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L549) **`Optional`** When a record is already available in the store and is requested again via `store.findRecord`, and the record does not need to be reloaded prior to return, this method provides the ability to specify whether a refresh of the data for the reload should be scheduled to occur in the background. Users may explicitly declare a record should/should not be background reloaded by passing `backgroundReload: true` or `backgroundReload: false` as an option to the request respectively. ```js store.findRecord('user', '1', { backgroundReload: false }) ``` If the `backgroundReload` option is not present, this method will be called to determine whether a backgroundReload should be performed. The default behavior if this method is not implemented and the option was not specified is to background reload, the same as a return of `true`. #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### snapshot `Snapshot` A Snapshot containing the record's current data #### Returns `boolean` true if the record should be reloaded in the background, false otherwise *** ### shouldReloadAll()? ```ts optional shouldReloadAll(store: Store$1, snapshotArray: SnapshotRecordArray): boolean; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:523](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L523) **`Optional`** When `store.findAll()` is called without a `reload` option, the adapter is presented the opportunity to trigger a new request for records of that type. If `reload` is specified as an option in the request (`true` or `false`) this method will not be called. ```js store.findAll('user', { reload: false }) ``` The default behavior if this method is not implemented and the option is not specified is to not reload, the same as a return of `false`. Note: the Promise returned by `store.findAll` resolves to the same LiveArray instance returned by `store.peekAll` for that type, and will include all records in the store for the given type, including any previously existing records not returned by the reload request. #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### snapshotArray `SnapshotRecordArray` #### Returns `boolean` true if the a new request for all records of the type in SnapshotRecordArray should be made immediately, false otherwise *** ### shouldReloadRecord()? ```ts optional shouldReloadRecord(store: Store$1, snapshot: Snapshot): boolean; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:497](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L497) **`Optional`** When a record is already available in the store and is requested again via `store.findRecord`, and `reload` is not specified as an option in the request, this method is called to determine whether the record should be reloaded prior to returning the result. If `reload` is specified as an option in the request (`true` or `false`) this method will not be called. ```js store.findRecord('user', '1', { reload: false }) ``` The default behavior if this method is not implemented and the option is not specified is to not reload, the same as a return of `false`. See also the documentation for `shouldBackgroundReloadRecord` which defaults to `true`. #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### snapshot `Snapshot` A Snapshot containing the record's current data #### Returns `boolean` true if the record should be reloaded immediately, false otherwise *** ### updateRecord() ```ts updateRecord( store: Store$1, schema: ModelSchema, snapshot: Snapshot ): Promise; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:280](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L280) `adapter.updateRecord` takes a request to update a resource of a given `type` and should return a `Promise` which fulfills with the updated data for the resource. The response will be fed to the associated serializer's `normalizeResponse` method with the `requestType` set to `updateRecord`, which should return a `JSON:API` document. The final result after normalization to `JSON:API` will be added to store via `store.push` where it will merge with any existing data for the record. ⚠️ If the adapter's response resolves to a false-y value, the associated `serializer.normalizeResponse` call will NOT be made. In this scenario you may need to do at least a minimum amount of response processing within the adapter. If the adapter rejects or throws an error the record will enter an error state and the attributes that had attempted to be saved will still be considered dirty. ### InvalidErrors When rejecting a `createRecord` request due to validation issues during save (typically a 422 status code), you may throw an `InvalidError`. Throwing an `InvalidError` makes per-attribute errors available for records to use in the UI as needed. Records can also use this information to mark themselves as being in an `invalid` state. For more reading [see the RecordData Errors RFC](https://emberjs.github.io/rfcs/0465-record-data-errors.html) ```js let error = new Error(errorMessage); // these two properties combined // alert WarpDrive to this error being for // invalid properties on the record during // the request error.isAdapterError = true; error.code = 'InvalidError'; // A JSON:API formatted array of errors // See https://jsonapi.org/format/#errors error.errors = []; throw error; ``` #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### schema `ModelSchema` An object with methods for accessing information about the type, attributes and relationships of the primary type associated with the request. ##### snapshot `Snapshot` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[`AdapterPayload`](AdapterPayload.md)> ## Properties ### coalesceFindRequests? ```ts optional coalesceFindRequests?: boolean; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts:449](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-adapter-interface.ts#L449) **`Optional`** If your adapter implements `findMany`, setting this to `true` will cause `findRecord` requests triggered within the same `runloop` to be coalesced into one or more calls to `adapter.findMany`. The number of calls made and the records contained in each call can be tuned by your adapter's `groupRecordsForHasMany` method. Implementing coalescing using this flag and the associated methods does not always offer the right level of correctness, timing control or granularity. If your application would be better suited coalescing across multiple types, coalescing for longer than a single runloop, or with a more custom request structure, coalescing within your application adapter may prove more effective. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/types/MinimumSerializerInterface.md description: >- Legacy contract for serializers: `normalizeResponse` to turn adapter payloads into JSON:API, plus `serialize` and other optional methods. --- # MinimumSerializerInterface ```ts interface MinimumSerializerInterface { destroy?(): void; normalize?(schema: ModelSchema, rawPayload: ObjectValue, prop?: string): SingleResourceDocument; normalizeResponse(store: Store$1, schema: ModelSchema, rawPayload: AdapterPayload, id: string | null, requestType: | "findRecord" | "queryRecord" | "findAll" | "findBelongsTo" | "findHasMany" | "findMany" | "query" | "createRecord" | "deleteRecord" | "updateRecord"): JsonApiDocument; pushPayload?(store: Store$1, rawPayload: ObjectValue): void; serialize(snapshot: Snapshot, options?: SerializerOptions): ObjectValue; serializeIntoHash?(hash: object, schema: ModelSchema, snapshot: Snapshot, options?: SerializerOptions): void; } ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts:54](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts#L54) :::danger ⚠️ **This is LEGACY documentation** for a feature that is no longer encouraged to be used. If starting a new app or thinking of implementing a new adapter, consider writing a Handler instead to be used with the [RequestManager](../../../core/classes/RequestManager.md) ::: The following documentation describes the methods an application serializer should implement with descriptions around when an application might expect these methods to be called. Methods that are not required are marked as **optional**. ## Methods ### destroy()? ```ts optional destroy(): void; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts:261](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts#L261) **`Optional`** In some situations the serializer may need to perform cleanup when destroyed, that cleanup can be done in `destroy`. If not implemented, the store does not inform the serializer of destruction. #### Returns `void` *** ### normalize()? ```ts optional normalize( schema: ModelSchema, rawPayload: ObjectValue, prop?: string ): SingleResourceDocument; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts:169](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts#L169) **`Optional`** This method is intended to normalize data into a [JSON:API Document](https://jsonapi.org/format/#document-structure) with a data member containing a single [Resource](https://jsonapi.org/format/#document-resource-objects). * `type` should be formatted in the singular, dasherized and lowercase form * `members` (the property names of attributes and relationships) should be formatted to match their definition in the corresponding `Model` definition. Typically this will be `camelCase`. * [`lid`](https://github.com/emberjs/rfcs/blob/main/text/0403-ember-data-identifiers.md) is a valid optional sibling to `id` and `type` in both [Resources](https://jsonapi.org/format/#document-resource-objects) and [Resource Identifier Objects](https://jsonapi.org/format/#document-resource-identifier-objects) This method is called by the `Store` when `store.normalize(modelName, payload)` is called. It is recommended to use `store.serializerFor(modelName).normalizeResponse` over `store.normalize`. This method may be called when also using the `RESTSerializer` when `serializer.pushPayload` is called by `store.pushPayload`. However, it is recommended to use `store.push` over `store.pushPayload` after normalizing the payload directly. Example: ```js function pushPayload(store, modelName, rawPayload) { const ModelClass = store.modelFor(modelName); const serializer = store.serializerFor(modelName); const jsonApiPayload = serializer.normalizeResponse(store, ModelClass, rawPayload, null, 'query'); return store.push(jsonApiPayload); } ``` This method may be called when also using the `JSONAPISerializer` when normalizing included records. If mixing serializer usage in this way we recommend implementing this method, but caution that it may lead to unexpected mixing of formats. This method may also be called when normalizing embedded relationships when using the `EmbeddedRecordsMixin`. If using this mixin in a serializer in your application we recommend implementing this method, but caution that it may lead to unexpected mixing of formats. #### Parameters ##### schema `ModelSchema` An object with methods for accessing information about the type, attributes and relationships of the primary type associated with the request. ##### rawPayload [`ObjectValue`](../../../core/types/json/raw/types/ObjectValue.md) Some raw JSON data to be normalized into a JSON:API Resource. ##### prop? `string` When called by the EmbeddedRecordsMixin this param will be the property at which the object provided as rawPayload was found. #### Returns [`SingleResourceDocument`](../../../core/types/spec/json-api-raw/types/SingleResourceDocument.md) A JSON:API Document containing a single JSON:API Resource as its primary data. *** ### normalizeResponse() ```ts normalizeResponse( store: Store$1, schema: ModelSchema, rawPayload: AdapterPayload, id: string | null, requestType: | "findRecord" | "queryRecord" | "findAll" | "findBelongsTo" | "findHasMany" | "findMany" | "query" | "createRecord" | "deleteRecord" | "updateRecord" ): JsonApiDocument; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts:83](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts#L83) This method is responsible for normalizing the value resolved from the promise returned by an Adapter request into the format expected by the `Store`. The output should be a [JSON:API Document](https://jsonapi.org/format/#document-structure) with the following additional restrictions: * `type` should be formatted in the `singular` `dasherized` `lowercase` form * `members` (the property names of attributes and relationships) should be formatted to match their definition in the corresponding `Model` definition. Typically this will be `camelCase`. * [`lid`](https://github.com/emberjs/rfcs/blob/main/text/0403-ember-data-identifiers.md) is a valid optional sibling to `id` and `type` in both [Resources](https://jsonapi.org/format/#document-resource-objects) and [Resource Identifier Objects](https://jsonapi.org/format/#document-resource-identifier-objects) #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### schema `ModelSchema` An object with methods for accessing information about the type, attributes and relationships of the primary type associated with the request. ##### rawPayload [`AdapterPayload`](AdapterPayload.md) The raw JSON response data returned from an API request. This correlates to the value the promise returned by the adapter method that performed the request resolved to. ##### id `string` | `null` For a findRecord request, this is the id initially provided in the call to store.findRecord. Else this value is null. ##### requestType | `"findRecord"` | `"queryRecord"` | `"findAll"` | `"findBelongsTo"` | `"findHasMany"` | `"findMany"` | `"query"` | `"createRecord"` | `"deleteRecord"` | `"updateRecord"` The type of request the Adapter had been asked to perform. #### Returns `JsonApiDocument` a document following the structure of a [{json:api} Document](https://jsonapi.org/format/#document-structure). *** ### pushPayload()? ```ts optional pushPayload(store: Store$1, rawPayload: ObjectValue): void; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts:250](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts#L250) **`Optional`** This method allows for normalization of data when `store.pushPayload` is called and should be implemented if you want to use that method. The method is responsible for pushing new data to the store using `store.push` once any necessary normalization has occurred, and no data in the store will be updated unless it does so. The normalized form pushed to the store should be a [JSON:API Document](https://jsonapi.org/format/#document-structure) with the following additional restrictions: * `type` should be formatted in the singular, dasherized and lowercase form * `members` (the property names of attributes and relationships) should be formatted to match their definition in the corresponding `Model` definition. Typically this will be `camelCase`. * [`lid`](https://github.com/emberjs/rfcs/blob/main/text/0403-ember-data-identifiers.md) is a valid optional sibling to `id` and `type` in both [Resources](https://jsonapi.org/format/#document-resource-objects) and [Resource Identifier Objects](https://jsonapi.org/format/#document-resource-identifier-objects) If you need better control over normalization or want access to the records being added or updated in the store, we recommended using `store.push` over `store.pushPayload` after normalizing the payload directly. This can even take advantage of an existing serializer for the format the data is in, for example: ```js function pushPayload(store, modelName, rawPayload) { const ModelClass = store.modelFor(modelName); const serializer = store.serializerFor(modelName); const jsonApiPayload = serializer.normalizeResponse(store, ModelClass, rawPayload, null, 'query'); return store.push(jsonApiPayload); } ``` #### Parameters ##### store `Store$1` The store service that initiated the request being normalized ##### rawPayload [`ObjectValue`](../../../core/types/json/raw/types/ObjectValue.md) The raw JSON response data returned from an API request. This JSON should be in the API format expected by the serializer. #### Returns `void` *** ### serialize() ```ts serialize(snapshot: Snapshot, options?: SerializerOptions): ObjectValue; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts:116](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts#L116) This method is responsible for serializing an individual record via a Snapshot into the format expected by the API. This method is called by `snapshot.serialize()`. When using `Model`, this method is called by `record.serialize()`. When using `JSONAPIAdapter` or `RESTAdapter` this method is called by `updateRecord` and `createRecord` if `Serializer.serializeIntoHash` is not implemented. #### Parameters ##### snapshot `Snapshot` A Snapshot for the record to serialize ##### options? [`SerializerOptions`](SerializerOptions.md) #### Returns [`ObjectValue`](../../../core/types/json/raw/types/ObjectValue.md) *** ### serializeIntoHash()? ```ts optional serializeIntoHash( hash: object, schema: ModelSchema, snapshot: Snapshot, options?: SerializerOptions ): void; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts:208](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts#L208) **`Optional`** When using `JSONAPIAdapter` or `RESTAdapter` this method is called by `adapter.updateRecord` and `adapter.createRecord` if `serializer.serializeIntoHash` is implemented. If this method is not implemented, `serializer.serialize` will be called in this case. You can use this method to customize the root keys serialized into the payload. The hash property should be modified by reference. For instance, your API may expect resources to be keyed by underscored type in the payload: ```js { _user: { type: 'user', id: '1' } } ``` Which when using these adapters can be achieved by implementing this method similar to the following: ```js serializeIntoHash(hash, ModelClass, snapshot, options) { hash[`_${snapshot.modelName}`] = this.serialize(snapshot, options).data; } ``` #### Parameters ##### hash `object` A top most object of the request payload onto which to append the serialized record ##### schema `ModelSchema` An object with methods for accessing information about the type, attributes and relationships of the primary type associated with the request. ##### snapshot `Snapshot` A Snapshot for the record to serialize ##### options? [`SerializerOptions`](SerializerOptions.md) #### Returns `void` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/types/SerializerOptions.md description: >- Options for legacy serializer `serialize` calls, such as `includeId` to include the record id in the output. --- # SerializerOptions ```ts type SerializerOptions = { includeId?: boolean; }; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts:19](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts#L19) Options accepted by [serialize](MinimumSerializerInterface.md#serialize) and related legacy serializer methods. ## Properties ### includeId? ```ts optional includeId?: boolean; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts:23](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/minimum-serializer-interface.ts#L23) whether the resource's id should be included in the serialized output --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/utils/functions/configureAssertFn.md description: >- Legacy migration helper that registers a callback invoked when an id or type passed to these utilities fails validation. --- # configureAssertFn() ```ts function configureAssertFn(fn: (message: string, condition: unknown) => void): void; ``` Defined in: [warp-drive-packages/legacy/src/compat/utils.ts:59](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/utils.ts#L59) Configure a function to be called when an id or type fails validation. This is useful for instrumenting to discover places where usage in the app is not consistent. ## Parameters ### fn (`message`: `string`, `condition`: `unknown`) => `void` a function which takes a message and a condition ## Returns `void` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/utils/functions/configureMismatchReporter.md description: >- Legacy migration helper that registers a callback invoked whenever `formattedId` or `formattedType` has to change the id or type it was given. --- # configureMismatchReporter() ```ts function configureMismatchReporter(fn: Reporter): void; ``` Defined in: [warp-drive-packages/legacy/src/compat/utils.ts:45](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/utils.ts#L45) Configure a function to be called when an id or type changes during normalization. This is useful for instrumenting to discover places where usage in the app is not consistent. ## Parameters ### fn `Reporter` a function which takes a mismatch-type ('formatted-id' | 'formatted-type'), actual, and expected value ## Returns `void` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/utils/functions/configureTypeNormalization.md description: >- Legacy migration helper that replaces the singularize-and-dasherize function `formattedType` and `isEquivType` use to normalize resource types. --- # configureTypeNormalization() ```ts function configureTypeNormalization(fn: (type: string) => string): void; ``` Defined in: [warp-drive-packages/legacy/src/compat/utils.ts:78](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/utils.ts#L78) Configure a function to be called to normalize a resource type string. Used by both formattedType and isEquivType to ensure consistent normalization during comparison. If validation fails or the type turns out be unnormalized the configured mismatch reporter and assert functions will be called. ## Parameters ### fn (`type`: `string`) => `string` a function which takes a string and returns a string ## Returns `void` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/utils/functions/expectId.md description: >- Legacy migration helper that normalizes a resource id to a string like `formattedId`, but asserts that it is not `null`. --- # expectId() ```ts function expectId(id: string | number): string; function expectId(id: null): never; ``` ## Call Signature ```ts function expectId(id: string | number): string; ``` Defined in: [warp-drive-packages/legacy/src/compat/utils.ts:186](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/utils.ts#L186) Like [formattedId](formattedId.md), but asserts that `id` is not `null` rather than allowing and passing through `null`. ### Parameters #### id `string` | `number` ### Returns `string` ## Call Signature ```ts function expectId(id: null): never; ``` Defined in: [warp-drive-packages/legacy/src/compat/utils.ts:192](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/utils.ts#L192) Throws, since `id` is `null`. ### Parameters #### id `null` ### Returns `never` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/utils/functions/formattedId.md description: >- Legacy migration helper that normalizes a resource id to the `string` or `null` the cache expects, asserting on invalid ids such as `''` or `0`. --- # formattedId() ```ts function formattedId(id: string | number): string; function formattedId(id: null): null; function formattedId(id: string | number | null): string | null; ``` ## Call Signature ```ts function formattedId(id: string | number): string; ``` Defined in: [warp-drive-packages/legacy/src/compat/utils.ts:156](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/utils.ts#L156) Format an id to the format expected by the WarpDrive Cache. Currently this means that id should be `string | null`. Asserts invalid IDs (undefined, '', 0, '0') in dev. **Usage** ````js import formattedId from 'client/utils/formatted-id'; formattedId('1'); // => '1' formattedId(1); // => '1' formattedId(null); // => null ``` ### Parameters #### id `string` \| `number` the potentially un-normalized id ### Returns `string` the normalized id ## Call Signature ```ts function formattedId(id: null): null; ```` Defined in: [warp-drive-packages/legacy/src/compat/utils.ts:157](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/utils.ts#L157) Format an id to the format expected by the WarpDrive Cache. Currently this means that id should be `string | null`. Asserts invalid IDs (undefined, '', 0, '0') in dev. **Usage** ````js import formattedId from 'client/utils/formatted-id'; formattedId('1'); // => '1' formattedId(1); // => '1' formattedId(null); // => null ``` ### Parameters #### id `null` the potentially un-normalized id ### Returns `null` the normalized id ## Call Signature ```ts function formattedId(id: string | number | null): string | null; ```` Defined in: [warp-drive-packages/legacy/src/compat/utils.ts:158](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/utils.ts#L158) Format an id to the format expected by the WarpDrive Cache. Currently this means that id should be `string | null`. Asserts invalid IDs (undefined, '', 0, '0') in dev. **Usage** ````js import formattedId from 'client/utils/formatted-id'; formattedId('1'); // => '1' formattedId(1); // => '1' formattedId(null); // => null ``` ### Parameters #### id `string` \| `number` \| `null` the potentially un-normalized id ### Returns `string` \| `null` the normalized id ```` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/utils/functions/formattedType.md description: >- Legacy migration helper that normalizes a resource type to the singular dasherized form the cache expects, such as `'PostComments'` to `'post-comment'`. --- # formattedType() ```ts function formattedType(type: string | T): T; ``` Defined in: [warp-drive-packages/legacy/src/compat/utils.ts:115](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/utils.ts#L115) Converts a potentially unnormalized type into the format expected by our WarpDrive Cache. Currently this is singular-dasherized. you should not rely on this function to give you an exact format for display purposes. Formatting for display should be handled differently if the exact format matters. Asserts invalid types (undefined, null, '') in dev. **Usage** ```js import formattedType from 'soxhub-client/helpers/formatted-type'; formattedType('post'); // => 'post' formattedType('posts'); // => 'post' formattedType('Posts'); // => 'post' formattedType('post-comment'); // => 'post-comment' formattedType('post-comments'); // => 'post-comment' formattedType('post_comment'); // => 'post-comment' formattedType('postComment'); // => 'post-comment' formattedType('PostComment'); // => 'post-comment' ``` ## Type Parameters ### T `T` *extends* `string` ## Parameters ### type `string` | `T` the potentially un-normalized type ## Returns `T` the normalized type --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/utils/functions/isEquivId.md description: >- Legacy migration helper that reports whether two resource ids match after normalization, so `1` and `'1'` are equivalent. --- # isEquivId() ```ts function isEquivId(expected: string | number, actual: string | number | null): boolean; ``` Defined in: [warp-drive-packages/legacy/src/compat/utils.ts:263](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/utils.ts#L263) Compares two IDs for strict equality, converting them to the format expected by the WarpDrive Cache to ensure differences in format are accounted for in the comparison. Asserts when expected or actual are invalid IDs in dev. Expected may never be null. ```js isEquivId('1', 1); // true isEquivId('2', '2'); // true isEquivId(3, '3'); // true isEquivId(4, '3'); // false isEquivId(1, null); // false ``` ## Parameters ### expected `string` | `number` a potentially un-normalized id to match against ### actual `string` | `number` | `null` a potentially un-normalized id to match against ## Returns `boolean` true if the ids are equivalent --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/utils/functions/isEquivType.md description: >- Legacy migration helper that reports whether two resource types match after normalization, so `'posts'` and `'post'` are equivalent. --- # isEquivType() ```ts function isEquivType(expected: string, actual: string): boolean; ``` Defined in: [warp-drive-packages/legacy/src/compat/utils.ts:226](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/utils.ts#L226) Compares two types for strict equality, converting them to the format expected by the WarpDrive Cache to ensure differences in format are accounted for in the comparison. Asserts when expected or actual are invalid types in dev. Expected may never be null. ```js isEquivType('posts', 'post'); // true isEquivType('post', 'post'); // true isEquivType('posts', 'posts'); // true isEquivType('post-comment', 'postComment'); // true isEquivType('post-comment', 'PostComment'); // true isEquivType('post-comment', 'post_comment'); // true isEquivType('post-comment', 'post-comment'); // true isEquivType('post-comment', 'post'); // false isEquivType('posts', null); // false ``` ## Parameters ### expected `string` a potentially unnormalized type to match against ### actual `string` a potentially unnormalized type to match against ## Returns `boolean` true if the types are equivalent --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/compat/utils.md description: >- Legacy helpers that normalize, compare, and report mismatched resource ids and types while migrating to stricter formats. --- Utilities for helping to migrate to stricter and more consistent use of IDs and types. ## Functions * [configureAssertFn](functions/configureAssertFn.md) * [configureMismatchReporter](functions/configureMismatchReporter.md) * [configureTypeNormalization](functions/configureTypeNormalization.md) * [expectId](functions/expectId.md) * [formattedId](functions/formattedId.md) * [formattedType](functions/formattedType.md) * [isEquivId](functions/isEquivId.md) * [isEquivType](functions/isEquivType.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/compat/variables/LegacyNetworkHandler.md description: >- Legacy `RequestManager` handler that fulfills find, query, create, update, and delete operations through the store's adapters and serializers, passing other requests along. --- # LegacyNetworkHandler ```ts const LegacyNetworkHandler: Handler; ``` Defined in: [warp-drive-packages/legacy/src/compat/legacy-network-handler/legacy-network-handler.ts:60](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/compat/legacy-network-handler/legacy-network-handler.ts#L60) A Handler that fulfills legacy `findRecord`/`findAll`/`query`/ `queryRecord`/`findBelongsTo`/`findHasMany`/`createRecord`/`updateRecord`/ `deleteRecord` requests using the store's configured [adapter](../types/MinimumAdapterInterface.md) and [serializer](../types/MinimumSerializerInterface.md), passing any other request through to the next handler unchanged. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/functions/useLegacyStore.md description: >- Creates a `Store` class preconfigured for legacy apps, with `Model` schema support, request handlers, cache, and optional adapter, serializer, and fragment support. --- # useLegacyStore() ```ts function useLegacyStore(options: LegacyModelStoreSetupOptions, StoreKlass?: typeof Store$1): typeof ConfiguredStore; function useLegacyStore(options: LegacyModelAndNetworkStoreSetupOptions, StoreKlass?: typeof Store$1): typeof ConfiguredStore; function useLegacyStore(options: LegacyModelAndNetworkAndRequestStoreSetupOptions, StoreKlass?: typeof Store$1): typeof ConfiguredStore; ``` ## Call Signature ```ts function useLegacyStore(options: LegacyModelStoreSetupOptions, StoreKlass?: typeof Store$1): typeof ConfiguredStore; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:303](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L303) Use the legacy store with the given options. See [Configure The Store](/guides/configuration/#configure-the-store) for where it fits in an app's setup, and [LegacyMode](/guides/the-manual/schemas/resources/legacy-mode) for the schemas it supports. See [LegacyStoreSetupOptions](../types/LegacyStoreSetupOptions.md) for details on the available options. ```ts import { useLegacyStore } from '@warp-drive/legacy'; import { JSONAPICache } from '@warp-drive/json-api'; export default useLegacyStore({ linksMode: false, legacyRequests: true, cache: JSONAPICache, schemas: [], }); ``` ### Adding Stateful Handlers A request Handler is sometimes more than a plain object or class with a `request` method — it may need access to a stateful dependency such as an Ember service (an auth token, a feature-flags service, an i18n helper, etc.). A plain class handler that only relies on Ember's `@service` decorator will not work here on its own: the handler is never instantiated *through* Ember's container (it's just `new`'d up), so it has no owner and its `@service` injections would fail to resolve. Instead, give `handlers` a function. It receives the Store instance being configured, which by the time the function runs already has an owner assigned. Use `getOwner`/`setOwner` from `@ember/owner` to transfer that owner onto your handler instance before returning it, exactly as you would when constructing any other DI-aware object outside of the container: ```ts import { getOwner, setOwner } from '@ember/owner'; import { service } from '@ember/service'; import { useLegacyStore } from '@warp-drive/legacy'; import type { NextFn } from '@warp-drive/core/request'; import type { RequestContext } from '@warp-drive/core/types/request'; import { JSONAPICache } from '@warp-drive/json-api'; class AuthHandler { @service session; request(context: RequestContext, next: NextFn) { const headers = new Headers(context.request.headers); headers.append('Authorization', `Bearer ${this.session.accessToken}`); return next(Object.assign({}, context.request, { headers })); } } export default useLegacyStore({ linksMode: false, legacyRequests: true, cache: JSONAPICache, handlers: (store) => { const authHandler = new AuthHandler(); setOwner(authHandler, getOwner(store)!); return [authHandler]; }, }); ``` The `handlers` function is invoked lazily and only once per store instance, the first time `store.requestManager` is accessed, so it is safe to do owner-dependent setup like this inside of it. ### Accessing the Store from a Handler's Context If a handler only needs to read something *off of the store itself* (its cache, or a property/service you've attached to a custom store subclass) rather than an unrelated Ember service, there is a second, simpler option that requires no DI/`setOwner` wiring at all. Every request issued via Store.request | store.request(...) automatically carries the originating store along as RequestInfo.store | context.request.store. Any handler — a plain object, a function-built handler, or a class — can read it directly, without needing the `handlers` callback form shown above: ```ts import { useLegacyStore } from '@warp-drive/legacy'; import type { NextFn } from '@warp-drive/core/request'; import type { RequestContext } from '@warp-drive/core/types/request'; import { JSONAPICache } from '@warp-drive/json-api'; const LoggingHandler = { request(context: RequestContext, next: NextFn) { // only present when the request was made via `store.request(...)` const store = context.request.store; if (store) { console.log(`[${store.constructor.name}] ${context.request.url ?? ''}`); } return next(context.request); }, }; export default useLegacyStore({ linksMode: false, legacyRequests: true, cache: JSONAPICache, handlers: [LoggingHandler], }); ``` The trade-off versus the `getOwner`/`setOwner` pattern above is that `context.request.store` is only populated for requests issued via `store.request(...)`; a request made directly against a [RequestManager](../../core/classes/RequestManager.md) won't have it set unless the caller supplies it explicitly, so a handler relying on it should treat it as optional (as `LoggingHandler` does above). ### Type Parameters #### T `T` *extends* `Cache` ### Parameters #### options [`LegacyModelStoreSetupOptions`](../types/LegacyModelStoreSetupOptions.md)<`T`> #### StoreKlass? *typeof* `Store$1` ### Returns *typeof* [`ConfiguredStore`](../classes/ConfiguredStore.md) ## Call Signature ```ts function useLegacyStore(options: LegacyModelAndNetworkStoreSetupOptions, StoreKlass?: typeof Store$1): typeof ConfiguredStore; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:307](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L307) Use the legacy store with the given options. See [Configure The Store](/guides/configuration/#configure-the-store) for where it fits in an app's setup, and [LegacyMode](/guides/the-manual/schemas/resources/legacy-mode) for the schemas it supports. See [LegacyStoreSetupOptions](../types/LegacyStoreSetupOptions.md) for details on the available options. ```ts import { useLegacyStore } from '@warp-drive/legacy'; import { JSONAPICache } from '@warp-drive/json-api'; export default useLegacyStore({ linksMode: false, legacyRequests: true, cache: JSONAPICache, schemas: [], }); ``` ### Adding Stateful Handlers A request Handler is sometimes more than a plain object or class with a `request` method — it may need access to a stateful dependency such as an Ember service (an auth token, a feature-flags service, an i18n helper, etc.). A plain class handler that only relies on Ember's `@service` decorator will not work here on its own: the handler is never instantiated *through* Ember's container (it's just `new`'d up), so it has no owner and its `@service` injections would fail to resolve. Instead, give `handlers` a function. It receives the Store instance being configured, which by the time the function runs already has an owner assigned. Use `getOwner`/`setOwner` from `@ember/owner` to transfer that owner onto your handler instance before returning it, exactly as you would when constructing any other DI-aware object outside of the container: ```ts import { getOwner, setOwner } from '@ember/owner'; import { service } from '@ember/service'; import { useLegacyStore } from '@warp-drive/legacy'; import type { NextFn } from '@warp-drive/core/request'; import type { RequestContext } from '@warp-drive/core/types/request'; import { JSONAPICache } from '@warp-drive/json-api'; class AuthHandler { @service session; request(context: RequestContext, next: NextFn) { const headers = new Headers(context.request.headers); headers.append('Authorization', `Bearer ${this.session.accessToken}`); return next(Object.assign({}, context.request, { headers })); } } export default useLegacyStore({ linksMode: false, legacyRequests: true, cache: JSONAPICache, handlers: (store) => { const authHandler = new AuthHandler(); setOwner(authHandler, getOwner(store)!); return [authHandler]; }, }); ``` The `handlers` function is invoked lazily and only once per store instance, the first time `store.requestManager` is accessed, so it is safe to do owner-dependent setup like this inside of it. ### Accessing the Store from a Handler's Context If a handler only needs to read something *off of the store itself* (its cache, or a property/service you've attached to a custom store subclass) rather than an unrelated Ember service, there is a second, simpler option that requires no DI/`setOwner` wiring at all. Every request issued via Store.request | store.request(...) automatically carries the originating store along as RequestInfo.store | context.request.store. Any handler — a plain object, a function-built handler, or a class — can read it directly, without needing the `handlers` callback form shown above: ```ts import { useLegacyStore } from '@warp-drive/legacy'; import type { NextFn } from '@warp-drive/core/request'; import type { RequestContext } from '@warp-drive/core/types/request'; import { JSONAPICache } from '@warp-drive/json-api'; const LoggingHandler = { request(context: RequestContext, next: NextFn) { // only present when the request was made via `store.request(...)` const store = context.request.store; if (store) { console.log(`[${store.constructor.name}] ${context.request.url ?? ''}`); } return next(context.request); }, }; export default useLegacyStore({ linksMode: false, legacyRequests: true, cache: JSONAPICache, handlers: [LoggingHandler], }); ``` The trade-off versus the `getOwner`/`setOwner` pattern above is that `context.request.store` is only populated for requests issued via `store.request(...)`; a request made directly against a [RequestManager](../../core/classes/RequestManager.md) won't have it set unless the caller supplies it explicitly, so a handler relying on it should treat it as optional (as `LoggingHandler` does above). ### Type Parameters #### T `T` *extends* `Cache` ### Parameters #### options [`LegacyModelAndNetworkStoreSetupOptions`](../types/LegacyModelAndNetworkStoreSetupOptions.md)<`T`> #### StoreKlass? *typeof* `Store$1` ### Returns *typeof* [`ConfiguredStore`](../classes/ConfiguredStore.md) ## Call Signature ```ts function useLegacyStore(options: LegacyModelAndNetworkAndRequestStoreSetupOptions, StoreKlass?: typeof Store$1): typeof ConfiguredStore; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:311](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L311) Use the legacy store with the given options. See [Configure The Store](/guides/configuration/#configure-the-store) for where it fits in an app's setup, and [LegacyMode](/guides/the-manual/schemas/resources/legacy-mode) for the schemas it supports. See [LegacyStoreSetupOptions](../types/LegacyStoreSetupOptions.md) for details on the available options. ```ts import { useLegacyStore } from '@warp-drive/legacy'; import { JSONAPICache } from '@warp-drive/json-api'; export default useLegacyStore({ linksMode: false, legacyRequests: true, cache: JSONAPICache, schemas: [], }); ``` ### Adding Stateful Handlers A request Handler is sometimes more than a plain object or class with a `request` method — it may need access to a stateful dependency such as an Ember service (an auth token, a feature-flags service, an i18n helper, etc.). A plain class handler that only relies on Ember's `@service` decorator will not work here on its own: the handler is never instantiated *through* Ember's container (it's just `new`'d up), so it has no owner and its `@service` injections would fail to resolve. Instead, give `handlers` a function. It receives the Store instance being configured, which by the time the function runs already has an owner assigned. Use `getOwner`/`setOwner` from `@ember/owner` to transfer that owner onto your handler instance before returning it, exactly as you would when constructing any other DI-aware object outside of the container: ```ts import { getOwner, setOwner } from '@ember/owner'; import { service } from '@ember/service'; import { useLegacyStore } from '@warp-drive/legacy'; import type { NextFn } from '@warp-drive/core/request'; import type { RequestContext } from '@warp-drive/core/types/request'; import { JSONAPICache } from '@warp-drive/json-api'; class AuthHandler { @service session; request(context: RequestContext, next: NextFn) { const headers = new Headers(context.request.headers); headers.append('Authorization', `Bearer ${this.session.accessToken}`); return next(Object.assign({}, context.request, { headers })); } } export default useLegacyStore({ linksMode: false, legacyRequests: true, cache: JSONAPICache, handlers: (store) => { const authHandler = new AuthHandler(); setOwner(authHandler, getOwner(store)!); return [authHandler]; }, }); ``` The `handlers` function is invoked lazily and only once per store instance, the first time `store.requestManager` is accessed, so it is safe to do owner-dependent setup like this inside of it. ### Accessing the Store from a Handler's Context If a handler only needs to read something *off of the store itself* (its cache, or a property/service you've attached to a custom store subclass) rather than an unrelated Ember service, there is a second, simpler option that requires no DI/`setOwner` wiring at all. Every request issued via Store.request | store.request(...) automatically carries the originating store along as RequestInfo.store | context.request.store. Any handler — a plain object, a function-built handler, or a class — can read it directly, without needing the `handlers` callback form shown above: ```ts import { useLegacyStore } from '@warp-drive/legacy'; import type { NextFn } from '@warp-drive/core/request'; import type { RequestContext } from '@warp-drive/core/types/request'; import { JSONAPICache } from '@warp-drive/json-api'; const LoggingHandler = { request(context: RequestContext, next: NextFn) { // only present when the request was made via `store.request(...)` const store = context.request.store; if (store) { console.log(`[${store.constructor.name}] ${context.request.url ?? ''}`); } return next(context.request); }, }; export default useLegacyStore({ linksMode: false, legacyRequests: true, cache: JSONAPICache, handlers: [LoggingHandler], }); ``` The trade-off versus the `getOwner`/`setOwner` pattern above is that `context.request.store` is only populated for requests issued via `store.request(...)`; a request made directly against a [RequestManager](../../core/classes/RequestManager.md) won't have it set unless the caller supplies it explicitly, so a handler relying on it should treat it as optional (as `LoggingHandler` does above). ### Type Parameters #### T `T` *extends* `Cache` ### Parameters #### options [`LegacyModelAndNetworkAndRequestStoreSetupOptions`](../types/LegacyModelAndNetworkAndRequestStoreSetupOptions.md)<`T`> #### StoreKlass? *typeof* `Store$1` ### Returns *typeof* [`ConfiguredStore`](../classes/ConfiguredStore.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/classes/Fragment.md description: >- Legacy `ModelFragments`-compatible object API, such as `hasDirtyAttributes`, `isFragment`, and `rollbackAttributes`, for reactive objects migrated off fragments. --- # Fragment Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts:17](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts#L17) The features added to an object resource by [FragmentExtension](../variables/FragmentExtension.md), providing a subset of the legacy `ModelFragments` fragment API for migrated resources. ## Constructors ### Constructor ```ts new Fragment(): Fragment; ``` #### Returns `Fragment` ## Methods ### rollbackAttributes() ```ts rollbackAttributes(this: PrivateReactiveResource): void; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts:62](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts#L62) Reverts this fragment's attribute back to its last known remote value. #### Parameters ##### this `PrivateReactiveResource` #### Returns `void` ## Properties ### isDestroyed ```ts isDestroyed: boolean = false; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts:26](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts#L26) Whether this fragment has been destroyed. *** ### isDestroying ```ts isDestroying: boolean = false; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts:22](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts#L22) Whether this fragment is in the process of being destroyed. ### $type #### Get Signature ```ts get $type(): string | null | undefined; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts:54](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts#L54) The resource type of this fragment, if known. ##### Returns `string` | `null` | `undefined` *** ### hasDirtyAttributes #### Get Signature ```ts get hasDirtyAttributes(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts:32](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts#L32) Whether this fragment (or the attribute it is rooted at) has uncommitted changes. ##### Returns `boolean` *** ### isFragment #### Get Signature ```ts get isFragment(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts:47](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts#L47) Always `true`. Used to distinguish fragments from other resources. ##### Returns `boolean` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/classes/FragmentArray.md description: >- Legacy `ModelFragments`-compatible array API, such as `addFragment`, `removeFragment`, and `rollbackAttributes`, for reactive arrays migrated off fragments. --- # FragmentArray\ Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts:17](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts#L17) The features added to an array resource by [FragmentArrayExtension](../variables/FragmentArrayExtension.md), providing a subset of the legacy `ModelFragments` fragment-array API for migrated resources. ## Type Parameters ### T `T` *extends* [`Fragment`](Fragment.md) ## Constructors ### Constructor ```ts new FragmentArray(): FragmentArray; ``` #### Returns `FragmentArray`<`T`> ## Methods ### addFragment() ```ts addFragment(fragment?: T): Fragment[] | undefined; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts:49](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts#L49) Adds an existing fragment to this array, if one was given. #### Parameters ##### fragment? `T` #### Returns [`Fragment`](Fragment.md)\[] | `undefined` *** ### createFragment() ```ts createFragment(fragment?: T): Fragment | undefined; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts:60](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts#L60) Appends a new fragment to the end of this array, if one was given. #### Parameters ##### fragment? `T` #### Returns [`Fragment`](Fragment.md) | `undefined` *** ### removeFragment() ```ts removeFragment(fragment?: T): void; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts:71](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts#L71) Removes the given fragment from this array, if present. #### Parameters ##### fragment? `T` #### Returns `void` *** ### rollbackAttributes() ```ts rollbackAttributes(): void; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts:86](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts#L86) Reverts each member fragment's attribute back to its last known remote value. #### Returns `void` ## Properties ### isDestroyed ```ts isDestroyed: boolean = false; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts:26](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts#L26) Whether this fragment array has been destroyed. *** ### isDestroying ```ts isDestroying: boolean = false; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts:22](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts#L22) Whether this fragment array is in the process of being destroyed. ### hasDirtyAttributes #### Get Signature ```ts get hasDirtyAttributes(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts:32](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts#L32) Whether this fragment array (or any of its members) has uncommitted changes. ##### Returns `boolean` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/functions/registerFragmentExtensions.md description: >- Legacy setup function that registers the fragment and fragment-array schema extensions on a `SchemaService` to support migrating off ModelFragments. --- # registerFragmentExtensions() ```ts function registerFragmentExtensions(schema: SchemaService): void; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/instance-initializers/fragment-extensions.ts:17](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/instance-initializers/fragment-extensions.ts#L17) Registers the [FragmentExtension](../variables/FragmentExtension.md)/[FragmentArrayExtension](../variables/FragmentArrayExtension.md) schema extensions on the given `SchemaService`, enabling ModelFragments migration support. ## Parameters ### schema `SchemaService` ## Returns `void` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/functions/withArrayDefaults.md description: >- Legacy ModelFragments migration helper that builds an `array` schema field preconfigured with the `ember-object`, `ember-array-like`, and `fragment-array` extensions. --- # withArrayDefaults() ```ts function withArrayDefaults(arrayName: ArrayName, primitiveType?: PrimitiveType): PrimitiveType extends undefined ? { kind: "array"; name: ArrayName; options: { arrayExtensions: string[]; }; type: "array"; } : { kind: "array"; name: ArrayName; options: { arrayExtensions: string[]; }; type: `array:${PrimitiveType}`; }; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/utilities/with-array-defaults.ts:11](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/utilities/with-array-defaults.ts#L11) Used as a helper to setup the relevant parts of an array schema and add extensions etc. ## Type Parameters ### ArrayName `ArrayName` *extends* `string` ### PrimitiveType `PrimitiveType` *extends* `string` ## Parameters ### arrayName `ArrayName` The name of the array ### primitiveType? `PrimitiveType` The primitive type of items in the array (optional) ## Returns `PrimitiveType` *extends* `undefined` ? { `kind`: `"array"`; `name`: `ArrayName`; `options`: { `arrayExtensions`: `string`\[]; }; `type`: `"array"`; } : { `kind`: `"array"`; `name`: `ArrayName`; `options`: { `arrayExtensions`: `string`\[]; }; `type`: `` `array:${PrimitiveType}` ``; } The schema for an array --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/functions/withFragmentArrayDefaults.md description: >- Legacy ModelFragments migration helper that builds a `schema-array` field of `fragment:` items, defaulting to an empty array, with Ember and fragment-array extensions. --- # withFragmentArrayDefaults() ```ts function withFragmentArrayDefaults(fragmentArrayType: FragmentArrayType, fragmentArrayName?: FragmentArrayName): { kind: "schema-array"; name: string; options: { arrayExtensions: string[]; defaultValue: boolean; }; type: `fragment:${string}`; }; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/utilities/with-fragment-array-defaults.ts:13](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/utilities/with-fragment-array-defaults.ts#L13) Used as a helper to setup the relevant parts of a fragment-array schema and add extensions etc. ## Type Parameters ### FragmentArrayType `FragmentArrayType` *extends* `string` ### FragmentArrayName `FragmentArrayName` *extends* `string` ## Parameters ### fragmentArrayType `FragmentArrayType` The type of the fragment-array ### fragmentArrayName? `FragmentArrayName` The name of the fragment-array ## Returns The schema for a fragment-array ### kind ```ts kind: "schema-array"; ``` This field is a `'schema-array'` field, an array of fragments. ### name ```ts name: string; ``` The name of the fragment-array field. ### options ```ts options: { arrayExtensions: string[]; defaultValue: boolean; }; ``` The schema options for this fragment-array field. #### options.arrayExtensions ```ts arrayExtensions: string[]; ``` The registered array-schema extensions to apply to this array. #### options.defaultValue ```ts defaultValue: boolean; ``` Whether the array defaults to a non-null empty array when unset. ### type ```ts type: `fragment:${string}`; ``` The resource type of the fragments contained in this array. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/functions/withFragmentDefaults.md description: >- Legacy ModelFragments migration helper that builds a `schema-object` field for a single `fragment:` type with the `ember-object` and `fragment` extensions. --- # withFragmentDefaults() ```ts function withFragmentDefaults(fragmentType: FragmentType, fragmentName?: FragmentName): { kind: "schema-object"; name: FragmentType | FragmentName; options: { objectExtensions: string[]; }; type: `fragment:${FragmentType}`; }; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/utilities/with-fragment-defaults.ts:11](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/utilities/with-fragment-defaults.ts#L11) Used as a helper to setup the relevant parts of a fragment schema and add extensions etc. ## Type Parameters ### FragmentType `FragmentType` *extends* `string` ### FragmentName `FragmentName` *extends* `string` ## Parameters ### fragmentType `FragmentType` The type of the fragment ### fragmentName? `FragmentName` The optional name of the fragment. If not provided, it will default to the fragmentType. ## Returns The schema for a fragment ### kind ```ts kind: "schema-object"; ``` This field is a `'schema-object'` field, a single fragment. ### name ```ts name: FragmentType | FragmentName; ``` The name of the fragment field. ### options ```ts options: { objectExtensions: string[]; }; ``` The schema options for this fragment field. #### options.objectExtensions ```ts objectExtensions: string[]; ``` The registered object-schema extensions to apply to this fragment. ### type ```ts type: `fragment:${FragmentType}`; ``` The resource type of the fragment. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/functions/withLegacy.md description: >- Legacy ModelFragments migration helper that completes a legacy resource schema with an `id` identity, `Model` defaults, and the `ember-object` and `fragment` extensions. --- # withLegacy() ```ts function withLegacy(schema: WithPartial): ResourceSchema; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/utilities/with-legacy.ts:16](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/utilities/with-legacy.ts#L16) Used as a helper to setup the relevant parts of a legacy resource schema migrated from `Model`, applying the `ember-object` and `fragment` object extensions and a default `@id` identity field. ## Parameters ### schema [`WithPartial`](../../../core/types/utils/types/WithPartial.md)<[`LegacyResourceSchema`](../../../core/types/schema/fields/types/LegacyResourceSchema.md), `"identity"` | `"legacy"`> the partial legacy resource schema to complete ## Returns [`ResourceSchema`](../../../core/types/schema/fields/types/ResourceSchema.md) the completed resource schema --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments.md description: >- Legacy helpers for migrating ember-data-model-fragments to WarpDrive schemas, including `withLegacy`, `withFragmentDefaults` and the `Fragment` and `FragmentArray` extensions. --- ## Classes * [Fragment](classes/Fragment.md) * [FragmentArray](classes/FragmentArray.md) ## Variables * [FragmentArrayExtension](variables/FragmentArrayExtension.md) * [FragmentExtension](variables/FragmentExtension.md) * [modelFor](variables/modelFor.md) ## Functions * [registerFragmentExtensions](functions/registerFragmentExtensions.md) * [withArrayDefaults](functions/withArrayDefaults.md) * [withFragmentArrayDefaults](functions/withFragmentArrayDefaults.md) * [withFragmentDefaults](functions/withFragmentDefaults.md) * [withLegacy](functions/withLegacy.md) ## Types * [WithFragment](types/WithFragment.md) * [WithFragmentArray](types/WithFragmentArray.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/types/WithFragment.md description: >- Legacy type for a reactive object migrated from a `ModelFragments` fragment, adding the `EmberObject` and `Fragment` APIs to it. --- # WithFragment\ ```ts type WithFragment = T & WithEmberObject & Fragment; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/index.ts:12](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/index.ts#L12) Adds the classic `EmberObject` API (via [WithEmberObject](../../compat/extensions/types/WithEmberObject.md)) and the [Fragment](../classes/Fragment.md) API to the type of a migrated single-fragment resource. ## Type Parameters ### T `T` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/types/WithFragmentArray.md description: >- Legacy type for a reactive array migrated from a `ModelFragments` fragment array, adding Ember array methods and the `FragmentArray` API to it. --- # WithFragmentArray\ ```ts type WithFragmentArray = T & WithArrayLike & FragmentArray; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/index.ts:20](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/index.ts#L20) Adds Ember's classic array-like API (via [WithArrayLike](../../compat/extensions/types/WithArrayLike.md)) and the [FragmentArray](../classes/FragmentArray.md) API to the type of a migrated fragment-array resource. ## Type Parameters ### T `T` *extends* [`Fragment`](../classes/Fragment.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/variables/FragmentArrayExtension.md description: >- Legacy schema extension named `fragment-array` that adds the `FragmentArray` API to reactive arrays migrated from `ModelFragments`. --- # FragmentArrayExtension ```ts const FragmentArrayExtension: { features: typeof FragmentArray; kind: "array"; name: "fragment-array"; }; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts:101](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment-array.ts#L101) A schema extension that adds the [FragmentArray](../classes/FragmentArray.md) API to migrated `ModelFragments` array resources. ## Type Declaration ### features ```ts features: typeof FragmentArray; ``` The features ([FragmentArray](../classes/FragmentArray.md)) added by this extension. ### kind ```ts kind: "array"; ``` This extension applies to `'array'` schemas. ### name ```ts name: "fragment-array"; ``` The registered name of this extension. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/variables/FragmentExtension.md description: >- Legacy schema extension named `fragment` that adds the `Fragment` API to reactive objects migrated from `ModelFragments`. --- # FragmentExtension ```ts const FragmentExtension: { features: typeof Fragment; kind: "object"; name: "fragment"; }; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts:79](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/extensions/fragment.ts#L79) A schema extension that adds the [Fragment](../classes/Fragment.md) API to migrated `ModelFragments` object resources. ## Type Declaration ### features ```ts features: typeof Fragment; ``` The features ([Fragment](../classes/Fragment.md)) added by this extension. ### kind ```ts kind: "object"; ``` This extension applies to `'object'` schemas. ### name ```ts name: "fragment"; ``` The registered name of this extension. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model-fragments/variables/modelFor.md description: >- Legacy `store.modelFor` fallback that returns a schema-backed `ShimModelClass` for a type when ModelFragments support is on and no `Model` class exists. --- # modelFor ```ts const modelFor: typeof fragmentsModelFor = fragmentsModelFor; ``` Defined in: [warp-drive-packages/legacy/src/model-fragments/hooks/model-for.ts:142](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model-fragments/hooks/model-for.ts#L142) The `modelFor` fallback used to construct a `ShimModelClass` schema for a type when ModelFragments support is enabled and no real `Model` subclass is registered for that type. --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/model/classes/Model.md description: >- Legacy base class whose subclasses both define a resource type's schema with `attr`, `belongsTo` and `hasMany` and serve as its reactive record. --- # Model Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:91](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L91) **`No Inherit Doc`** **`Legacy`** Base class from which Models can be defined. ::: code-group ```js [app/models/user.js] import { Model, attr, belongsTo, hasMany } from '@warp-drive/legacy/model'; export default class User extends Model { @attr name; @attr('number') age; @hasMany('post', { async: true, inverse: null }) posts; @belongsTo('group', { async: false, inverse: 'users' }) group; } ``` ```ts [app/models/user.ts] import { Model, attr, belongsTo, hasMany, type AsyncHasMany } from '@warp-drive/legacy/model'; import type { NumberTransform } from '@ember-data/serializer/transform'; import type Group from './group'; import type Post from './post'; export default class User extends Model { @attr declare name: string; @attr('number') declare age: number; @hasMany('post', { async: true, inverse: null }) declare posts: AsyncHasMany; @belongsTo('group', { async: false, inverse: 'users' }) declare group: Group | null; } ``` ::: Models both define the schema for a resource type and provide the class to use as the reactive object for data of resource of that type. ## Extends * `EmberObject` ## Implements * `MinimalLegacyRecord` ## Methods ### belongsTo() ```ts belongsTo(this: T, prop: K & K extends _MaybeBelongsToFields ? K : never): BelongsToReference; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:370](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L370) Get the reference for the specified belongsTo relationship. For instance, given the following model ```js [app/models/blog-post.js] import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class BlogPost extends Model { @belongsTo('user', { async: true, inverse: null }) author; } ``` Then the reference for the author relationship would be retrieved from a record instance like so: ```js blogPost.belongsTo('author'); ``` A `BelongsToReference` is a low-level API that allows access and manipulation of a belongsTo relationship. It is especially useful when you're dealing with `async` relationships as it allows synchronous access to the relationship data if loaded, as well as APIs for loading, reloading the data or accessing available information without triggering a load. It may also be useful when using `sync` relationships that need to be loaded/reloaded with more precise timing than marking the relationship as `async` and relying on autofetch would have allowed. However,keep in mind that marking a relationship as `async: false` will introduce bugs into your application if the data is not always guaranteed to be available by the time the relationship is accessed. Ergo, it is recommended when using this approach to utilize `links` for unloaded relationship state instead of identifiers. Reference APIs are entangled with the relationship's underlying state, thus any getters or cached properties that utilize these will properly invalidate if the relationship state changes. References are "stable", meaning that multiple calls to retrieve the reference for a given relationship will always return the same HasManyReference. #### Type Parameters ##### T `T` *extends* `Model` ##### K `K` *extends* `string` #### Parameters ##### this `T` ##### prop `K` & `K` *extends* `_MaybeBelongsToFields`<`T`> ? `K` : `never` the name of the relationship #### Returns `BelongsToReference`<`T`, `K`> reference for this relationship *** ### changedAttributes() ```ts changedAttributes(this: T): ChangedAttributesHash; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:219](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L219) Returns an object, whose keys are changed properties, and value is an \[oldProp, newProp] array. The array represents the diff of the canonical state with the local state of the model. Note: if the model is created locally, the canonical state is empty since the adapter hasn't acknowledged the attributes yet: Example ```js [app/models/mascot.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class MascotModel extends Model { @attr('string') name; @attr('boolean', { defaultValue: false }) isAdmin; } ``` ```javascript let mascot = store.createRecord('mascot'); mascot.changedAttributes(); // {} mascot.set('name', 'Tomster'); mascot.changedAttributes(); // { name: [undefined, 'Tomster'] } mascot.set('isAdmin', true); mascot.changedAttributes(); // { isAdmin: [undefined, true], name: [undefined, 'Tomster'] } mascot.save().then(function() { mascot.changedAttributes(); // {} mascot.set('isAdmin', false); mascot.changedAttributes(); // { isAdmin: [true, false] } }); ``` #### Type Parameters ##### T `T` *extends* `MinimalLegacyRecord` #### Parameters ##### this `T` #### Returns `ChangedAttributesHash` an object, whose keys are changed properties, and value is an \[oldProp, newProp] array. *** ### deleteRecord() ```ts deleteRecord(this: T): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:454](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L454) Marks the record as deleted but does not save it. You must call `save` afterwards if you want to persist it. You might use this method if you want to allow the user to still `rollbackAttributes()` after a delete was made. Example ```js import Component from '@glimmer/component'; export default class extends Component { softDelete = () => { this.args.model.deleteRecord(); } confirm = () => { this.args.model.save(); } undo = () => { this.args.model.rollbackAttributes(); } } ``` #### Type Parameters ##### T `T` *extends* `MinimalLegacyRecord` #### Parameters ##### this `T` #### Returns `void` *** ### destroyRecord() ```ts destroyRecord(this: T, options?: Record): Promise; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:164](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L164) Same as `deleteRecord`, but saves the record immediately. Example ```js import Component from '@glimmer/component'; export default class extends Component { delete = () => { this.args.model.destroyRecord().then(function() { this.transitionToRoute('model.index'); }); } } ``` If you pass an object on the `adapterOptions` property of the options argument it will be passed to your adapter via the snapshot ```js record.destroyRecord({ adapterOptions: { subscribe: false } }); ``` ```js [app/adapters/post.js] import MyCustomAdapter from './custom-adapter'; export default class PostAdapter extends MyCustomAdapter { deleteRecord(store, type, snapshot) { if (snapshot.adapterOptions.subscribe) { // ... } // ... } } ``` #### Type Parameters ##### T `T` *extends* `MinimalLegacyRecord` #### Parameters ##### this `T` ##### options? [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<`Model`> a promise that will be resolved when the adapter returns successfully or rejected if the adapter returns with an error. *** ### eachAttribute() ```ts eachAttribute(callback: (this: | NoInfer | undefined, key: string, meta: LegacyAttributeField) => void, binding?: T): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1069](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1069) Iterates over the attributes defined on this record's class, calling `callback` for each one. See [the static eachAttribute](#eachattribute-1). #### Type Parameters ##### T `T` #### Parameters ##### callback (`this`: | [`NoInfer`](https://www.typescriptlang.org/docs/handbook/utility-types.html#noinfertype)<`T`> | `undefined`, `key`: `string`, `meta`: [`LegacyAttributeField`](../../../core/types/schema/fields/types/LegacyAttributeField.md)) => `void` the callback to invoke ##### binding? `T` the value to which the callback's `this` should be bound #### Returns `void` *** ### eachRelationship() ```ts eachRelationship(callback: (this: | NoInfer | undefined, key: string, meta: LegacyRelationshipField) => void, binding?: T): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1040](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1040) Given a callback, iterates over each of the relationships in the model, invoking the callback with the name of each relationship and its relationship descriptor. The callback method you provide should have the following signature (all parameters are optional): ```javascript function(name, descriptor); ``` * `name` the name of the current property in the iteration * `descriptor` the meta object that describes this relationship The relationship descriptor argument is an object with the following properties. * **name** String the name of this relationship on the Model * **kind** String "hasMany" or "belongsTo" * **options** Object the original options hash passed when the relationship was declared * **parentType** Model the type of the Model that owns this relationship * **type** String the type name of the related Model Note that in addition to a callback, you can also pass an optional target object that will be set as `this` on the context. Example ```js [app/serializers/application.js] import JSONSerializer from '@ember-data/serializer/json'; export default class ApplicationSerializer extends JSONSerializer { serialize(record, options) { let json = {}; record.eachRelationship(function(name, descriptor) { if (descriptor.kind === 'hasMany') { let serializedHasManyName = name.toUpperCase() + '_IDS'; json[serializedHasManyName] = record.get(name).map(r => r.id); } }); return json; } } ``` #### Type Parameters ##### T `T` #### Parameters ##### callback (`this`: | [`NoInfer`](https://www.typescriptlang.org/docs/handbook/utility-types.html#noinfertype)<`T`> | `undefined`, `key`: `string`, `meta`: [`LegacyRelationshipField`](../../../core/types/schema/fields/types/LegacyRelationshipField.md)) => `void` the callback to invoke ##### binding? `T` the value to which the callback's `this` should be bound #### Returns `void` *** ### hasMany() ```ts hasMany(this: T, prop: K): HasManyReference; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:424](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L424) Get the reference for the specified hasMany relationship. For instance, given the following model ```js [app/models/blog-post.js] import { Model, hasMany } from '@warp-drive/legacy/model'; export default class BlogPost extends Model { @hasMany('comment', { async: true, inverse: null }) comments; } ``` Then the reference for the comments relationship would be retrieved from a record instance like so: ```js blogPost.hasMany('comments'); ``` A `HasManyReference` is a low-level API that allows access and manipulation of a hasMany relationship. It is especially useful when you are dealing with `async` relationships as it allows synchronous access to the relationship data if loaded, as well as APIs for loading, reloading the data or accessing available information without triggering a load. It may also be useful when using `sync` relationships with `@ember-data/model` that need to be loaded/reloaded with more precise timing than marking the relationship as `async` and relying on autofetch would have allowed. However,keep in mind that marking a relationship as `async: false` will introduce bugs into your application if the data is not always guaranteed to be available by the time the relationship is accessed. Ergo, it is recommended when using this approach to utilize `links` for unloaded relationship state instead of identifiers. Reference APIs are entangled with the relationship's underlying state, thus any getters or cached properties that utilize these will properly invalidate if the relationship state changes. References are "stable", meaning that multiple calls to retrieve the reference for a given relationship will always return the same HasManyReference. #### Type Parameters ##### T `T` *extends* `MinimalLegacyRecord` ##### K `K` *extends* `string` #### Parameters ##### this `T` ##### prop `K` the name of the relationship #### Returns `HasManyReference`<`T`, `K`> reference for this relationship *** ### inverseFor() ```ts inverseFor(name: string): | LegacyRelationshipField | null; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1058](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1058) Returns the inverse relationship schema for the given relationship name, if one exists. See [the static inverseFor](#inversefor-1). #### Parameters ##### name `string` #### Returns | [`LegacyRelationshipField`](../../../core/types/schema/fields/types/LegacyRelationshipField.md) | `null` *** ### notifyPropertyChange() ```ts notifyPropertyChange(prop: string): this; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:974](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L974) Convenience method to call `propertyWillChange` and `propertyDidChange` in succession. Notify the observer system that a property has just changed. Sometimes you need to change a value directly or indirectly without actually calling `get()` or `set()` on it. In this case, you can use this method instead. Calling this method will notify all observers that the property has potentially changed value. #### Parameters ##### prop `string` #### Returns `this` #### Method notifyPropertyChange *** ### relationshipFor() ```ts relationshipFor(name: string): | LegacyRelationshipField | undefined; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1050](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1050) Returns the relationship schema for the given relationship name, if any. #### Parameters ##### name `string` #### Returns | [`LegacyRelationshipField`](../../../core/types/schema/fields/types/LegacyRelationshipField.md) | `undefined` *** ### reload() ```ts reload(this: T, options?: Record): Promise; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:314](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L314) Reload the record from the adapter. This will only work if the record has already finished loading. Example ```js import Component from '@glimmer/component'; export default class extends Component { async reload = () => { await this.args.model.reload(); // do something with the reloaded model } } ``` #### Type Parameters ##### T `T` *extends* `MinimalLegacyRecord` #### Parameters ##### this `T` ##### options? [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> optional, may include `adapterOptions` hash which will be passed to adapter request #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<`T`> a promise that will be resolved with the record when the adapter returns successfully or rejected if the adapter returns with an error. *** ### rollbackAttributes() ```ts rollbackAttributes(this: T): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:238](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L238) If the model `hasDirtyAttributes` this function will discard any unsaved changes. If the model `isNew` it will be removed from the store. Example ```javascript record.name; // 'Untitled Document' record.set('name', 'Doc 1'); record.name; // 'Doc 1' record.rollbackAttributes(); record.name; // 'Untitled Document' ``` #### Type Parameters ##### T `T` *extends* `MinimalLegacyRecord` #### Parameters ##### this `T` #### Returns `void` *** ### ~~save()~~ ```ts save(this: T, options?: Record): Promise; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:286](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L286) Save the record and persist any changes to the record to an external source via the adapter. Example ```javascript record.set('name', 'Tomster'); record.save().then(function() { // Success callback }, function() { // Error callback }); ``` If you pass an object using the `adapterOptions` property of the options argument it will be passed to your adapter via the snapshot. ```js record.save({ adapterOptions: { subscribe: false } }); ``` ```js [app/adapters/post.js] import MyCustomAdapter from './custom-adapter'; export default class PostAdapter extends MyCustomAdapter { updateRecord(store, type, snapshot) { if (snapshot.adapterOptions.subscribe) { // ... } // ... } } ``` #### Type Parameters ##### T `T` *extends* `MinimalLegacyRecord` #### Parameters ##### this `T` ##### options? [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<`Model`> a promise that will be resolved when the adapter returns successfully or rejected if the adapter returns with an error. #### Deprecated use Store.request instead *** ### serialize() ```ts serialize(this: T, options?: Record): unknown; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:120](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L120) Create a JSON representation of the record, using the serialization strategy of the store's adapter. `serialize` takes an optional hash as a parameter, currently supported options are: * `includeId`: `true` if the record's ID should be included in the JSON representation. #### Type Parameters ##### T `T` *extends* `MinimalLegacyRecord` #### Parameters ##### this `T` ##### options? [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns `unknown` an object whose values are primitive JSON values only *** ### toString() ```ts toString(): string; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:855](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L855) Returns a string representation which attempts to provide more information than Javascript's `toString` typically does, in a generic way for all Ember objects. ```javascript import EmberObject from '@ember/object'; const Person = EmberObject.extend(); person = Person.create(); person.toString(); //=> "" ``` If the object's class is not defined on an Ember namespace, it will indicate it is a subclass of the registered superclass: ```javascript const Student = Person.extend(); let student = Student.create(); student.toString(); //=> "<(subclass of Person):ember1025>" ``` If the method `toStringExtension` is defined, its return value will be included in the output. ```javascript const Teacher = Person.extend({ toStringExtension() { return this.get('fullName'); } }); teacher = Teacher.create(); teacher.toString(); //=> "" ``` #### Returns `string` string representation #### Method toString *** ### unloadRecord() ```ts unloadRecord(this: T): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:172](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L172) Unloads the record from the store. This will not send a delete request to your server, it just unloads the record from memory. #### Type Parameters ##### T `T` *extends* `MinimalLegacyRecord` #### Parameters ##### this `T` #### Returns `void` *** ### eachAttribute() ```ts static eachAttribute(callback: (this: T | undefined, key: MaybeAttrFields, attribute: LegacyAttributeField) => void, binding?: T): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1822](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1822) Iterates through the attributes of the model, calling the passed function on each attribute. The callback method you provide should have the following signature (all parameters are optional): ```javascript function(name, meta); ``` * `name` the name of the current property in the iteration * `meta` the meta object for the attribute property in the iteration Note that in addition to a callback, you can also pass an optional target object that will be set as `this` on the context. Example ```javascript import { Model, attr } from '@warp-drive/legacy/model'; class PersonModel extends Model { @attr('string') firstName; @attr('string') lastName; @attr('date') birthday; } PersonModel.eachAttribute(function(name, meta) { // do thing }); // prints: // firstName {type: "string", kind: 'attribute', options: Object, parentType: function, name: "firstName"} // lastName {type: "string", kind: 'attribute', options: Object, parentType: function, name: "lastName"} // birthday {type: "date", kind: 'attribute', options: Object, parentType: function, name: "birthday"} ``` #### Type Parameters ##### T `T` ##### Schema `Schema` *extends* `Model` #### Parameters ##### callback (`this`: `T` | `undefined`, `key`: `MaybeAttrFields`<`Schema`>, `attribute`: [`LegacyAttributeField`](../../../core/types/schema/fields/types/LegacyAttributeField.md)) => `void` The callback to execute ##### binding? `T` \[optional] the value to which the callback's `this` should be bound #### Returns `void` *** ### eachRelatedType() ```ts static eachRelatedType(callback: (this: T | undefined, type: string) => void, binding?: T): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1620](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1620) Given a callback, iterates over each of the types related to a model, invoking the callback with the related type's class. Each type will be returned just once, regardless of how many different relationships it has with a model. #### Type Parameters ##### T `T` #### Parameters ##### callback (`this`: `T` | `undefined`, `type`: `string`) => `void` the callback to invoke ##### binding? `T` the value to which the callback's `this` should be bound #### Returns `void` *** ### eachRelationship() ```ts static eachRelationship(callback: (this: T | undefined, key: MaybeRelationshipFields, relationship: LegacyRelationshipField) => void, binding?: T): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1592](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1592) Given a callback, iterates over each of the relationships in the model, invoking the callback with the name of each relationship and its relationship descriptor. #### Type Parameters ##### T `T` ##### Schema `Schema` *extends* `Model` #### Parameters ##### callback (`this`: `T` | `undefined`, `key`: `MaybeRelationshipFields`<`Schema`>, `relationship`: [`LegacyRelationshipField`](../../../core/types/schema/fields/types/LegacyRelationshipField.md)) => `void` the callback to invoke ##### binding? `T` the value to which the callback's `this` should be bound #### Returns `void` *** ### eachTransformedAttribute() ```ts static eachTransformedAttribute(callback: (this: T | undefined, key: Exclude, type: string) => void, binding?: T): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1879](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1879) Iterates through the transformedAttributes of the model, calling the passed function on each attribute. Note the callback will not be called for any attributes that do not have an transformation type. The callback method you provide should have the following signature (all parameters are optional): ```javascript function(name, type); ``` * `name` the name of the current property in the iteration * `type` a string containing the name of the type of transformed applied to the attribute Note that in addition to a callback, you can also pass an optional target object that will be set as `this` on the context. Example ```javascript import { Model, attr } from '@warp-drive/legacy/model'; let Person = Model.extend({ firstName: attr(), lastName: attr('string'), birthday: attr('date') }); Person.eachTransformedAttribute(function(name, type) { // do thing }); // prints: // lastName string // birthday date ``` #### Type Parameters ##### T `T` ##### Schema `Schema` *extends* `Model` #### Parameters ##### callback (`this`: `T` | `undefined`, `key`: [`Exclude`](https://www.typescriptlang.org/docs/handbook/utility-types.html#excludeuniontype-excludedmembers)\, `type`: `string`) => `void` The callback to execute ##### binding? `T` \[optional] the value to which the callback's `this` should be bound #### Returns `void` *** ### inverseFor() ```ts static inverseFor(name: string, store: Store$1): | LegacyRelationshipField | null; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1206](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1206) Find the relationship which is the inverse of the one asked for. For example, if you define models like this: ```js [app/models/post.js] import { Model, hasMany } from '@warp-drive/legacy/model'; export default class PostModel extends Model { @hasMany('message') comments; } ``` ```js [app/models/message.js] import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class MessageModel extends Model { @belongsTo('post') owner; } ``` ```js store.modelFor('post').inverseFor('comments', store) // { type: 'message', name: 'owner', kind: 'belongsTo' } store.modelFor('message').inverseFor('owner', store) // { type: 'post', name: 'comments', kind: 'hasMany' } ``` #### Parameters ##### name `string` the name of the relationship ##### store `Store$1` #### Returns | [`LegacyRelationshipField`](../../../core/types/schema/fields/types/LegacyRelationshipField.md) | `null` the inverse relationship, or null *** ### toString() ```ts static toString(): string; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1898](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1898) Returns the name of the model class. #### Returns `string` *** ### typeForRelationship() ```ts static typeForRelationship(name: string, store: Store$1): ModelSchema | undefined; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1152](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1152) For a given relationship name, returns the model type of the relationship. For example, if you define a model like this: ```js [app/models/post.js] import { Model, hasMany } from '@warp-drive/legacy/model'; export default class PostModel extends Model { @hasMany('comment') comments; } ``` Calling `store.modelFor('post').typeForRelationship('comments', store)` will return `Comment`. #### Parameters ##### name `string` the name of the relationship ##### store `Store$1` an instance of Store #### Returns `ModelSchema`<`unknown`> | `undefined` the type of the relationship, or undefined ## Properties ### isReloading ```ts isReloading: boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:802](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L802) If `true` the store is attempting to reload the record from the adapter. Example ```javascript record.isReloading; // false record.reload(); record.isReloading; // true ``` *** ### store ```ts store: Store$1; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:96](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L96) The store service instance which created this record instance *** ### modelName ```ts static modelName: string; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1113](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1113) Represents the model's class name as a string. This can be used to look up the model's class name through `Store`'s modelFor method. `modelName` is generated for you by WarpDrive. It will be a lowercased, dasherized string. For example: ```javascript store.modelFor('post').modelName; // 'post' store.modelFor('blog-post').modelName; // 'blog-post' ``` The most common place you'll want to access `modelName` is in your serializer's `payloadKeyFromModelName` method. For example, to change payload keys to underscore (instead of dasherized), you might use the following code: ```javascript import RESTSerializer from '@ember-data/serializer/rest'; import { underscore } from '/utils/string-utils'; export default const PostSerializer = RESTSerializer.extend({ payloadKeyFromModelName(modelName) { return underscore(modelName); } }); ``` ### adapterError #### Get Signature ```ts get adapterError(): unknown; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:955](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L955) This property holds the `AdapterError` object with which last adapter operation was rejected. ##### Returns `unknown` #### Set Signature ```ts set adapterError(v: unknown): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:961](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L961) `adapterError` is read-only and cannot be set directly. ##### Parameters ###### v `unknown` ##### Returns `void` *** ### currentState #### Set Signature ```ts set currentState(_v: RecordState): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:880](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L880) `currentState` is read-only and cannot be set directly. ##### Parameters ###### \_v `RecordState` ##### Returns `void` *** ### dirtyType #### Get Signature ```ts get dirtyType(): "" | "updated" | "deleted" | "created"; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:755](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L755) If the record is in the dirty state this property will report what kind of change has caused it to move into the dirty state. Possible values are: * `created` The record has been created by the client and not yet saved to the adapter. * `updated` The record has been updated by the client and not yet saved to the adapter. * `deleted` The record has been deleted by the client and not yet saved to the adapter. Example ```javascript let record = store.createRecord('model'); record.dirtyType; // 'created' ``` ##### Returns `""` | `"updated"` | `"deleted"` | `"created"` *** ### errors #### Get Signature ```ts get errors(): Errors; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:942](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L942) When the record is in the `invalid` state this object will contain any errors returned by the adapter. When present the errors hash contains keys corresponding to the invalid property names and values which are arrays of Javascript objects with two keys: * `message` A string containing the error message from the backend * `attribute` The name of the property associated with this error message ```javascript record.errors.length; // 0 record.set('foo', 'invalid value'); record.save().catch(function() { record.errors.foo; // [{message: 'foo should be a number.', attribute: 'foo'}] }); ``` The `errors` property is useful for displaying error messages to the user. ```handlebars {{#each @model.errors.username as |error|}}
{{error.message}}
{{/each}} {{#each @model.errors.email as |error|}}
{{error.message}}
{{/each}} ``` You can also access the special `messages` property on the error object to get an array of all the error strings. ```handlebars {{#each @model.errors.messages as |message|}}
{{message}}
{{/each}} ``` ##### Returns `Errors` *** ### hasDirtyAttributes #### Get Signature ```ts get hasDirtyAttributes(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:630](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L630) If this property is `true` the record is in the `dirty` state. The record has local changes that have not yet been saved by the adapter. This includes records that have been created (but not yet saved) or deleted. Example ```javascript let record = store.createRecord('model'); record.hasDirtyAttributes; // true const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' })); model.hasDirtyAttributes; // false model.foo = 'some value'; model.hasDirtyAttributes; // true ``` ##### Returns `boolean` *** ### id #### Get Signature ```ts get id(): string | null; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:822](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L822) All ember models have an id property. This is an identifier managed by an external source. These are always coerced to be strings before being used internally. Note when declaring the attributes for a model it is an error to declare an id attribute. ```javascript let record = store.createRecord('model'); record.id; // null const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' })); model.id; // '1' ``` ##### Returns `string` | `null` #### Set Signature ```ts set id(id: string | null): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:839](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L839) Assigns the resource's primary key. Typically only used internally when a client-created record is assigned an id upon being saved. ##### Parameters ###### id `string` | `null` ##### Returns `void` *** ### isDeleted #### Get Signature ```ts get isDeleted(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:695](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L695) If this property is `true` the record is in the `deleted` state and has been marked for deletion. When `isDeleted` is true and `hasDirtyAttributes` is true, the record is deleted locally but the deletion was not yet persisted. When `isSaving` is true, the change is in-flight. When both `hasDirtyAttributes` and `isSaving` are false, the change has persisted. Example ```javascript let record = store.createRecord('model'); record.isDeleted; // false record.deleteRecord(); // Locally deleted record.isDeleted; // true record.hasDirtyAttributes; // true record.isSaving; // false // Persisting the deletion let promise = record.save(); record.isDeleted; // true record.isSaving; // true // Deletion Persisted promise.then(function() { record.isDeleted; // true record.isSaving; // false record.hasDirtyAttributes; // false }); ``` ##### Returns `boolean` *** ### isEmpty #### Get Signature ```ts get isEmpty(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:567](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L567) If this property is `true` the record is in the `empty` state. Empty is the first state all records enter after they have been created. Most records created by the store will quickly transition to the `loading` state if data needs to be fetched from the server or the `created` state if the record is created on the client. A record can also enter the empty state if the adapter is unable to locate the record. ##### Returns `boolean` *** ### isError #### Get Signature ```ts get isError(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:777](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L777) If `true` the adapter reported that it was unable to save local changes to the backend for any reason other than a server-side validation error. Example ```javascript record.isError; // false record.set('foo', 'valid value'); record.save().then(null, function() { record.isError; // true }); ``` ##### Returns `boolean` #### Set Signature ```ts set isError(v: boolean): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:783](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L783) `isError` is read-only and cannot be set directly. ##### Parameters ###### v `boolean` ##### Returns `void` *** ### isLoaded #### Get Signature ```ts get isLoaded(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:603](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L603) If this property is `true` the record is in the `loaded` state. A record enters this state when its data is populated. Most of a record's lifecycle is spent inside substates of the `loaded` state. Example ```javascript let record = store.createRecord('model'); record.isLoaded; // true const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' })); model.isLoaded; ``` ##### Returns `boolean` *** ### isLoading #### Get Signature ```ts get isLoading(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:580](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L580) If this property is `true` the record is in the `loading` state. A record enters this state when the store asks the adapter for its data. It remains in this state until the adapter provides the requested data. ##### Returns `boolean` *** ### isNew #### Get Signature ```ts get isNew(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:719](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L719) If this property is `true` the record is in the `new` state. A record will be in the `new` state when it has been created on the client and the adapter has not yet report that it was successfully saved. Example ```javascript let record = store.createRecord('model'); record.isNew; // true record.save().then(function(model) { model.isNew; // false }); ``` ##### Returns `boolean` *** ### isSaving #### Get Signature ```ts get isSaving(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:655](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L655) If this property is `true` the record is in the `saving` state. A record enters the saving state when `save` is called, but the adapter has not yet acknowledged that the changes have been persisted to the backend. Example ```javascript let record = store.createRecord('model'); record.isSaving; // false let promise = record.save(); record.isSaving; // true promise.then(function() { record.isSaving; // false }); ``` ##### Returns `boolean` *** ### isValid #### Get Signature ```ts get isValid(): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:732](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L732) If this property is `true` the record is in the `valid` state. A record will be in the `valid` state when the adapter did not report any server-side validation failures. ##### Returns `boolean` *** ### attributes #### Get Signature ```ts get static attributes(): Map; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1702](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1702) A map whose keys are the attributes of the model (properties described by attr) and whose values are the meta object for the property. Example ```js [app/models/person.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class PersonModel extends Model { @attr('string') firstName; @attr('string') lastName; @attr('date') birthday; } ``` ```javascript import Person from 'app/models/person' let attributes = Person.attributes attributes.forEach(function(meta, name) { // do thing }); // prints: // firstName {type: "string", kind: 'attribute', options: Object, parentType: function, name: "firstName"} // lastName {type: "string", kind: 'attribute', options: Object, parentType: function, name: "lastName"} // birthday {type: "date", kind: 'attribute', options: Object, parentType: function, name: "birthday"} ``` ##### Returns [`Map`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)<`string`, [`LegacyAttributeField`](../../../core/types/schema/fields/types/LegacyAttributeField.md)> *** ### fields #### Get Signature ```ts get static fields(): Map; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1565](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1565) A map whose keys are the fields of the model and whose values are strings describing the kind of the field. A model's fields are the union of all of its attributes and relationships. For example: ```js [app/models/blog.js] import { Model, attr, belongsTo, hasMany } from '@warp-drive/legacy/model'; export default class BlogModel extends Model { @hasMany('user') users; @belongsTo('user') owner; @hasMany('post') posts; @attr('string') title; } ``` ```js import Blog from 'app/models/blog' let fields = Blog.fields; fields.forEach(function(kind, field) { // do thing }); // prints: // users, hasMany // owner, belongsTo // posts, hasMany // title, attribute ``` ##### Returns [`Map`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)<`string`, `"belongsTo"` | `"hasMany"` | `"attribute"`> *** ### inverseMap #### Get Signature ```ts get static inverseMap(): Record; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1167](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1167) A cache of resolved inverse relationships by name, populated lazily by [inverseFor](#inversefor-1). ##### Returns [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, | [`LegacyRelationshipField`](../../../core/types/schema/fields/types/LegacyRelationshipField.md) | `null`> *** ### relatedTypes #### Get Signature ```ts get static relatedTypes(): string[]; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1417](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1417) An array of types directly related to a model. Each type will be included once, regardless of the number of relationships it has with the model. For example, given a model with this definition: ```js [app/models/blog.js] import { Model, belongsTo, hasMany } from '@warp-drive/legacy/model'; export default class BlogModel extends Model { @hasMany('user') users; @belongsTo('user') owner; @hasMany('post') posts; } ``` This property would contain the following: ```javascript import Blog from 'app/models/blog'; let relatedTypes = Blog.relatedTypes'); //=> ['user', 'post'] ``` ##### Returns `string`\[] *** ### relationshipNames #### Get Signature ```ts get static relationshipNames(): { belongsTo: string[]; hasMany: string[]; }; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1359](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1359) A hash containing lists of the model's relationships, grouped by the relationship kind. For example, given a model with this definition: ```js [app/models/blog.js] import { Model, belongsTo, hasMany } from '@warp-drive/legacy/model'; export default class BlogModel extends Model { @hasMany('user') users; @belongsTo('user') owner; @hasMany('post') posts; } ``` This property would contain the following: ```javascript import Blog from 'app/models/blog'; let relationshipNames = Blog.relationshipNames; relationshipNames.hasMany; //=> ['users', 'posts'] relationshipNames.belongsTo; //=> ['owner'] ``` ##### Returns ###### belongsTo ```ts belongsTo: string[]; ``` the names of the model's `belongsTo` relationships ###### hasMany ```ts hasMany: string[]; ``` the names of the model's `hasMany` relationships *** ### relationships #### Get Signature ```ts get static relationships(): Map; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1305](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1305) The model's relationships as a map, keyed on the type of the relationship. The value of each entry is an array containing a descriptor for each relationship with that type, describing the name of the relationship as well as the type. For example, given the following model definition: ```js [app/models/blog.js] import { Model, belongsTo, hasMany } from '@warp-drive/legacy/model'; export default class BlogModel extends Model { @hasMany('user') users; @belongsTo('user') owner; @hasMany('post') posts; } ``` This computed property would return a map describing these relationships, like this: ```javascript import Blog from 'app/models/blog'; import User from 'app/models/user'; import Post from 'app/models/post'; let relationships = Blog.relationships; relationships.user; //=> [ { name: 'users', kind: 'hasMany' }, // { name: 'owner', kind: 'belongsTo' } ] relationships.post; //=> [ { name: 'posts', kind: 'hasMany' } ] ``` ##### Returns [`Map`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)<`string`, [`LegacyRelationshipField`](../../../core/types/schema/fields/types/LegacyRelationshipField.md)\[]> *** ### relationshipsByName #### Get Signature ```ts get static relationshipsByName(): Map; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1476](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1476) A map whose keys are the relationships of a model and whose values are relationship descriptors. For example, given a model with this definition: ```js [app/models/blog.js] import { Model, belongsTo, hasMany } from '@warp-drive/legacy/model'; export default class BlogModel extends Model { @hasMany('user') users; @belongsTo('user') owner; @hasMany('post') posts; } ``` This property would contain the following: ```javascript import Blog from 'app/models/blog'; let relationshipsByName = Blog.relationshipsByName; relationshipsByName.users; //=> { name: 'users', kind: 'hasMany', type: 'user', options: Object } relationshipsByName.owner; //=> { name: 'owner', kind: 'belongsTo', type: 'user', options: Object } ``` ##### Returns [`Map`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)<`string`, [`LegacyRelationshipField`](../../../core/types/schema/fields/types/LegacyRelationshipField.md)> *** ### relationshipsObject #### Get Signature ```ts get static relationshipsObject(): Record; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1501](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1501) A hash of the model's relationship schemas keyed by relationship name. See also [relationshipsByName](#relationshipsbyname), which provides the same information as a `Map`. ##### Returns [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, [`LegacyRelationshipField`](../../../core/types/schema/fields/types/LegacyRelationshipField.md)> *** ### transformedAttributes #### Get Signature ```ts get static transformedAttributes(): Map; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1763](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1763) A map whose keys are the attributes of the model (properties described by attr) and whose values are type of transformation applied to each attribute. This map does not include any attributes that do not have an transformation type. Example ```js [app/models/person.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class PersonModel extends Model { @attr firstName; @attr('string') lastName; @attr('date') birthday; } ``` ```javascript import Person from 'app/models/person'; let transformedAttributes = Person.transformedAttributes transformedAttributes.forEach(function(field, type) { // do thing }); // prints: // lastName string // birthday date ``` ##### Returns [`Map`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)<`string`, `string`> --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/model/functions/attr.md description: >- Legacy `Model` decorator that declares an attribute field, optionally converted by a named transform and given a `defaultValue`. --- # attr() ```ts function attr(): DataDecorator; function attr(type: TypeFromInstance): DataDecorator; function attr(type: string): DataDecorator; function attr(options: AttrOptions): DataDecorator; function attr(type: TypeFromInstance, options?: OptionsFromInstance): DataDecorator; function attr(type: string, options?: AttrOptions< | object | unknown[] | PrimitiveValue> & object): DataDecorator; function attr( target: object, key: string | symbol, desc?: PropertyDescriptor ): void; ``` ## Call Signature ```ts function attr(): DataDecorator; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/attr.ts:295](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/attr.ts#L295) `attr` defines an attribute on a [Model](../classes/Model.md). By default, attributes are passed through as-is, however you can specify an optional type to have the value automatically transformed. WarpDrive ships with four basic transform types: `string`, `number`, `boolean` and `date`. You can define your own transforms by subclassing [Transform](../../serializer/transform/classes/Transform.md). Note that you cannot use `attr` to define an attribute of `id`. `attr` takes an optional hash as a second parameter, currently supported options are: * `defaultValue`: Pass a string or a function to be called to set the attribute to a default value if and only if the key is absent from the payload response. Example ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr('boolean', { defaultValue: false }) verified; } ``` Default value can also be a function. This is useful it you want to return a new object for each attribute. ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr({ defaultValue() { return {}; } }) settings; } ``` The `options` hash is passed as second argument to a transforms' `serialize` and `deserialize` method. This allows to configure a transformation and adapt the corresponding value, based on the config: ```js [app/models/post.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class PostModel extends Model { @attr('text', { uppercase: true }) text; } ``` ```js [app/transforms/text.js] export default class TextTransform { serialize(value, options) { if (options.uppercase) { return value.toUpperCase(); } return value; } deserialize(value) { return value; } static create() { return new this(); } } ``` ### Returns `DataDecorator` ## Call Signature ```ts function attr(type: TypeFromInstance): DataDecorator; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/attr.ts:296](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/attr.ts#L296) `attr` defines an attribute on a [Model](../classes/Model.md). By default, attributes are passed through as-is, however you can specify an optional type to have the value automatically transformed. WarpDrive ships with four basic transform types: `string`, `number`, `boolean` and `date`. You can define your own transforms by subclassing [Transform](../../serializer/transform/classes/Transform.md). Note that you cannot use `attr` to define an attribute of `id`. `attr` takes an optional hash as a second parameter, currently supported options are: * `defaultValue`: Pass a string or a function to be called to set the attribute to a default value if and only if the key is absent from the payload response. Example ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr('boolean', { defaultValue: false }) verified; } ``` Default value can also be a function. This is useful it you want to return a new object for each attribute. ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr({ defaultValue() { return {}; } }) settings; } ``` The `options` hash is passed as second argument to a transforms' `serialize` and `deserialize` method. This allows to configure a transformation and adapt the corresponding value, based on the config: ```js [app/models/post.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class PostModel extends Model { @attr('text', { uppercase: true }) text; } ``` ```js [app/transforms/text.js] export default class TextTransform { serialize(value, options) { if (options.uppercase) { return value.toUpperCase(); } return value; } deserialize(value) { return value; } static create() { return new this(); } } ``` ### Type Parameters #### T `T` ### Parameters #### type `TypeFromInstance`<`T`> the attribute type ### Returns `DataDecorator` ## Call Signature ```ts function attr(type: string): DataDecorator; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/attr.ts:297](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/attr.ts#L297) `attr` defines an attribute on a [Model](../classes/Model.md). By default, attributes are passed through as-is, however you can specify an optional type to have the value automatically transformed. WarpDrive ships with four basic transform types: `string`, `number`, `boolean` and `date`. You can define your own transforms by subclassing [Transform](../../serializer/transform/classes/Transform.md). Note that you cannot use `attr` to define an attribute of `id`. `attr` takes an optional hash as a second parameter, currently supported options are: * `defaultValue`: Pass a string or a function to be called to set the attribute to a default value if and only if the key is absent from the payload response. Example ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr('boolean', { defaultValue: false }) verified; } ``` Default value can also be a function. This is useful it you want to return a new object for each attribute. ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr({ defaultValue() { return {}; } }) settings; } ``` The `options` hash is passed as second argument to a transforms' `serialize` and `deserialize` method. This allows to configure a transformation and adapt the corresponding value, based on the config: ```js [app/models/post.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class PostModel extends Model { @attr('text', { uppercase: true }) text; } ``` ```js [app/transforms/text.js] export default class TextTransform { serialize(value, options) { if (options.uppercase) { return value.toUpperCase(); } return value; } deserialize(value) { return value; } static create() { return new this(); } } ``` ### Parameters #### type `string` the attribute type ### Returns `DataDecorator` ## Call Signature ```ts function attr(options: AttrOptions): DataDecorator; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/attr.ts:298](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/attr.ts#L298) `attr` defines an attribute on a [Model](../classes/Model.md). By default, attributes are passed through as-is, however you can specify an optional type to have the value automatically transformed. WarpDrive ships with four basic transform types: `string`, `number`, `boolean` and `date`. You can define your own transforms by subclassing [Transform](../../serializer/transform/classes/Transform.md). Note that you cannot use `attr` to define an attribute of `id`. `attr` takes an optional hash as a second parameter, currently supported options are: * `defaultValue`: Pass a string or a function to be called to set the attribute to a default value if and only if the key is absent from the payload response. Example ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr('boolean', { defaultValue: false }) verified; } ``` Default value can also be a function. This is useful it you want to return a new object for each attribute. ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr({ defaultValue() { return {}; } }) settings; } ``` The `options` hash is passed as second argument to a transforms' `serialize` and `deserialize` method. This allows to configure a transformation and adapt the corresponding value, based on the config: ```js [app/models/post.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class PostModel extends Model { @attr('text', { uppercase: true }) text; } ``` ```js [app/transforms/text.js] export default class TextTransform { serialize(value, options) { if (options.uppercase) { return value.toUpperCase(); } return value; } deserialize(value) { return value; } static create() { return new this(); } } ``` ### Parameters #### options `AttrOptions` a hash of options ### Returns `DataDecorator` ## Call Signature ```ts function attr(type: TypeFromInstance, options?: OptionsFromInstance): DataDecorator; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/attr.ts:299](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/attr.ts#L299) `attr` defines an attribute on a [Model](../classes/Model.md). By default, attributes are passed through as-is, however you can specify an optional type to have the value automatically transformed. WarpDrive ships with four basic transform types: `string`, `number`, `boolean` and `date`. You can define your own transforms by subclassing [Transform](../../serializer/transform/classes/Transform.md). Note that you cannot use `attr` to define an attribute of `id`. `attr` takes an optional hash as a second parameter, currently supported options are: * `defaultValue`: Pass a string or a function to be called to set the attribute to a default value if and only if the key is absent from the payload response. Example ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr('boolean', { defaultValue: false }) verified; } ``` Default value can also be a function. This is useful it you want to return a new object for each attribute. ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr({ defaultValue() { return {}; } }) settings; } ``` The `options` hash is passed as second argument to a transforms' `serialize` and `deserialize` method. This allows to configure a transformation and adapt the corresponding value, based on the config: ```js [app/models/post.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class PostModel extends Model { @attr('text', { uppercase: true }) text; } ``` ```js [app/transforms/text.js] export default class TextTransform { serialize(value, options) { if (options.uppercase) { return value.toUpperCase(); } return value; } deserialize(value) { return value; } static create() { return new this(); } } ``` ### Type Parameters #### T `T` ### Parameters #### type `TypeFromInstance`<`T`> the attribute type #### options? `OptionsFromInstance`<`T`> a hash of options ### Returns `DataDecorator` ## Call Signature ```ts function attr(type: string, options?: AttrOptions< | object | unknown[] | PrimitiveValue> & object): DataDecorator; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/attr.ts:300](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/attr.ts#L300) `attr` defines an attribute on a [Model](../classes/Model.md). By default, attributes are passed through as-is, however you can specify an optional type to have the value automatically transformed. WarpDrive ships with four basic transform types: `string`, `number`, `boolean` and `date`. You can define your own transforms by subclassing [Transform](../../serializer/transform/classes/Transform.md). Note that you cannot use `attr` to define an attribute of `id`. `attr` takes an optional hash as a second parameter, currently supported options are: * `defaultValue`: Pass a string or a function to be called to set the attribute to a default value if and only if the key is absent from the payload response. Example ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr('boolean', { defaultValue: false }) verified; } ``` Default value can also be a function. This is useful it you want to return a new object for each attribute. ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr({ defaultValue() { return {}; } }) settings; } ``` The `options` hash is passed as second argument to a transforms' `serialize` and `deserialize` method. This allows to configure a transformation and adapt the corresponding value, based on the config: ```js [app/models/post.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class PostModel extends Model { @attr('text', { uppercase: true }) text; } ``` ```js [app/transforms/text.js] export default class TextTransform { serialize(value, options) { if (options.uppercase) { return value.toUpperCase(); } return value; } deserialize(value) { return value; } static create() { return new this(); } } ``` ### Parameters #### type `string` the attribute type #### options? `AttrOptions`< | `object` | `unknown`\[] | [`PrimitiveValue`](../../../core/types/json/raw/types/PrimitiveValue.md)> & `object` a hash of options ### Returns `DataDecorator` ## Call Signature ```ts function attr( target: object, key: string | symbol, desc?: PropertyDescriptor ): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/attr.ts:301](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/attr.ts#L301) `attr` defines an attribute on a [Model](../classes/Model.md). By default, attributes are passed through as-is, however you can specify an optional type to have the value automatically transformed. WarpDrive ships with four basic transform types: `string`, `number`, `boolean` and `date`. You can define your own transforms by subclassing [Transform](../../serializer/transform/classes/Transform.md). Note that you cannot use `attr` to define an attribute of `id`. `attr` takes an optional hash as a second parameter, currently supported options are: * `defaultValue`: Pass a string or a function to be called to set the attribute to a default value if and only if the key is absent from the payload response. Example ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr('boolean', { defaultValue: false }) verified; } ``` Default value can also be a function. This is useful it you want to return a new object for each attribute. ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') username; @attr('string') email; @attr({ defaultValue() { return {}; } }) settings; } ``` The `options` hash is passed as second argument to a transforms' `serialize` and `deserialize` method. This allows to configure a transformation and adapt the corresponding value, based on the config: ```js [app/models/post.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class PostModel extends Model { @attr('text', { uppercase: true }) text; } ``` ```js [app/transforms/text.js] export default class TextTransform { serialize(value, options) { if (options.uppercase) { return value.toUpperCase(); } return value; } deserialize(value) { return value; } static create() { return new this(); } } ``` ### Parameters #### target `object` #### key `string` | `symbol` #### desc? `PropertyDescriptor` ### Returns `void` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/functions/belongsTo.md description: >- Legacy `Model` decorator that declares a to-one relationship to another resource type, configured with required `async` and `inverse` options. --- # belongsTo() ```ts function belongsTo(): never; function belongsTo(type: string): never; function belongsTo(type: TypeFromInstance>, options: RelationshipOptions): RelationshipDecorator; function belongsTo(type: string, options: RelationshipOptions): RelationshipDecorator; ``` ## Call Signature ```ts function belongsTo(): never; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/belongs-to.ts:300](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/belongs-to.ts#L300) `belongsTo` is used to define One-To-One and One-To-Many, and One-To-None relationships on a [Model](../classes/Model.md). `belongsTo` takes a configuration hash as a second parameter, currently supported options are: * `async`: (*required*) A boolean value used to declare whether this is a sync (false) or async (true) relationship. * `inverse`: (*required*) A string used to identify the inverse property on a related model, or `null`. * `polymorphic`: (*optional*) A boolean value to mark the relationship as polymorphic * `as`: (*optional*) A string used to declare the abstract type "this" record satisfies for polymorphism. ### Examples To declare a **one-to-many** (or many-to-many) relationship, use `belongsTo` in combination with `hasMany`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('post', { async: false, inverse: 'comments' }) post; } // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'post' }) comments; } ``` To declare a **one-to-one** relationship with managed inverses, use `belongsTo` for both sides: ```js // app/models/author.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Author extends Model { @belongsTo('address', { async: true, inverse: 'owner' }) address; } // app/models/address.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Address extends Model { @belongsTo('author', { async: true, inverse: 'address' }) owner; } ``` To declare a **one-to-one** relationship without managed inverses, use `belongsTo` for both sides with `null` as the inverse: ```js // app/models/author.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Author extends Model { @belongsTo('address', { async: true, inverse: null }) address; } // app/models/address.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Address extends Model { @belongsTo('author', { async: true, inverse: null }) owner; } ``` To declare a one-to-none relationship between two models, use `belongsTo` with inverse set to `null` on just one side:: ```js // app/models/person.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Person extends Model { @belongsTo('person', { async: false, inverse: null }) bestFriend; } ``` #### Sync vs Async Relationships WarpDrive fulfills relationships using resource data available in the cache. Sync relationships point directly to the known related resources. When a relationship is declared as async, if any of the known related resources have not been loaded, they will be fetched. The property on the record when accessed provides a promise that resolves once all resources are loaded. Async relationships may take advantage of links. On access, if the related link has not been loaded, or if any known resources are not available in the cache, the fresh state will be fetched using the link. In contrast to async relationship, accessing a sync relationship will error on access when any of the known related resources have not been loaded. If you are using `links` with sync relationships, you have to use the BelongsTo reference API to fetch or refresh related resources that aren't loaded. For instance, for a `bestFriend` relationship: ```js person.belongsTo('bestFriend').reload(); ``` #### Polymorphic Relationships To declare a polymorphic relationship, use `hasMany` with the `polymorphic` option set to `true`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('commentable', { async: false, inverse: 'comments', polymorphic: true }) parent; } ``` `'commentable'` here is referred to as the "abstract type" for the polymorphic relationship. Polymorphic relationships with `inverse: null` will accept any type of record as their content. Polymorphic relationships with `inverse` set to a string will only accept records with a matching inverse relationships declaring itself as satisfying the abstract type. Below, 'as' is used to declare the that 'post' record satisfies the abstract type 'commentable' for this relationship. ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'parent', as: 'commentable' }) comments; } ``` Note: every Model that declares an inverse to a polymorphic relationship must declare itself exactly the same. This is because polymorphism is based on structural traits. Polymorphic to polymorphic relationships are supported. Both sides of the relationship must be declared as polymorphic, and the `as` option must be used to declare the abstract type each record satisfies on both sides. ### Returns `never` ## Call Signature ```ts function belongsTo(type: string): never; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/belongs-to.ts:301](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/belongs-to.ts#L301) `belongsTo` is used to define One-To-One and One-To-Many, and One-To-None relationships on a [Model](../classes/Model.md). `belongsTo` takes a configuration hash as a second parameter, currently supported options are: * `async`: (*required*) A boolean value used to declare whether this is a sync (false) or async (true) relationship. * `inverse`: (*required*) A string used to identify the inverse property on a related model, or `null`. * `polymorphic`: (*optional*) A boolean value to mark the relationship as polymorphic * `as`: (*optional*) A string used to declare the abstract type "this" record satisfies for polymorphism. ### Examples To declare a **one-to-many** (or many-to-many) relationship, use `belongsTo` in combination with `hasMany`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('post', { async: false, inverse: 'comments' }) post; } // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'post' }) comments; } ``` To declare a **one-to-one** relationship with managed inverses, use `belongsTo` for both sides: ```js // app/models/author.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Author extends Model { @belongsTo('address', { async: true, inverse: 'owner' }) address; } // app/models/address.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Address extends Model { @belongsTo('author', { async: true, inverse: 'address' }) owner; } ``` To declare a **one-to-one** relationship without managed inverses, use `belongsTo` for both sides with `null` as the inverse: ```js // app/models/author.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Author extends Model { @belongsTo('address', { async: true, inverse: null }) address; } // app/models/address.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Address extends Model { @belongsTo('author', { async: true, inverse: null }) owner; } ``` To declare a one-to-none relationship between two models, use `belongsTo` with inverse set to `null` on just one side:: ```js // app/models/person.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Person extends Model { @belongsTo('person', { async: false, inverse: null }) bestFriend; } ``` #### Sync vs Async Relationships WarpDrive fulfills relationships using resource data available in the cache. Sync relationships point directly to the known related resources. When a relationship is declared as async, if any of the known related resources have not been loaded, they will be fetched. The property on the record when accessed provides a promise that resolves once all resources are loaded. Async relationships may take advantage of links. On access, if the related link has not been loaded, or if any known resources are not available in the cache, the fresh state will be fetched using the link. In contrast to async relationship, accessing a sync relationship will error on access when any of the known related resources have not been loaded. If you are using `links` with sync relationships, you have to use the BelongsTo reference API to fetch or refresh related resources that aren't loaded. For instance, for a `bestFriend` relationship: ```js person.belongsTo('bestFriend').reload(); ``` #### Polymorphic Relationships To declare a polymorphic relationship, use `hasMany` with the `polymorphic` option set to `true`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('commentable', { async: false, inverse: 'comments', polymorphic: true }) parent; } ``` `'commentable'` here is referred to as the "abstract type" for the polymorphic relationship. Polymorphic relationships with `inverse: null` will accept any type of record as their content. Polymorphic relationships with `inverse` set to a string will only accept records with a matching inverse relationships declaring itself as satisfying the abstract type. Below, 'as' is used to declare the that 'post' record satisfies the abstract type 'commentable' for this relationship. ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'parent', as: 'commentable' }) comments; } ``` Note: every Model that declares an inverse to a polymorphic relationship must declare itself exactly the same. This is because polymorphism is based on structural traits. Polymorphic to polymorphic relationships are supported. Both sides of the relationship must be declared as polymorphic, and the `as` option must be used to declare the abstract type each record satisfies on both sides. ### Parameters #### type `string` the name of the related resource ### Returns `never` ## Call Signature ```ts function belongsTo(type: TypeFromInstance>, options: RelationshipOptions): RelationshipDecorator; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/belongs-to.ts:302](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/belongs-to.ts#L302) `belongsTo` is used to define One-To-One and One-To-Many, and One-To-None relationships on a [Model](../classes/Model.md). `belongsTo` takes a configuration hash as a second parameter, currently supported options are: * `async`: (*required*) A boolean value used to declare whether this is a sync (false) or async (true) relationship. * `inverse`: (*required*) A string used to identify the inverse property on a related model, or `null`. * `polymorphic`: (*optional*) A boolean value to mark the relationship as polymorphic * `as`: (*optional*) A string used to declare the abstract type "this" record satisfies for polymorphism. ### Examples To declare a **one-to-many** (or many-to-many) relationship, use `belongsTo` in combination with `hasMany`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('post', { async: false, inverse: 'comments' }) post; } // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'post' }) comments; } ``` To declare a **one-to-one** relationship with managed inverses, use `belongsTo` for both sides: ```js // app/models/author.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Author extends Model { @belongsTo('address', { async: true, inverse: 'owner' }) address; } // app/models/address.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Address extends Model { @belongsTo('author', { async: true, inverse: 'address' }) owner; } ``` To declare a **one-to-one** relationship without managed inverses, use `belongsTo` for both sides with `null` as the inverse: ```js // app/models/author.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Author extends Model { @belongsTo('address', { async: true, inverse: null }) address; } // app/models/address.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Address extends Model { @belongsTo('author', { async: true, inverse: null }) owner; } ``` To declare a one-to-none relationship between two models, use `belongsTo` with inverse set to `null` on just one side:: ```js // app/models/person.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Person extends Model { @belongsTo('person', { async: false, inverse: null }) bestFriend; } ``` #### Sync vs Async Relationships WarpDrive fulfills relationships using resource data available in the cache. Sync relationships point directly to the known related resources. When a relationship is declared as async, if any of the known related resources have not been loaded, they will be fetched. The property on the record when accessed provides a promise that resolves once all resources are loaded. Async relationships may take advantage of links. On access, if the related link has not been loaded, or if any known resources are not available in the cache, the fresh state will be fetched using the link. In contrast to async relationship, accessing a sync relationship will error on access when any of the known related resources have not been loaded. If you are using `links` with sync relationships, you have to use the BelongsTo reference API to fetch or refresh related resources that aren't loaded. For instance, for a `bestFriend` relationship: ```js person.belongsTo('bestFriend').reload(); ``` #### Polymorphic Relationships To declare a polymorphic relationship, use `hasMany` with the `polymorphic` option set to `true`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('commentable', { async: false, inverse: 'comments', polymorphic: true }) parent; } ``` `'commentable'` here is referred to as the "abstract type" for the polymorphic relationship. Polymorphic relationships with `inverse: null` will accept any type of record as their content. Polymorphic relationships with `inverse` set to a string will only accept records with a matching inverse relationships declaring itself as satisfying the abstract type. Below, 'as' is used to declare the that 'post' record satisfies the abstract type 'commentable' for this relationship. ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'parent', as: 'commentable' }) comments; } ``` Note: every Model that declares an inverse to a polymorphic relationship must declare itself exactly the same. This is because polymorphism is based on structural traits. Polymorphic to polymorphic relationships are supported. Both sides of the relationship must be declared as polymorphic, and the `as` option must be used to declare the abstract type each record satisfies on both sides. ### Type Parameters #### T `T` ### Parameters #### type [`TypeFromInstance`](../../../core/types/record/types/TypeFromInstance.md)<[`Exclude`](https://www.typescriptlang.org/docs/handbook/utility-types.html#excludeuniontype-excludedmembers)<`T`, `null`>> the name of the related resource #### options `RelationshipOptions`<`T`, `boolean`> a hash of options ### Returns `RelationshipDecorator`<`T`> ## Call Signature ```ts function belongsTo(type: string, options: RelationshipOptions): RelationshipDecorator; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/belongs-to.ts:310](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/belongs-to.ts#L310) `belongsTo` is used to define One-To-One and One-To-Many, and One-To-None relationships on a [Model](../classes/Model.md). `belongsTo` takes a configuration hash as a second parameter, currently supported options are: * `async`: (*required*) A boolean value used to declare whether this is a sync (false) or async (true) relationship. * `inverse`: (*required*) A string used to identify the inverse property on a related model, or `null`. * `polymorphic`: (*optional*) A boolean value to mark the relationship as polymorphic * `as`: (*optional*) A string used to declare the abstract type "this" record satisfies for polymorphism. ### Examples To declare a **one-to-many** (or many-to-many) relationship, use `belongsTo` in combination with `hasMany`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('post', { async: false, inverse: 'comments' }) post; } // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'post' }) comments; } ``` To declare a **one-to-one** relationship with managed inverses, use `belongsTo` for both sides: ```js // app/models/author.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Author extends Model { @belongsTo('address', { async: true, inverse: 'owner' }) address; } // app/models/address.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Address extends Model { @belongsTo('author', { async: true, inverse: 'address' }) owner; } ``` To declare a **one-to-one** relationship without managed inverses, use `belongsTo` for both sides with `null` as the inverse: ```js // app/models/author.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Author extends Model { @belongsTo('address', { async: true, inverse: null }) address; } // app/models/address.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Address extends Model { @belongsTo('author', { async: true, inverse: null }) owner; } ``` To declare a one-to-none relationship between two models, use `belongsTo` with inverse set to `null` on just one side:: ```js // app/models/person.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Person extends Model { @belongsTo('person', { async: false, inverse: null }) bestFriend; } ``` #### Sync vs Async Relationships WarpDrive fulfills relationships using resource data available in the cache. Sync relationships point directly to the known related resources. When a relationship is declared as async, if any of the known related resources have not been loaded, they will be fetched. The property on the record when accessed provides a promise that resolves once all resources are loaded. Async relationships may take advantage of links. On access, if the related link has not been loaded, or if any known resources are not available in the cache, the fresh state will be fetched using the link. In contrast to async relationship, accessing a sync relationship will error on access when any of the known related resources have not been loaded. If you are using `links` with sync relationships, you have to use the BelongsTo reference API to fetch or refresh related resources that aren't loaded. For instance, for a `bestFriend` relationship: ```js person.belongsTo('bestFriend').reload(); ``` #### Polymorphic Relationships To declare a polymorphic relationship, use `hasMany` with the `polymorphic` option set to `true`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('commentable', { async: false, inverse: 'comments', polymorphic: true }) parent; } ``` `'commentable'` here is referred to as the "abstract type" for the polymorphic relationship. Polymorphic relationships with `inverse: null` will accept any type of record as their content. Polymorphic relationships with `inverse` set to a string will only accept records with a matching inverse relationships declaring itself as satisfying the abstract type. Below, 'as' is used to declare the that 'post' record satisfies the abstract type 'commentable' for this relationship. ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'parent', as: 'commentable' }) comments; } ``` Note: every Model that declares an inverse to a polymorphic relationship must declare itself exactly the same. This is because polymorphism is based on structural traits. Polymorphic to polymorphic relationships are supported. Both sides of the relationship must be declared as polymorphic, and the `as` option must be used to declare the abstract type each record satisfies on both sides. ### Parameters #### type `string` the name of the related resource #### options `RelationshipOptions`<`unknown`, `boolean`> a hash of options ### Returns `RelationshipDecorator`<`unknown`> --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/functions/buildSchema.md description: >- Legacy factory for a schema service that reads resource schemas from an app's `Model` classes, returned from the store's `createSchemaService` hook. --- # buildSchema() ```ts function buildSchema(store: Store$1): SchemaService; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/schema-provider.ts:276](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/schema-provider.ts#L276) The `createSchemaService` implementation for use with `Model`. Pass the result of this to your store's `createSchemaService` method when configuring the store to use `Model` for schema information. ## Parameters ### store `Store$1` ## Returns `SchemaService` --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/model/functions/hasMany.md description: >- Legacy `Model` decorator that declares a to-many relationship to another resource type, configured with required `async` and `inverse` options. --- # hasMany() ```ts function hasMany(): never; function hasMany(type: string): never; function hasMany(type: TypeFromInstance>, options: RelationshipOptions): RelationshipDecorator; function hasMany(type: string, options: RelationshipOptions): RelationshipDecorator; ``` ## Call Signature ```ts function hasMany(): never; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/has-many.ts:255](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/has-many.ts#L255) `hasMany` is used to define Many-To-One and Many-To-Many, and Many-To-None relationships on a [Model](../classes/Model.md). `hasMany` takes a configuration hash as a second parameter, currently supported options are: * `async`: (*required*) A boolean value used to declare whether this is a sync (false) or async (true) relationship. * `inverse`: (*required*) A string used to identify the inverse property on a related model, or `null`. * `polymorphic`: (*optional*) A boolean value to mark the relationship as polymorphic * `as`: (*optional*) A string used to declare the abstract type "this" record satisfies for polymorphism. ### Examples To declare a **many-to-one** (or one-to-many) relationship, use `belongsTo` in combination with `hasMany`: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'post' }) comments; } // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('post', { async: false, inverse: 'comments' }) post; } ``` To declare a **many-to-many** relationship with managed inverses, use `hasMany` for both sides: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('tag', { async: true, inverse: 'posts' }) tags; } // app/models/tag.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Tag extends Model { @hasMany('post', { async: true, inverse: 'tags' }) posts; } ``` To declare a **many-to-many** relationship without managed inverses, use `hasMany` for both sides with `null` as the inverse: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('tag', { async: true, inverse: null }) tags; } // app/models/tag.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Tag extends Model { @hasMany('post', { async: true, inverse: null }) posts; } ``` To declare a many-to-none relationship between two models, use `hasMany` with inverse set to `null` on just one side:: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('category', { async: true, inverse: null }) categories; } ``` #### Sync vs Async Relationships WarpDrive fulfills relationships using resource data available in the cache. Sync relationships point directly to the known related resources. When a relationship is declared as async, if any of the known related resources have not been loaded, they will be fetched. The property on the record when accessed provides a promise that resolves once all resources are loaded. Async relationships may take advantage of links. On access, if the related link has not been loaded, or if any known resources are not available in the cache, the fresh state will be fetched using the link. In contrast to async relationship, accessing a sync relationship will error on access when any of the known related resources have not been loaded. If you are using `links` with sync relationships, you have to use the HasMany reference API to fetch or refresh related resources that aren't loaded. For instance, for a `comments` relationship: ```js post.hasMany('comments').reload(); ``` #### Polymorphic Relationships To declare a polymorphic relationship, use `hasMany` with the `polymorphic` option set to `true`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('commentable', { async: false, inverse: 'comments', polymorphic: true }) parent; } ``` `'commentable'` here is referred to as the "abstract type" for the polymorphic relationship. Polymorphic relationships with `inverse: null` will accept any type of record as their content. Polymorphic relationships with `inverse` set to a string will only accept records with a matching inverse relationships declaring itself as satisfying the abstract type. Below, 'as' is used to declare the that 'post' record satisfies the abstract type 'commentable' for this relationship. ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'parent', as: 'commentable' }) comments; } ``` Note: every Model that declares an inverse to a polymorphic relationship must declare itself exactly the same. This is because polymorphism is based on structural traits. Polymorphic to polymorphic relationships are supported. Both sides of the relationship must be declared as polymorphic, and the `as` option must be used to declare the abstract type each record satisfies on both sides. ### Returns `never` ## Call Signature ```ts function hasMany(type: string): never; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/has-many.ts:256](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/has-many.ts#L256) `hasMany` is used to define Many-To-One and Many-To-Many, and Many-To-None relationships on a [Model](../classes/Model.md). `hasMany` takes a configuration hash as a second parameter, currently supported options are: * `async`: (*required*) A boolean value used to declare whether this is a sync (false) or async (true) relationship. * `inverse`: (*required*) A string used to identify the inverse property on a related model, or `null`. * `polymorphic`: (*optional*) A boolean value to mark the relationship as polymorphic * `as`: (*optional*) A string used to declare the abstract type "this" record satisfies for polymorphism. ### Examples To declare a **many-to-one** (or one-to-many) relationship, use `belongsTo` in combination with `hasMany`: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'post' }) comments; } // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('post', { async: false, inverse: 'comments' }) post; } ``` To declare a **many-to-many** relationship with managed inverses, use `hasMany` for both sides: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('tag', { async: true, inverse: 'posts' }) tags; } // app/models/tag.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Tag extends Model { @hasMany('post', { async: true, inverse: 'tags' }) posts; } ``` To declare a **many-to-many** relationship without managed inverses, use `hasMany` for both sides with `null` as the inverse: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('tag', { async: true, inverse: null }) tags; } // app/models/tag.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Tag extends Model { @hasMany('post', { async: true, inverse: null }) posts; } ``` To declare a many-to-none relationship between two models, use `hasMany` with inverse set to `null` on just one side:: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('category', { async: true, inverse: null }) categories; } ``` #### Sync vs Async Relationships WarpDrive fulfills relationships using resource data available in the cache. Sync relationships point directly to the known related resources. When a relationship is declared as async, if any of the known related resources have not been loaded, they will be fetched. The property on the record when accessed provides a promise that resolves once all resources are loaded. Async relationships may take advantage of links. On access, if the related link has not been loaded, or if any known resources are not available in the cache, the fresh state will be fetched using the link. In contrast to async relationship, accessing a sync relationship will error on access when any of the known related resources have not been loaded. If you are using `links` with sync relationships, you have to use the HasMany reference API to fetch or refresh related resources that aren't loaded. For instance, for a `comments` relationship: ```js post.hasMany('comments').reload(); ``` #### Polymorphic Relationships To declare a polymorphic relationship, use `hasMany` with the `polymorphic` option set to `true`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('commentable', { async: false, inverse: 'comments', polymorphic: true }) parent; } ``` `'commentable'` here is referred to as the "abstract type" for the polymorphic relationship. Polymorphic relationships with `inverse: null` will accept any type of record as their content. Polymorphic relationships with `inverse` set to a string will only accept records with a matching inverse relationships declaring itself as satisfying the abstract type. Below, 'as' is used to declare the that 'post' record satisfies the abstract type 'commentable' for this relationship. ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'parent', as: 'commentable' }) comments; } ``` Note: every Model that declares an inverse to a polymorphic relationship must declare itself exactly the same. This is because polymorphism is based on structural traits. Polymorphic to polymorphic relationships are supported. Both sides of the relationship must be declared as polymorphic, and the `as` option must be used to declare the abstract type each record satisfies on both sides. ### Parameters #### type `string` the name of the related resource ### Returns `never` ## Call Signature ```ts function hasMany(type: TypeFromInstance>, options: RelationshipOptions): RelationshipDecorator; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/has-many.ts:257](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/has-many.ts#L257) `hasMany` is used to define Many-To-One and Many-To-Many, and Many-To-None relationships on a [Model](../classes/Model.md). `hasMany` takes a configuration hash as a second parameter, currently supported options are: * `async`: (*required*) A boolean value used to declare whether this is a sync (false) or async (true) relationship. * `inverse`: (*required*) A string used to identify the inverse property on a related model, or `null`. * `polymorphic`: (*optional*) A boolean value to mark the relationship as polymorphic * `as`: (*optional*) A string used to declare the abstract type "this" record satisfies for polymorphism. ### Examples To declare a **many-to-one** (or one-to-many) relationship, use `belongsTo` in combination with `hasMany`: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'post' }) comments; } // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('post', { async: false, inverse: 'comments' }) post; } ``` To declare a **many-to-many** relationship with managed inverses, use `hasMany` for both sides: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('tag', { async: true, inverse: 'posts' }) tags; } // app/models/tag.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Tag extends Model { @hasMany('post', { async: true, inverse: 'tags' }) posts; } ``` To declare a **many-to-many** relationship without managed inverses, use `hasMany` for both sides with `null` as the inverse: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('tag', { async: true, inverse: null }) tags; } // app/models/tag.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Tag extends Model { @hasMany('post', { async: true, inverse: null }) posts; } ``` To declare a many-to-none relationship between two models, use `hasMany` with inverse set to `null` on just one side:: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('category', { async: true, inverse: null }) categories; } ``` #### Sync vs Async Relationships WarpDrive fulfills relationships using resource data available in the cache. Sync relationships point directly to the known related resources. When a relationship is declared as async, if any of the known related resources have not been loaded, they will be fetched. The property on the record when accessed provides a promise that resolves once all resources are loaded. Async relationships may take advantage of links. On access, if the related link has not been loaded, or if any known resources are not available in the cache, the fresh state will be fetched using the link. In contrast to async relationship, accessing a sync relationship will error on access when any of the known related resources have not been loaded. If you are using `links` with sync relationships, you have to use the HasMany reference API to fetch or refresh related resources that aren't loaded. For instance, for a `comments` relationship: ```js post.hasMany('comments').reload(); ``` #### Polymorphic Relationships To declare a polymorphic relationship, use `hasMany` with the `polymorphic` option set to `true`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('commentable', { async: false, inverse: 'comments', polymorphic: true }) parent; } ``` `'commentable'` here is referred to as the "abstract type" for the polymorphic relationship. Polymorphic relationships with `inverse: null` will accept any type of record as their content. Polymorphic relationships with `inverse` set to a string will only accept records with a matching inverse relationships declaring itself as satisfying the abstract type. Below, 'as' is used to declare the that 'post' record satisfies the abstract type 'commentable' for this relationship. ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'parent', as: 'commentable' }) comments; } ``` Note: every Model that declares an inverse to a polymorphic relationship must declare itself exactly the same. This is because polymorphism is based on structural traits. Polymorphic to polymorphic relationships are supported. Both sides of the relationship must be declared as polymorphic, and the `as` option must be used to declare the abstract type each record satisfies on both sides. ### Type Parameters #### T `T` ### Parameters #### type [`TypeFromInstance`](../../../core/types/record/types/TypeFromInstance.md)<`NoNull`<`T`>> the name of the related resource #### options `RelationshipOptions`<`T`, `boolean`> a hash of options ### Returns `RelationshipDecorator`<`T`> ## Call Signature ```ts function hasMany(type: string, options: RelationshipOptions): RelationshipDecorator; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/has-many.ts:265](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/has-many.ts#L265) `hasMany` is used to define Many-To-One and Many-To-Many, and Many-To-None relationships on a [Model](../classes/Model.md). `hasMany` takes a configuration hash as a second parameter, currently supported options are: * `async`: (*required*) A boolean value used to declare whether this is a sync (false) or async (true) relationship. * `inverse`: (*required*) A string used to identify the inverse property on a related model, or `null`. * `polymorphic`: (*optional*) A boolean value to mark the relationship as polymorphic * `as`: (*optional*) A string used to declare the abstract type "this" record satisfies for polymorphism. ### Examples To declare a **many-to-one** (or one-to-many) relationship, use `belongsTo` in combination with `hasMany`: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'post' }) comments; } // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('post', { async: false, inverse: 'comments' }) post; } ``` To declare a **many-to-many** relationship with managed inverses, use `hasMany` for both sides: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('tag', { async: true, inverse: 'posts' }) tags; } // app/models/tag.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Tag extends Model { @hasMany('post', { async: true, inverse: 'tags' }) posts; } ``` To declare a **many-to-many** relationship without managed inverses, use `hasMany` for both sides with `null` as the inverse: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('tag', { async: true, inverse: null }) tags; } // app/models/tag.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Tag extends Model { @hasMany('post', { async: true, inverse: null }) posts; } ``` To declare a many-to-none relationship between two models, use `hasMany` with inverse set to `null` on just one side:: ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('category', { async: true, inverse: null }) categories; } ``` #### Sync vs Async Relationships WarpDrive fulfills relationships using resource data available in the cache. Sync relationships point directly to the known related resources. When a relationship is declared as async, if any of the known related resources have not been loaded, they will be fetched. The property on the record when accessed provides a promise that resolves once all resources are loaded. Async relationships may take advantage of links. On access, if the related link has not been loaded, or if any known resources are not available in the cache, the fresh state will be fetched using the link. In contrast to async relationship, accessing a sync relationship will error on access when any of the known related resources have not been loaded. If you are using `links` with sync relationships, you have to use the HasMany reference API to fetch or refresh related resources that aren't loaded. For instance, for a `comments` relationship: ```js post.hasMany('comments').reload(); ``` #### Polymorphic Relationships To declare a polymorphic relationship, use `hasMany` with the `polymorphic` option set to `true`: ```js // app/models/comment.js import { Model, belongsTo } from '@warp-drive/legacy/model'; export default class Comment extends Model { @belongsTo('commentable', { async: false, inverse: 'comments', polymorphic: true }) parent; } ``` `'commentable'` here is referred to as the "abstract type" for the polymorphic relationship. Polymorphic relationships with `inverse: null` will accept any type of record as their content. Polymorphic relationships with `inverse` set to a string will only accept records with a matching inverse relationships declaring itself as satisfying the abstract type. Below, 'as' is used to declare the that 'post' record satisfies the abstract type 'commentable' for this relationship. ```js // app/models/post.js import { Model, hasMany } from '@warp-drive/legacy/model'; export default class Post extends Model { @hasMany('comment', { async: false, inverse: 'parent', as: 'commentable' }) comments; } ``` Note: every Model that declares an inverse to a polymorphic relationship must declare itself exactly the same. This is because polymorphism is based on structural traits. Polymorphic to polymorphic relationships are supported. Both sides of the relationship must be declared as polymorphic, and the `as` option must be used to declare the abstract type each record satisfies on both sides. ### Parameters #### type `string` the name of the related resource #### options `RelationshipOptions`<`unknown`, `boolean`> a hash of options ### Returns `RelationshipDecorator`<`unknown`> --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/functions/instantiateRecord.md description: >- Legacy store hook that creates a `Model` instance for a resource key using the `Model` class registered for its type. --- # instantiateRecord() ```ts function instantiateRecord( this: Store$1, identifier: ResourceKey, createRecordArgs?: { [key: string]: unknown; } ): Model; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/hooks.ts:23](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/hooks.ts#L23) The `instantiateRecord` hook implementation for use with `Model`. Pass this to your store's `instantiateRecord` method when configuring the store to use `Model` for schema/record instantiation. ## Parameters ### this `Store$1` ### identifier [`ResourceKey`](../../../core/types/identifier/types/ResourceKey.md) ### createRecordArgs? ## Returns [`Model`](../classes/Model.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/functions/modelFor.md description: >- Legacy `store.modelFor` implementation that returns the `Model` class registered for a resource type, if there is one. --- # modelFor() ```ts function modelFor(type: TypeFromInstance): void | typeof Model; function modelFor(type: string): void | typeof Model; ``` ## Call Signature ```ts function modelFor(type: TypeFromInstance): void | typeof Model; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/hooks.ts:76](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/hooks.ts#L76) The `modelFor` implementation for use with `Model`, exposed on the store as `store.modelFor(type)` when the store is configured to use `Model`. Returns the `Model` subclass registered for the given type, if any. ### Type Parameters #### T `T` ### Parameters #### type [`TypeFromInstance`](../../../core/types/record/types/TypeFromInstance.md)<`T`> ### Returns `void` | *typeof* [`Model`](../classes/Model.md) ## Call Signature ```ts function modelFor(type: string): void | typeof Model; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/hooks.ts:82](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/hooks.ts#L82) Overload accepting a raw type string instead of a typed record instance. ### Parameters #### type `string` ### Returns `void` | *typeof* [`Model`](../classes/Model.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/functions/restoreDeprecatedModelRequestBehaviors.md description: >- Legacy opt-in that restores the pre-`RequestManager` `save`, `destroyRecord`, `reload`, and `isReloading` onto a `Model` class without deprecation warnings. --- # restoreDeprecatedModelRequestBehaviors() ```ts function restoreDeprecatedModelRequestBehaviors(ModelKlass: typeof Model): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/model.ts:1957](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/model.ts#L1957) Restores the pre-`RequestManager` implementations of `save`, `destroyRecord`, and `reload` onto the given `Model` subclass, for apps that have not yet migrated off of the deprecated `ENABLE_LEGACY_REQUEST_METHODS` behaviors. ## Parameters ### ModelKlass *typeof* [`Model`](../classes/Model.md) ## Returns `void` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/functions/teardownRecord.md description: >- Legacy store hook that destroys a `Model` instance when the store releases its record. --- # teardownRecord() ```ts function teardownRecord(record: Model): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/hooks.ts:59](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/hooks.ts#L59) The `teardownRecord` hook implementation for use with `Model`. Pass this to your store's `teardownRecord` method when configuring the store to use `Model` for schema/record instantiation. ## Parameters ### record [`Model`](../classes/Model.md) ## Returns `void` --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/model.md description: >- Legacy `Model` base class and `attr`, `belongsTo`, and `hasMany` decorators that define resource schemas as classes and present records. --- This package provides a Presentation Model for resource data in an WarpDrive Cache. Models are defined as classes extending from `import Model from '@warp-drive/legacy/model';` and the attributes and relationships on these classes are parsed at runtime to supply static "schema" to WarpDrive's SchemaService. Resource data for individual resources fetched from your API is presented to the UI via instances of the `Model`s you define. An instantiated `Model` is referred to as a `record`. When we refer to the `ModelClass` as opposed to a `Model` or `Record` we are referring specifically to the class definition and the static schema methods present on it. When we refer to a `record` we refer to a specific class instance presenting the resource data for a given `type` and `id`. ### Why It's Legacy The `Model` pattern uses class inheritance and decorators to define your data schema: * The `attr`, `belongsTo` and `hasMany` decorators are Ember computed properties, and the schema is read at runtime by walking each Model class's computed properties. * Every record is an instance of its own `Model` subclass, and `Model` extends `EmberObject`, which ties your data layer to Ember and its object model. ### Modern Alternative Use **schemas** with `@warp-drive/core`. Modern ***Warp*Drive**: * defines each resource's schema as a plain object, a `ResourceSchema`, registered with the store's SchemaService, with no class or decorators * presents every resource type through one record implementation, [ReactiveResource](/api/@warp-drive/core/reactive/types/ReactiveResource), which reads its fields from the registered schema * shares fields across schemas with [traits](/guides/the-manual/schemas/traits), and adds memoized read-only fields with [derivations](/guides/the-manual/schemas/derivations) and value conversions with [transformations](/guides/the-manual/schemas/transformations), instead of inheritance * works in any framework ***Warp*Drive** supports, since `@warp-drive/core` has no runtime dependency on Ember (see [Installation](/guides/installation/)) For guidance on migrating from Model classes to schemas, see the [Schemas Guide](/guides/the-manual/schemas/) and the [Migration Guide](/upgrading/v5/). ### Defining a Model ```js [app/models/person.js] import Model, { attr, belongsTo, hasMany } from '@warp-drive/legacy/model'; export default class PersonModel extends Model { @attr name; @belongsTo('pet', { inverse: 'owners', async: false }) dog; @hasMany('person', { inverse: 'friends', async: true }) friends; } ``` ### modelName convention By convention, the name of a given model (its `type`) matches the name of the file in the `app/models` folder and should be lowercase, singular and dasherized. ## Classes ### default Renames and re-exports [Model](classes/Model.md) ## Functions * [attr](functions/attr.md) * [belongsTo](functions/belongsTo.md) * [buildSchema](functions/buildSchema.md) * [hasMany](functions/hasMany.md) * [instantiateRecord](functions/instantiateRecord.md) * [modelFor](functions/modelFor.md) * [restoreDeprecatedModelRequestBehaviors](functions/restoreDeprecatedModelRequestBehaviors.md) * [teardownRecord](functions/teardownRecord.md) ## Types * [AsyncHasMany](types/AsyncHasMany.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/migration-support/classes/DelegatingSchemaService.md description: >- Legacy schema service that serves a resource's schema from the primary service when it has one, and otherwise from its `Model` class, for incremental migration. --- # DelegatingSchemaService Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:573](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L573) See the class documentation above for usage. ## Implements * `SchemaService` ## Constructors ### Constructor ```ts new DelegatingSchemaService(store: Store$1, schema: SchemaService): DelegatingSchemaService; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:601](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L601) #### Parameters ##### store `Store$1` ##### schema `SchemaService` #### Returns `DelegatingSchemaService` ## Methods ### attributesDefinitionFor()? ```ts optional attributesDefinitionFor(resource: | ResourceKey | { type: string; }): AttributesSchema; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:578](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L578) Delegates to whichever of the primary/fallback schema services has a schema for the resource, preferring the primary. See [isDelegated](#isdelegated). #### Parameters ##### resource | [`ResourceKey`](../../../../core/types/identifier/types/ResourceKey.md) | { `type`: `string`; } #### Returns `AttributesSchema` *** ### cacheFields()? ```ts optional cacheFields(resource: { type: string; }): Map; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:639](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L639) Queries for the fields of a given resource type or resource identity. Should error if the resource type is not recognized. #### Parameters ##### resource ###### type `string` #### Returns [`Map`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)<`string`, | [`LegacyBelongsToField`](../../../../core/types/schema/fields/types/LegacyBelongsToField.md) | [`LegacyHasManyField`](../../../../core/types/schema/fields/types/LegacyHasManyField.md) | [`LinksModeBelongsToField`](../../../../core/types/schema/fields/types/LinksModeBelongsToField.md) | [`LinksModeHasManyField`](../../../../core/types/schema/fields/types/LinksModeHasManyField.md) | [`LegacyAttributeField`](../../../../core/types/schema/fields/types/LegacyAttributeField.md) | [`GenericField`](../../../../core/types/schema/fields/types/GenericField.md) | [`ObjectField`](../../../../core/types/schema/fields/types/ObjectField.md) | [`SchemaObjectField`](../../../../core/types/schema/fields/types/SchemaObjectField.md) | [`ArrayField`](../../../../core/types/schema/fields/types/ArrayField.md) | [`SchemaArrayField`](../../../../core/types/schema/fields/types/SchemaArrayField.md) | [`ResourceField`](../../../../core/types/schema/fields/types/ResourceField.md) | [`CollectionField`](../../../../core/types/schema/fields/types/CollectionField.md)> *** ### CAUTION\_MEGA\_DANGER\_ZONE\_arrayExtensions() ```ts CAUTION_MEGA_DANGER_ZONE_arrayExtensions(field: ExtensibleField): | Map | null; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:700](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L700) Retrieve the extension map for an array field #### Parameters ##### field `ExtensibleField` #### Returns | [`Map`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)<`string` | `symbol`, `ExtensionDef`> | `null` *** ### CAUTION\_MEGA\_DANGER\_ZONE\_hasExtension() ```ts CAUTION_MEGA_DANGER_ZONE_hasExtension(ext: { kind: "object" | "array"; name: string; }): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:679](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L679) Check if a specific extension has been registered previously #### Parameters ##### ext ###### kind `"object"` | `"array"` ###### name `string` #### Returns `boolean` *** ### CAUTION\_MEGA\_DANGER\_ZONE\_objectExtensions() ```ts CAUTION_MEGA_DANGER_ZONE_objectExtensions(field: ExtensibleField, resolvedType: string | null): | Map | null; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:693](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L693) Retrieve the extension map for an object field #### Parameters ##### field `ExtensibleField` ##### resolvedType `string` | `null` #### Returns | [`Map`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)<`string` | `symbol`, `ExtensionDef`> | `null` *** ### CAUTION\_MEGA\_DANGER\_ZONE\_registerExtension() ```ts CAUTION_MEGA_DANGER_ZONE_registerExtension(extension: CAUTION_MEGA_DANGER_ZONE_Extension): void; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:683](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L683) Register an extension for either objects or arrays See also CAUTION\_MEGA\_DANGER\_ZONE\_Extension #### Parameters ##### extension `CAUTION_MEGA_DANGER_ZONE_Extension` #### Returns `void` *** ### CAUTION\_MEGA\_DANGER\_ZONE\_resourceExtensions() ```ts CAUTION_MEGA_DANGER_ZONE_resourceExtensions(resource: | ResourceKey | { type: string; }): | Map | null; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:687](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L687) Retrieve the extension map for a resource #### Parameters ##### resource | [`ResourceKey`](../../../../core/types/identifier/types/ResourceKey.md) | { `type`: `string`; } #### Returns | [`Map`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)<`string` | `symbol`, `ExtensionDef`> | `null` *** ### derivation() ```ts derivation(field: | DerivedField | { type: string; }): Derivation; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:654](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L654) Returns the derivation registered with the name provided by `field.type`. Validates that the field is a valid DerivedField. #### Parameters ##### field | [`DerivedField`](../../../../core/types/schema/fields/types/DerivedField.md) | { `type`: `string`; } #### Returns [`Derivation`](../../../../core/types/schema/concepts/types/Derivation.md) *** ### doesTypeExist()? ```ts optional doesTypeExist(type: string): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:588](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L588) Whether either the primary or fallback schema service has a schema for the given type. #### Parameters ##### type `string` #### Returns `boolean` *** ### fields() ```ts fields(resource: | ResourceKey | { type: string; }): Map; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:633](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L633) Queries for the fields of a given resource type or resource identity. Should error if the resource type is not recognized. #### Parameters ##### resource | [`ResourceKey`](../../../../core/types/identifier/types/ResourceKey.md) | { `type`: `string`; } #### Returns [`Map`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)<`string`, [`FieldSchema`](../../../../core/types/schema/fields/types/FieldSchema.md)> *** ### hashFn() ```ts hashFn(field: | HashField | { type: string; }): HashFn; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:651](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L651) Returns the hash function registered with the name provided by `field.type`. Validates that the field is a valid HashField. #### Parameters ##### field | [`HashField`](../../../../core/types/schema/fields/types/HashField.md) | { `type`: `string`; } #### Returns [`HashFn`](../../../../core/types/schema/concepts/types/HashFn.md) *** ### hasResource() ```ts hasResource(resource: | ResourceKey | { type: string; }): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:618](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L618) Queries whether the SchemaService recognizes `type` as a resource type #### Parameters ##### resource | [`ResourceKey`](../../../../core/types/identifier/types/ResourceKey.md) | { `type`: `string`; } #### Returns `boolean` *** ### hasTrait() ```ts hasTrait(type: string): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:621](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L621) Queries whether the SchemaService recognizes `type` as a resource trait #### Parameters ##### type `string` #### Returns `boolean` *** ### isDelegated() ```ts isDelegated(resource: | ResourceKey | { type: string; }): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:610](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L610) Whether the given resource's schema is being served by the fallback (legacy Model-derived) schema service rather than the primary one. #### Parameters ##### resource | [`ResourceKey`](../../../../core/types/identifier/types/ResourceKey.md) | { `type`: `string`; } #### Returns `boolean` *** ### registerDerivation() ```ts registerDerivation(derivation: Derivation): void; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:672](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L672) Enables registration of a derivation. The derivation can later be retrieved by the name attached to it's `[Type]` property. #### Type Parameters ##### R `R` ##### T `T` ##### FM `FM` *extends* | [`ObjectValue`](../../../../core/types/json/raw/types/ObjectValue.md) | `null` #### Parameters ##### derivation [`Derivation`](../../../../core/types/schema/concepts/types/Derivation.md)<`R`, `T`, `FM`> #### Returns `void` *** ### registerHashFn() ```ts registerHashFn(hashFn: HashFn): void; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:675](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L675) Enables registration of a hashing function The hashing function can later be retrieved by the name attached to it's `[Type]` property. #### Parameters ##### hashFn [`HashFn`](../../../../core/types/schema/concepts/types/HashFn.md) #### Returns `void` *** ### registerResource() ```ts registerResource(schema: | ResourceSchema | ObjectSchema): void; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:666](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L666) Enables registration of a single Schema representing either a resource in PolarisMode or LegacyMode or an ObjectSchema representing an embedded structure in other schemas. This can be useful for either pre-loading schema information or for registering schema information delivered by API calls or other sources just-in-time. #### Parameters ##### schema | [`ResourceSchema`](../../../../core/types/schema/fields/types/ResourceSchema.md) | [`ObjectSchema`](../../../../core/types/schema/fields/types/ObjectSchema.md) #### Returns `void` *** ### registerResources() ```ts registerResources(schemas: ( | ResourceSchema | ObjectSchema)[]): void; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:663](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L663) Enables registration of multiple Schemas at once. This can be useful for either pre-loading schema information or for registering schema information delivered by API calls or other sources just-in-time. #### Parameters ##### schemas ( | [`ResourceSchema`](../../../../core/types/schema/fields/types/ResourceSchema.md) | [`ObjectSchema`](../../../../core/types/schema/fields/types/ObjectSchema.md))\[] #### Returns `void` *** ### registerTransformation() ```ts registerTransformation(transform: Transformation): void; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:669](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L669) Enables registration of a transformation. The transformation can later be retrieved by the name attached to it's `[Type]` property. #### Parameters ##### transform [`Transformation`](../../../../core/types/schema/concepts/types/Transformation.md) #### Returns `void` *** ### relationshipsDefinitionFor()? ```ts optional relationshipsDefinitionFor(resource: | ResourceKey | { type: string; }): RelationshipsSchema; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:583](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L583) Delegates to whichever of the primary/fallback schema services has a schema for the resource, preferring the primary. See [isDelegated](#isdelegated). #### Parameters ##### resource | [`ResourceKey`](../../../../core/types/identifier/types/ResourceKey.md) | { `type`: `string`; } #### Returns `RelationshipsSchema` *** ### resource() ```ts resource(resource: | ResourceKey | { type: string; }): | ResourceSchema | ObjectSchema; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:657](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L657) Returns the schema for the provided resource type. #### Parameters ##### resource | [`ResourceKey`](../../../../core/types/identifier/types/ResourceKey.md) | { `type`: `string`; } #### Returns | [`ResourceSchema`](../../../../core/types/schema/fields/types/ResourceSchema.md) | [`ObjectSchema`](../../../../core/types/schema/fields/types/ObjectSchema.md) *** ### resourceHasTrait() ```ts resourceHasTrait(resource: | ResourceKey | { type: string; }, trait: string): boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:627](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L627) Queries whether the given resource has the given trait #### Parameters ##### resource | [`ResourceKey`](../../../../core/types/identifier/types/ResourceKey.md) | { `type`: `string`; } ##### trait `string` #### Returns `boolean` *** ### resourceTypes() ```ts resourceTypes(): readonly string[]; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:614](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L614) Returns all known resource types #### Returns readonly `string`\[] *** ### transformation() ```ts transformation(field: | GenericField | ObjectField | ArrayField | { type: string; }): Transformation; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:648](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L648) Returns the transformation registered with the name provided by `field.type`. Validates that the field is a valid transformable. #### Parameters ##### field | [`GenericField`](../../../../core/types/schema/fields/types/GenericField.md) | [`ObjectField`](../../../../core/types/schema/fields/types/ObjectField.md) | [`ArrayField`](../../../../core/types/schema/fields/types/ArrayField.md) | { `type`: `string`; } #### Returns [`Transformation`](../../../../core/types/schema/concepts/types/Transformation.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/migration-support/functions/registerDerivations.md description: >- Legacy setup that registers the derivation, relationship behaviors, and extension a schema service needs to support LegacyMode records. --- # registerDerivations() ```ts function registerDerivations(schema: SchemaService): void; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:450](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L450) A function which registers the necessary derivations to support the LegacyMode features of @warp-drive/legacy/model while migrating to WarpDrive. This must be called in order to use the fields added by [withDefaults](withDefaults.md) or [withRestoredDeprecatedModelRequestBehaviors](withRestoredDeprecatedModelRequestBehaviors.md). ## Parameters ### schema `SchemaService` The schema service to register the derivations with. ## Returns `void` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/migration-support/functions/withDefaults.md description: >- Legacy helper that marks a resource schema as LegacyMode and adds the fields that give its records `Model`-like state and methods. --- # withDefaults() ```ts function withDefaults(schema: WithPartial): LegacyResourceSchema; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:347](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L347) A function which adds the necessary fields to a schema and marks it as being in LegacyMode. This is used to support the legacy features of @warp-drive/legacy/model while migrating to WarpDrive. Example: ```ts import { withDefaults, WithLegacy } from '@warp-drive/legacy/model/migration-support'; import { Type } from '@warp-drive/core/types/symbols'; import type { HasMany } from '@warp-drive/legacy/model'; export const UserSchema = withDefaults({ type: 'user', fields: [ { name: 'firstName', kind: 'attribute' }, { name: 'lastName', kind: 'attribute' }, { name: 'age', kind: 'attribute' }, { name: 'friends', kind: 'hasMany', type: 'user', options: { inverse: 'friends', async: false } }, { name: 'bestFriend', kind: 'belongsTo', type: 'user', options: { inverse: null, async: false } }, ], }); export type User = WithLegacy<{ firstName: string; lastName: string; age: number; friends: HasMany; bestFriend: User | null; [Type]: 'user'; }> ``` Using this function require registering the derivations it requires with the schema service. ```ts import { registerDerivations } from '@warp-drive/legacy/model/migration-support'; registerDerivations(schema); ``` ## Parameters ### schema [`WithPartial`](../../../../core/types/utils/types/WithPartial.md)<[`LegacyResourceSchema`](../../../../core/types/schema/fields/types/LegacyResourceSchema.md), `"identity"` | `"legacy"`> The schema to add legacy support to. ## Returns [`LegacyResourceSchema`](../../../../core/types/schema/fields/types/LegacyResourceSchema.md) The schema with legacy support added. --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/migration-support/functions/withRestoredDeprecatedModelRequestBehaviors.md description: >- Legacy alternative to `withDefaults` that makes a LegacyMode schema whose `save`, `reload`, and `destroyRecord` run without deprecation warnings. --- # withRestoredDeprecatedModelRequestBehaviors() ```ts function withRestoredDeprecatedModelRequestBehaviors(schema: WithPartial): LegacyResourceSchema; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:403](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L403) Adds the necessasary fields to the schema for supporting the deprecated request methods on LegacyMode schemas. Use this instead of `withDefaults` to add the fields and behaviors necessary to support Model-Like capabilities. ```ts import { withRestoredDeprecatedModelRequestBehaviors } from '@warp-drive/legacy/model/migration-support'; export const UserSchema = withRestoredDeprecatedModelRequestBehaviors({ type: 'user', fields: [ { name: 'firstName', kind: 'attribute' }, { name: 'lastName', kind: 'attribute' }, ] }); ``` ## Parameters ### schema [`WithPartial`](../../../../core/types/utils/types/WithPartial.md)<[`LegacyResourceSchema`](../../../../core/types/schema/fields/types/LegacyResourceSchema.md), `"identity"` | `"legacy"`> ## Returns [`LegacyResourceSchema`](../../../../core/types/schema/fields/types/LegacyResourceSchema.md) --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/model/migration-support.md description: >- Legacy helpers for migrating from `Model` to `ReactiveResource`: LegacyMode schema defaults, derivations, types, and a schema service that serves both at once. --- This module provides support for migrating away from @warp-drive/legacy/model to ReactiveResource from @warp-drive/core/reactive. It includes: * A `withDefaults` function to assist in creating a schema in LegacyMode * A `registerDerivations` function to register the derivations necessary to support LegacyMode * A `DelegatingSchemaService` that can be used to provide a schema service that works with both @warp-drive/legacy/model and @warp-drive/core/reactive simultaneously for migration purposes. * A `WithLegacy` type util that can be used to create a type that includes the legacy properties and methods of a record. Using LegacyMode features on a ReactiveResource *requires* the use of these derivations and schema additions. LegacyMode is not intended to be a long-term solution, but rather a stepping stone to assist in more rapidly adopting modern WarpDrive features. ## Classes * [DelegatingSchemaService](classes/DelegatingSchemaService.md) ## Functions * [registerDerivations](functions/registerDerivations.md) * [withDefaults](functions/withDefaults.md) * [withRestoredDeprecatedModelRequestBehaviors](functions/withRestoredDeprecatedModelRequestBehaviors.md) ## Types * [WithLegacy](types/WithLegacy.md) * [WithLegacyDerivations](types/WithLegacyDerivations.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/migration-support/types/WithLegacy.md description: >- Legacy type that adds the `Model`-style state flags and methods (`save`, `isNew`, `errors`, etc.) that `withDefaults` provides to a LegacyMode record type. --- # WithLegacy\ ```ts type WithLegacy = T & LegacyModeRecord; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:212](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L212) A Type utility that enables quickly adding type information for the fields defined by `import { withDefaults } from '@warp-drive/legacy/model/migration-support'`. Example: ```ts import { withDefaults, WithLegacy } from '@warp-drive/legacy/model/migration-support'; import { Type } from '@warp-drive/core/types/symbols'; import type { HasMany } from '@@warp-drive/legacy/model'; export const UserSchema = withDefaults({ type: 'user', fields: [ { name: 'firstName', kind: 'attribute' }, { name: 'lastName', kind: 'attribute' }, { name: 'age', kind: 'attribute' }, { name: 'friends', kind: 'hasMany', type: 'user', options: { inverse: 'friends', async: false } }, { name: 'bestFriend', kind: 'belongsTo', type: 'user', options: { inverse: null, async: false } }, ], }); export type User = WithLegacy<{ firstName: string; lastName: string; age: number; friends: HasMany; bestFriend: User | null; [Type]: 'user'; }> ``` ## Type Parameters ### T `T` *extends* [`TypedRecordInstance`](../../../../core/types/record/types/TypedRecordInstance.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/migration-support/types/WithLegacyDerivations.md description: >- Legacy type that adds the `Model`-style `belongsTo` and `hasMany` reference methods to a typed record migrating from `Model` to a schema-based record. --- # WithLegacyDerivations\ ```ts type WithLegacyDerivations = T & MinimalLegacyRecord & { belongsTo: typeof belongsTo; hasMany: typeof hasMany; }; ``` Defined in: [warp-drive-packages/legacy/src/model/migration-support.ts:92](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/migration-support.ts#L92) Adds the `Model`-style `belongsTo`/`hasMany` reference methods to a [TypedRecordInstance](../../../../core/types/record/types/TypedRecordInstance.md), for use when migrating a resource from `Model` to a schema-based record while preserving these APIs. ## Type Declaration ### belongsTo ```ts belongsTo: typeof belongsTo; ``` see belongsTo ### hasMany ```ts hasMany: typeof hasMany; ``` see hasMany ## Type Parameters ### T `T` *extends* [`TypedRecordInstance`](../../../../core/types/record/types/TypedRecordInstance.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/model/types/AsyncHasMany.md description: >- Legacy promise-like, iterable proxy returned by an async `hasMany` on a `Model`, which templates can consume while the related records load. --- # AsyncHasMany\ ```ts interface AsyncHasMany { [LegacyPromiseProxy]: true; content: LegacyManyArray | null; isDestroyed: boolean; isFulfilled: boolean; isPending: boolean; isRejected: boolean; isSettled: boolean; promise: | Promise> | null; get length(): number; get links(): | Links | null | undefined; get meta(): | Record | null | undefined; catch(cb: ((reason: any) => unknown) | null | undefined): Promise; destroy(): void; finally(cb: (() => void) | null | undefined): Promise; reload(options: Omit): this; then(success: ((value: LegacyManyArray) => unknown) | null | undefined, rejected?: ((reason: any) => unknown) | null): Promise; } ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:16](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L16) This class is returned as the result of accessing an async hasMany relationship on an instance of a Model extending from `@warp-drive/legacy/model`. A PromiseManyArray is an iterable proxy that allows templates to consume related ManyArrays and update once their contents are no longer pending. In your JS code you should resolve the promise first. ```js const comments = await post.comments; ``` ## Type Parameters ### T `T` ## Methods ### catch() ```ts catch(cb: ((reason: any) => unknown) | null | undefined): Promise; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:162](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L162) catch errors thrown by this promise #### Parameters ##### cb ((`reason`: `any`) => `unknown`) | `null` | `undefined` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<`unknown`> *** ### destroy() ```ts destroy(): void; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:183](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L183) Tears down this proxy, releasing its [content](#content) and [promise](#promise) and marking it as [destroyed](#isdestroyed). #### Returns `void` *** ### finally() ```ts finally(cb: (() => void) | null | undefined): Promise; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:171](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L171) run cleanup after this promise completes #### Parameters ##### cb (() => `void`) | `null` | `undefined` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<`unknown`> *** ### reload() ```ts reload(options: Omit): this; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:113](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L113) Reload the relationship #### Parameters ##### options [`Omit`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys)<`BaseFinderOptions`, `""`> #### Returns `this` *** ### then() ```ts then(success: ((value: LegacyManyArray) => unknown) | null | undefined, rejected?: ((reason: any) => unknown) | null): Promise; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:151](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L151) chain this promise #### Parameters ##### success ((`value`: `LegacyManyArray`) => `unknown`) | `null` | `undefined` ##### rejected? ((`reason`: `any`) => `unknown`) | `null` #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<`unknown`> ## Properties ### \[LegacyPromiseProxy] ```ts [LegacyPromiseProxy]: true; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:21](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L21) A property signifying that this object implements the classic Ember `PromiseProxyMixin`-like API. See LegacyPromiseProxy. *** ### content ```ts content: LegacyManyArray | null; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:55](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L55) The resolved `ManyArray` for the relationship, if the promise has resolved, else `null`. *** ### isDestroyed ```ts isDestroyed: boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:50](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L50) Whether [destroy](#destroy) has been called. *** ### isFulfilled ```ts isFulfilled: boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:138](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L138) Whether the loading promise succeeded *** ### isPending ```ts isPending: boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:126](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L126) Whether the loading promise is still pending *** ### isRejected ```ts isRejected: boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:132](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L132) Whether the loading promise rejected *** ### isSettled ```ts isSettled: boolean; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:144](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L144) Whether the loading promise completed (resolved or rejected) *** ### promise ```ts promise: | Promise> | null; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:46](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L46) The promise for the relationship's content, or `null` once [destroy](#destroy) has been called. ### length #### Get Signature ```ts get length(): number; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:68](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L68) Retrieve the length of the content ##### Returns `number` *** ### links #### Get Signature ```ts get links(): | Links | null | undefined; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:196](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L196) Retrieve the links for this relationship ##### Returns | [`Links`](../../../core/types/spec/json-api-raw/types/Links.md) | `null` | `undefined` *** ### meta #### Get Signature ```ts get meta(): | Record | null | undefined; ``` Defined in: [warp-drive-packages/legacy/src/model/-private/promise-many-array.ts:205](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/model/-private/promise-many-array.ts#L205) Retrieve the meta for this relationship ##### Returns | [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> | `null` | `undefined` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/classes/Serializer.md description: >- Legacy abstract base class for serializers that normalize API responses into JSON:API and serialize records into the API's request format. Serializer --- # Serializer Defined in: [warp-drive-packages/legacy/src/serializer.ts:184](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer.ts#L184) > ⚠️ CAUTION you likely want the docs for [MinimumSerializerInterface](../../compat/types/MinimumSerializerInterface.md) > as extending this abstract class is unnecessary. `Serializer` is an abstract base class that you may override in your application to customize it for your backend. The minimum set of methods that you should implement is: * `normalizeResponse()` * `serialize()` And you can optionally override the following methods: * `normalize()` For an example implementation, see the included [JSONSerializer](../json/classes/JSONSerializer.md). ## Extends * `EmberObject` ## Constructors ### Constructor ```ts new Serializer(owner?: Owner): Serializer; ``` #### Parameters ##### owner? `Owner` #### Returns `Serializer` #### Inherited from ```ts EmberObject.constructor ``` ## Methods ### normalize() ```ts normalize(_typeClass: ModelSchema, hash: Record): | EmptyResourceDocument | SingleResourceDocument; ``` Defined in: [warp-drive-packages/legacy/src/serializer.ts:308](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer.ts#L308) The `normalize` method is used to convert a payload received from your external data source into the normalized form `store.push()` expects. You should override this method, munge the hash and return the normalized payload. Example: ```js Serializer.extend({ normalize(modelClass, resourceHash) { let data = { id: resourceHash.id, type: modelClass.modelName, attributes: resourceHash }; return { data: data }; } }) ``` #### Parameters ##### \_typeClass `ModelSchema` the model class the hash is being normalized for ##### hash [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> the raw payload hash to normalize #### Returns | [`EmptyResourceDocument`](../../../core/types/spec/json-api-raw/types/EmptyResourceDocument.md) | [`SingleResourceDocument`](../../../core/types/spec/json-api-raw/types/SingleResourceDocument.md) the normalized resource document ## Properties ### store ```ts store: Store$1; ``` Defined in: [warp-drive-packages/legacy/src/serializer.ts:204](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer.ts#L204) The `store` property is the application's `store` that contains all records. It can be used to look up serializers for other model types that may be nested inside the payload response. Example: ```js Serializer.extend({ extractRelationship(relationshipModelName, relationshipHash) { let modelClass = this.store.modelFor(relationshipModelName); let relationshipSerializer = this.store.serializerFor(relationshipModelName); return relationshipSerializer.normalize(modelClass, relationshipHash); } }); ``` --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/serializer.md description: >- Legacy serializer layer that converts data between an API's format and JSON:API for the adapter-based request flow. --- ## Overview :::danger ⚠️ **This is LEGACY documentation** for a feature that is no longer encouraged to be used. If starting a new app or thinking of implementing a new serializer, consider writing a Handler instead to be used with the [RequestManager](../../core/classes/RequestManager.md) ::: In order to properly manage and present your data, WarpDrive needs to understand the structure of data it receives. `Serializers` convert data between the server's API format and the format WarpDrive understands. Data received from an API response is **normalized** into [{json:api}](https://jsonapi.org/) (the format used internally by WarpDrive), while data sent to an API is **serialized** into the format the API expects. ### Why It's Legacy The Serializer pattern was designed to transform data between your API's format and the {json:api} format the legacy store works with: * `store.serializerFor` resolves a serializer by resource type at runtime, looking up `serializer:` and then `serializer:application` through Ember's owner, though an API's format more often varies per API version than per resource type (see Serializer Resolution below). * Every response is converted into {json:api} before it reaches the cache, whatever format the API actually uses. * The provided serializer classes extend `EmberObject`, which, together with the owner lookup, ties the pattern to Ember. ### Modern Alternative Use [Handlers](/api/@warp-drive/core/request/types/Handler) with the [RequestManager](../../core/classes/RequestManager.md). Modern ***Warp*Drive**: * normalizes a payload inside a handler when it needs transforming, using plain functions and helpers such as `dasherize` and `singularize` from `@warp-drive/utilities/string` * lets you pick a cache that understands your API's format natively, such as `JSONAPICache` from `@warp-drive/json-api` for {json:api}, or write your own that implements the Cache interface For an alternative modern pattern to Serializers, see the [Request Handlers Guide](/guides/the-manual/requests/handlers). ### Setup Serializers run inside the `LegacyNetworkHandler` from [`@warp-drive/legacy/compat`](/api/@warp-drive/legacy/compat/). A store created with `useLegacyStore` adds it unless `linksMode` is `true`; a store you build yourself must add it to its `RequestManager`, as shown in [Configure the Store](/guides/configuration/legacy-package-setup/setup/universal.md#configure-the-store). ### Implementing a Serializer There are only two required serializer methods, one for normalizing data from the server API format into {json:api}, and another for serializing records via `Snapshots` into the expected server API format. To implement a serializer, export a class that conforms to the structure described by [MinimumSerializerInterface](../compat/types/MinimumSerializerInterface.md) from the `app/serializers/` directory. An example is below. ```ts import EmberObject from '@ember/object'; export default class ApplicationSerializer extends EmberObject { normalizeResponse(store, schema, rawPayload) { return rawPayload; } serialize(snapshot, options) { const serializedResource = { id: snapshot.id, type: snapshot.modelName, attributes: snapshot.attributes() }; return serializedResource; } } ``` ### Serializer Resolution `store.serializerFor(name)` will lookup serializers defined in `app/serializers/` and return an instance. If no serializer is found, an error will be thrown. `serializerFor` first attempts to find a serializer with an exact match on `name`, then falls back to checking for the presence of a serializer named `application`. ```ts store.serializerFor('author'); // lookup paths (in order) => // app/serializers/author.js // app/serializers/application.js ``` Most requests in `@warp-drive/legacy` are made with respect to a particular `type` (or `modelName`) (e.g., "get me the full collection of **books**" or "get me the **employee** whose id is 37"). We refer to this as the **primary** resource `type`. Typically `serializerFor` will be used to find a serializer with a name matching that of the primary resource `type` for the request, falling back to the `application` serializer for those types that do not have a defined serializer. This is often described as a `per-model` or `per-type` strategy for defining serializers. However, because APIs rarely format payloads per-type but rather per-API-version, this may not be a desired strategy. It is recommended that applications define only a single `application` adapter and serializer where possible. If you have multiple API formats and the per-type strategy is not viable, one strategy is to write an `application` adapter and serializer that make use of `options` to specify the desired format when making a request. ### Using a Serializer Any serializer in `app/serializers/` can be looked up by `name` using `store.serializerFor(name)`. ### Default Serializers For applications whose APIs are *very close to* or *exactly* the **REST** format or **JSON:API** format the `@warp-drive/legacy/serializer` package contains implementations these applications can extend. It also contains a simple `JSONSerializer` for serializing to/from very basic JSON objects. Many applications will find writing their own serializer to be more performant and less complex than extending these classes even when their API format is very close to that expected by these serializers. It is recommended that apps write their own serializer to best suit the needs of their API and application. ## Classes * [Serializer](classes/Serializer.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/json-api/classes/JSONAPISerializer.md description: >- Legacy serializer that normalizes and serializes record payloads following the JSON:API spec. --- # JSONAPISerializer Defined in: [warp-drive-packages/legacy/src/serializer/json-api.ts:148](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/json-api.ts#L148) :::danger ⚠️ This is LEGACY documentation for a feature that is no longer encouraged to be used. If starting a new app or thinking of implementing a new adapter, consider writing a Handler instead to be used with the [RequestManager](../../../../core/classes/RequestManager.md) ::: In WarpDrive a Serializer is used to serialize and deserialize records when they are transferred in and out of an external source. This process involves normalizing property names, transforming attribute values and serializing relationships. `JSONAPISerializer` supports the http://jsonapi.org/ spec, though even compliant {json:api} servers may find writing an application specific serializer better suited to their needs and more performant. This serializer normalizes a JSON API payload that looks like: ```js [app/models/player.js] import Model, { attr, belongsTo } from '@warp-drive/legacy/model'; export default class Player extends Model { @attr('string') name; @attr('string') skill; @attr('number') gamesPlayed; @belongsTo('club') club; } ``` ```js [app/models/club.js] import Model, { attr, hasMany } from '@warp-drive/legacy/model'; export default class Club extends Model { @attr('string') name; @attr('string') location; @hasMany('player') players; } ``` ```js { "data": [ { "attributes": { "name": "Benfica", "location": "Portugal" }, "id": "1", "relationships": { "players": { "data": [ { "id": "3", "type": "players" } ] } }, "type": "clubs" } ], "included": [ { "attributes": { "name": "Eusebio Silva Ferreira", "skill": "Rocket shot", "games-played": 431 }, "id": "3", "relationships": { "club": { "data": { "id": "1", "type": "clubs" } } }, "type": "players" } ] } ``` to the format that the JSONAPICache expects. ### Customizing meta Since a JSON API Document can have meta defined in multiple locations you can use the specific serializer hooks if you need to customize the meta. One scenario would be to camelCase the meta keys of your payload. The example below shows how this could be done using `normalizeArrayResponse` and `extractRelationship`. ```js [app/serializers/application.js] import { JSONAPISerializer } from '@warp-drive/legacy/serializer/json-api'; export default class ApplicationSerializer extends JSONAPISerializer { normalizeArrayResponse(store, primaryModelClass, payload, id, requestType) { let normalizedDocument = super.normalizeArrayResponse(...arguments); // Customize document meta normalizedDocument.meta = camelCaseKeys(normalizedDocument.meta); return normalizedDocument; } extractRelationship(relationshipHash) { let normalizedRelationship = super.extractRelationship(...arguments); // Customize relationship meta normalizedRelationship.meta = camelCaseKeys(normalizedRelationship.meta); return normalizedRelationship; } } ``` --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/json-api.md description: >- Legacy `JSONAPISerializer`, which normalizes and serializes record payloads following the JSON:API spec. --- ## Classes * [JSONAPISerializer](classes/JSONAPISerializer.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/json/classes/JSONSerializer.md description: >- Legacy serializer for plain JSON payloads that don't follow the JSON:API spec, normalizing them into JSON:API documents for the store. JSONSerializer --- # JSONSerializer Defined in: [warp-drive-packages/legacy/src/serializer/json.ts:113](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/json.ts#L113) :::danger ⚠️ **This is LEGACY documentation** for a feature that is no longer encouraged to be used. If starting a new app or thinking of implementing a new adapter, consider writing a Handler instead to be used with the [RequestManager](../../../../core/classes/RequestManager.md) ::: In WarpDrive a Serializer is used to serialize and deserialize records when they are transferred in and out of an external source. This process involves normalizing property names, transforming attribute values and serializing relationships. By default, WarpDrive uses and recommends the `JSONAPISerializer`. `JSONSerializer` is useful for simpler or legacy backends that may not support the http://jsonapi.org/ spec. For example, given the following `User` model and JSON payload: ```js [app/models/user.js] import Model, { attr, belongsTo, hasMany } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @hasMany('user') friends; @belongsTo('location') house; @attr('string') name; } ``` ```js { id: 1, name: 'Sebastian', friends: [3, 4], links: { house: '/houses/lefkada' } } ``` `JSONSerializer` will normalize the JSON payload to the {json:api} format that the JSONAPICache uses to cache data in the Store. You can customize how JSONSerializer processes its payload by passing options in the `attrs` hash or by subclassing the `JSONSerializer` and overriding hooks: * To customize how a single record is normalized, use the `normalize` hook. * To customize how `JSONSerializer` normalizes the whole server response, use the `normalizeResponse` hook. * To customize how `JSONSerializer` normalizes a specific response from the server, use one of the many specific `normalizeResponse` hooks. * To customize how `JSONSerializer` normalizes your id, attributes or relationships, use the `extractId`, `extractAttributes` and `extractRelationships` hooks. The `JSONSerializer` normalization process follows these steps: 1. `normalizeResponse` * entry method to the serializer. 2. `normalizeCreateRecordResponse` * a `normalizeResponse` for a specific operation is called. 3. `normalizeSingleResponse`|`normalizeArrayResponse` * for methods like `createRecord` we expect a single record back, while for methods like `findAll` we expect multiple records back. 4. `normalize` * `normalizeArrayResponse` iterates and calls `normalize` for each of its records while `normalizeSingle` calls it once. This is the method you most likely want to subclass. 5. `extractId` | `extractAttributes` | `extractRelationships` * `normalize` delegates to these methods to turn the record payload into the JSON API format. --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/json.md description: >- Legacy `JSONSerializer`, which normalizes and serializes plain JSON payloads that don't follow the JSON:API spec. --- ## Classes * [JSONSerializer](classes/JSONSerializer.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/rest/classes/EmbeddedRecordsMixin.md description: >- Legacy serializer mixin that extracts and serializes related records embedded in a payload instead of referenced by id, configured per relationship via `attrs`. EmbeddedRecordsMixin --- # EmbeddedRecordsMixin Defined in: [warp-drive-packages/legacy/src/serializer/-private/embedded-records-mixin.ts:104](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/embedded-records-mixin.ts#L104) ## Using Embedded Records `EmbeddedRecordsMixin` supports serializing embedded records. To set up embedded records, include the mixin when extending a serializer, then define and configure embedded (model) relationships. Note that embedded records will serialize with the serializer for their model instead of the serializer in which they are defined. Note also that this mixin does not work with JSONAPISerializer because the JSON:API specification does not describe how to format embedded resources. Below is an example of a per-type serializer (`post` type). ```js [app/serializers/post.js] import RESTSerializer, { EmbeddedRecordsMixin } from '@warp-drive/legacy/serializer/rest'; export default class PostSerializer extends RESTSerializer.extend(EmbeddedRecordsMixin) { attrs = { author: { embedded: 'always' }, comments: { serialize: 'ids' } } } ``` Note that this use of `{ embedded: 'always' }` is unrelated to the `{ embedded: 'always' }` that is defined as an option on `attr` as part of defining a model while working with the `ActiveModelSerializer`. Nevertheless, using `{ embedded: 'always' }` as an option to `attr` is not a valid way to set up embedded records. The `attrs` option for a resource `{ embedded: 'always' }` is shorthand for: ```js { serialize: 'records', deserialize: 'records' } ``` ### Configuring Attrs A resource's `attrs` option may be set to use `ids`, `records` or false for the `serialize` and `deserialize` settings. The `attrs` property can be set on the `ApplicationSerializer` or a per-type serializer. In the case where embedded JSON is expected while extracting a payload (reading) the setting is `deserialize: 'records'`, there is no need to use `ids` when extracting as that is the default behaviour without this mixin if you are using the vanilla `EmbeddedRecordsMixin`. Likewise, to embed JSON in the payload while serializing `serialize: 'records'` is the setting to use. There is an option of not embedding JSON in the serialized payload by using `serialize: 'ids'`. If you do not want the relationship sent at all, you can use `serialize: false`. ### EmbeddedRecordsMixin defaults If you do not overwrite `attrs` for a specific relationship, the `EmbeddedRecordsMixin` will behave in the following way: BelongsTo: `{ serialize: 'id', deserialize: 'id' }` HasMany: `{ serialize: false, deserialize: 'ids' }` ### Model Relationships Embedded records must have a model defined to be extracted and serialized. Note that when defining any relationships on your model such as `belongsTo` and `hasMany`, you should not both specify `async: true` and also indicate through the serializer's `attrs` attribute that the related model should be embedded for deserialization. If a model is declared embedded for deserialization (`embedded: 'always'` or `deserialize: 'records'`), then do not use `async: true`. To successfully extract and serialize embedded records the model relationships must be set up correctly. See the [defining relationships](https://guides.emberjs.com/current/models/relationships) section of the **Defining Models** guide page. Records without an `id` property are not considered embedded records, model instances must have an `id` property to be used with Ember Data. ### Example JSON payloads, Models and Serializers **When customizing a serializer it is important to grok what the customizations are. Please read the docs for the methods this mixin provides, in case you need to modify it to fit your specific needs.** --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/rest/classes/RESTSerializer.md description: >- Legacy serializer for REST payloads that key records by model type name at the root, with hooks for normalizing keys and payloads. RESTSerializer --- # RESTSerializer Defined in: [warp-drive-packages/legacy/src/serializer/rest.ts:85](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/rest.ts#L85) :::danger ⚠️ **This is LEGACY documentation** for a feature that is no longer encouraged to be used. If starting a new app or thinking of implementing a new adapter, consider writing a Handler instead to be used with the [RequestManager](../../../../core/classes/RequestManager.md) ::: Normally, applications will use the `RESTSerializer` by implementing the `normalize` method. This allows you to do whatever kind of munging you need and is especially useful if your server is inconsistent and you need to do munging differently for many different kinds of responses. See the `normalize` documentation for more information. ## Across the Board Normalization There are also a number of hooks that you might find useful to define across-the-board rules for your payload. These rules will be useful if your server is consistent, or if you're building an adapter for an infrastructure service, like Firebase, and want to encode service conventions. For example, if all of your keys are underscored and all-caps, but otherwise consistent with the names you use in your models, you can implement across-the-board rules for how to convert an attribute name in your model to a key in your JSON. ```js [app/serializers/application.js] import { RESTSerializer } from '@warp-drive/legacy/serializer/rest'; import { underscore } from '/utils/string-utils'; export default class ApplicationSerializer extends RESTSerializer { keyForAttribute(attr, method) { return underscore(attr).toUpperCase(); } } ``` You can also implement `keyForRelationship`, which takes the name of the relationship as the first parameter, the kind of relationship (`hasMany` or `belongsTo`) as the second parameter, and the method (`serialize` or `deserialize`) as the third parameter. --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/rest.md description: >- Legacy `RESTSerializer` for payloads that key records by model name at the root, plus the `EmbeddedRecordsMixin` for embedded relationships. --- ## Classes * [EmbeddedRecordsMixin](classes/EmbeddedRecordsMixin.md) * [RESTSerializer](classes/RESTSerializer.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/transform/classes/BooleanTransform.md description: >- Legacy transform for `attr('boolean')` that converts payload values to and from booleans, optionally allowing `null`. --- # BooleanTransform Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/boolean.ts:6](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/boolean.ts#L6) The `BooleanTransform` class is used to serialize and deserialize boolean attributes on Ember Data record objects. This transform is used when `'boolean'` is passed as the type parameter to the [attr](../../../model/functions/attr.md)function. Usage ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('boolean') isAdmin; @attr('string') name; @attr('string') email; } ``` By default, the boolean transform only allows for values of `true` or `false`. You can opt into allowing `null` values for boolean attributes via `attr('boolean', { allowNull: true })` ```js [app/models/user.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('string') email; @attr('string') username; @attr('boolean', { allowNull: true }) wantsWeeklyEmail; } ``` ## Constructors ### Constructor ```ts new BooleanTransform(): BooleanTransform; ``` #### Returns `BooleanTransform` ## Methods ### deserialize() ```ts deserialize(serialized: string | number | boolean | null, options?: { allowNull?: boolean; }): boolean | null; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/boolean.ts:54](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/boolean.ts#L54) Converts a serialized (raw payload) value into a `boolean` (or `null` when `allowNull` is set and the value is nullish). #### Parameters ##### serialized `string` | `number` | `boolean` | `null` ##### options? ###### allowNull? `boolean` #### Returns `boolean` | `null` *** ### serialize() ```ts serialize(deserialized: boolean | null, options?: { allowNull?: boolean; }): boolean | null; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/boolean.ts:73](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/boolean.ts#L73) Converts a `boolean` attribute value into its serialized (raw payload) form. #### Parameters ##### deserialized `boolean` | `null` ##### options? ###### allowNull? `boolean` #### Returns `boolean` | `null` *** ### create() ```ts static create(): BooleanTransform; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/boolean.ts:84](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/boolean.ts#L84) Creates a new instance of this transform. #### Returns `BooleanTransform` ## Properties ### \_\_\_(unique) Symbol($type) ```ts ___(unique) Symbol($type): "boolean"; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/boolean.ts:10](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/boolean.ts#L10) see [TransformName](../../../../core/types/symbols/variables/TransformName.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/transform/classes/DateTransform.md description: >- Legacy transform for `attr('date')` that converts ISO 8601 strings or epoch numbers to `Date` objects and serializes them back to ISO 8601 strings. --- # DateTransform Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/date.ts:6](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/date.ts#L6) The `DateTransform` class is used to serialize and deserialize date attributes on Ember Data record objects. This transform is used when `'date'` is passed as the type parameter to the [attr](../../../model/functions/attr.md) function. It uses the [`ISO 8601`](https://en.wikipedia.org/wiki/ISO_8601) standard. ```js [app/models/score.js] import Model, { attr, belongsTo } from '@warp-drive/legacy/model'; export default class ScoreModel extends Model { @attr('number') value; @belongsTo('player') player; @attr('date') date; } ``` ## Constructors ### Constructor ```ts new DateTransform(): DateTransform; ``` #### Returns `DateTransform` ## Methods ### deserialize() ```ts deserialize(serialized: string | number | null, _options?: Record): | Date | null; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/date.ts:39](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/date.ts#L39) Converts a serialized (raw payload) `ISO 8601` string, epoch number, or nullish value into a `Date` (or `null`/`undefined`). #### Parameters ##### serialized `string` | `number` | `null` ##### \_options? [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns | [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | `null` *** ### serialize() ```ts serialize(date: Date, _options?: Record): string | null; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/date.ts:63](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/date.ts#L63) Converts a `Date` attribute value into an `ISO 8601` string, or `null` if the value is not a valid `Date`. #### Parameters ##### date [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) ##### \_options? [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns `string` | `null` *** ### create() ```ts static create(): DateTransform; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/date.ts:75](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/date.ts#L75) Creates a new instance of this transform. #### Returns `DateTransform` ## Properties ### \_\_\_(unique) Symbol($type) ```ts ___(unique) Symbol($type): "date"; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/date.ts:10](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/date.ts#L10) see [TransformName](../../../../core/types/symbols/variables/TransformName.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/transform/classes/NumberTransform.md description: >- Legacy transform for `attr('number')` that converts payload values to numbers, or `null` when empty or not a valid number. --- # NumberTransform Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/number.ts:10](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/number.ts#L10) The `NumberTransform` class is used to serialize and deserialize numeric attributes on Ember Data record objects. This transform is used when `number` is passed as the type parameter to the [attr](../../../model/functions/attr.md) function. Usage ```js [app/models/score.js] import Model, { attr, belongsTo } from '@warp-drive/legacy/model'; export default class ScoreModel extends Model { @attr('number') value; @belongsTo('player') player; @attr('date') date; } ``` ## Constructors ### Constructor ```ts new NumberTransform(): NumberTransform; ``` #### Returns `NumberTransform` ## Methods ### deserialize() ```ts deserialize(serialized: string | number | null | undefined, _options?: Record): number | null; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/number.ts:44](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/number.ts#L44) Converts a serialized (raw payload) value into a `number`, or `null` if the value is empty, nullish, or not a valid number. #### Parameters ##### serialized `string` | `number` | `null` | `undefined` ##### \_options? [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns `number` | `null` *** ### serialize() ```ts serialize(deserialized: string | number | null | undefined, _options?: Record): number | null; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/number.ts:57](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/number.ts#L57) Converts a `number` attribute value into its serialized (raw payload) form. #### Parameters ##### deserialized `string` | `number` | `null` | `undefined` ##### \_options? [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns `number` | `null` *** ### create() ```ts static create(): NumberTransform; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/number.ts:70](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/number.ts#L70) Creates a new instance of this transform. #### Returns `NumberTransform` ## Properties ### \_\_\_(unique) Symbol($type) ```ts ___(unique) Symbol($type): "number"; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/number.ts:14](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/number.ts#L14) see [TransformName](../../../../core/types/symbols/variables/TransformName.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/transform/classes/StringTransform.md description: >- Legacy transform for `attr('string')` that converts payload values to and from strings. --- # StringTransform Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/string.ts:6](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/string.ts#L6) The `StringTransform` class is used to serialize and deserialize string attributes on Ember Data record objects. This transform is used when `string` is passed as the type parameter to the [attr](../../../model/functions/attr.md) function. Usage ```js [app/models/user.js] import Model, { attr, belongsTo } from '@warp-drive/legacy/model'; export default class UserModel extends Model { @attr('boolean') isAdmin; @attr('string') name; @attr('string') email; } ``` ## Constructors ### Constructor ```ts new StringTransform(): StringTransform; ``` #### Returns `StringTransform` ## Methods ### deserialize() ```ts deserialize(serialized: unknown, _options?: Record): string | null; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/string.ts:38](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/string.ts#L38) Converts a serialized (raw payload) value into a `string`, or `null` if the value is falsy (and not an empty string). #### Parameters ##### serialized `unknown` ##### \_options? [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns `string` | `null` *** ### serialize() ```ts serialize(deserialized: unknown, _options?: Record): string | null; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/string.ts:44](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/string.ts#L44) Converts a `string` attribute value into its serialized (raw payload) form. #### Parameters ##### deserialized `unknown` ##### \_options? [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)<`string`, `unknown`> #### Returns `string` | `null` *** ### create() ```ts static create(): StringTransform; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/string.ts:51](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/string.ts#L51) Creates a new instance of this transform. #### Returns `StringTransform` ## Properties ### \_\_\_(unique) Symbol($type) ```ts ___(unique) Symbol($type): "string"; ``` Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/string.ts:10](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/string.ts#L10) see [TransformName](../../../../core/types/symbols/variables/TransformName.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/transform/classes/Transform.md description: >- Legacy base for custom attribute transforms, which implement `serialize` and `deserialize` to convert values between payloads and records. Transform --- # Transform Defined in: [warp-drive-packages/legacy/src/serializer/-private/transforms/transform.ts:5](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/serializer/-private/transforms/transform.ts#L5) The `Transform` class is used to serialize and deserialize model attributes when they are saved or loaded from an adapter. Subclassing `Transform` is useful for creating custom attributes. All subclasses of `Transform` must implement a `serialize` and a `deserialize` method. Example ```js [app/transforms/temperature.js] // Converts centigrade in the JSON to fahrenheit in the app export default class TemperatureTransform { deserialize(serialized, options) { return (serialized * 1.8) + 32; } serialize(deserialized, options) { return (deserialized - 32) / 1.8; } static create() { return new this(); } } ``` Usage ```js [app/models/requirement.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class RequirementModel extends Model { @attr('string') name; @attr('temperature') temperature; } ``` The options passed into the `attr` function when the attribute is declared on the model is also available in the transform. ```js [app/models/post.js] import { Model, attr } from '@warp-drive/legacy/model'; export default class PostModel extends Model { @attr('string') title; @attr('markdown', { markdown: { gfm: false, sanitize: true } }) markdown; } ``` ```js [app/transforms/markdown.js] export default class MarkdownTransform { serialize(deserialized, options) { return deserialized.raw; } deserialize(serialized, options) { let markdownOptions = options.markdown || {}; return marked(serialized, markdownOptions); } static create() { return new this(); } } ``` ## Constructors ### Constructor ```ts new Transform(owner?: Owner): Transform; ``` #### Parameters ##### owner? `Owner` #### Returns `Transform` --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/serializer/transform.md description: >- Legacy transforms that serialize and deserialize attribute values: the `Transform` base class plus the boolean, date, number and string transforms. --- ## Classes * [BooleanTransform](classes/BooleanTransform.md) * [DateTransform](classes/DateTransform.md) * [NumberTransform](classes/NumberTransform.md) * [StringTransform](classes/StringTransform.md) * [Transform](classes/Transform.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/store/functions/restoreDeprecatedStoreBehaviors.md description: >- Legacy opt-in that restores the adapter-based `findRecord`, `findAll`, `query`, `saveRecord`, and related methods onto a `Store` class. --- # restoreDeprecatedStoreBehaviors() ```ts function restoreDeprecatedStoreBehaviors(StoreKlass: typeof Store$1): void; ``` Defined in: [warp-drive-packages/legacy/src/store.ts:43](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/store.ts#L43) Restores the deprecated `findRecord`/`findAll`/`query`/`queryRecord`/ `findBelongsTo`/`findHasMany`/`createRecord`/`deleteRecord`/`saveRecord` legacy-network-layer implementations of these methods onto the given `Store` subclass, for apps that have not yet migrated to the `RequestManager`-based equivalents. ## Parameters ### StoreKlass *typeof* `Store$1` ## Returns `void` --- --- url: https://canary.warp-drive.io/api/@warp-drive/legacy/store.md description: >- Legacy `restoreDeprecatedStoreBehaviors`, which restores the adapter-based `findRecord`, `findAll`, `query`, `saveRecord` and related methods onto a `Store` class. --- ## Functions * [restoreDeprecatedStoreBehaviors](functions/restoreDeprecatedStoreBehaviors.md) --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/types/LegacyModelAndNetworkAndRequestStoreSetupOptions.md description: >- `useLegacyStore` options for a store that uses `Model`, the legacy adapter and serializer network layer, and deprecated request methods like `store.findRecord`. --- # LegacyModelAndNetworkAndRequestStoreSetupOptions\ ```ts interface LegacyModelAndNetworkAndRequestStoreSetupOptions extends _LegacyStoreSetupOptions { legacyRequests: true; linksMode: false; modelFragments?: boolean; schemas?: ( | ResourceSchema | ObjectSchema)[]; } ``` Defined in: [warp-drive-packages/legacy/src/index.ts:133](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L133) Setup options for a legacy store configured to use `Model` along with the legacy adapter/serializer network layer and the deprecated `store.findRecord`/`findAll`/`query`/etc. request methods. ## Extends * `_LegacyStoreSetupOptions`<`T`> ## Type Parameters ### T `T` *extends* `Cache` ## Properties ### legacyRequests ```ts legacyRequests: true; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:149](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L149) if true, all legacy request methods and supporting infrastructure will be available on the store. If legacyRequests is true, [linksMode](#linksmode) must be false #### Default ```ts false ``` *** ### linksMode ```ts linksMode: false; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:140](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L140) If true, it is presumed that no requests require use of the LegacyNetworkHandler and associated adapters/serializer methods. #### Default ```ts false ``` *** ### modelFragments? ```ts optional modelFragments?: boolean; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:64](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L64) Whether to include support for ModelFragments migrations. #### Default ```ts false ``` #### Inherited from ```ts _LegacyStoreSetupOptions.modelFragments ``` *** ### schemas? ```ts optional schemas?: ( | ResourceSchema | ObjectSchema)[]; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:57](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L57) The [ResourceSchemas](../../core/types/schema/fields/types/ResourceSchema.md) or [ObjectSchemas](../../core/types/schema/fields/types/ObjectSchema.md) of entities migrated to no longer use [Model](../model/classes/Model.md). :::caution [Model](../model/classes/Model.md) is still able to be used directly as a source of schema when using [useLegacyStore](../functions/useLegacyStore.md), however, its reliance on EmberObject, classic computeds and resolver behaviors mean that Model will stop working when these things are deprecated in Ember. ::: #### Inherited from ```ts _LegacyStoreSetupOptions.schemas ``` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/types/LegacyModelAndNetworkStoreSetupOptions.md description: >- `useLegacyStore` options for a store that uses `Model` and the legacy adapter and serializer network layer, without deprecated request methods like `store.findRecord`. --- # LegacyModelAndNetworkStoreSetupOptions\ ```ts interface LegacyModelAndNetworkStoreSetupOptions extends _LegacyStoreSetupOptions { legacyRequests?: false; linksMode: false; modelFragments?: boolean; schemas?: ( | ResourceSchema | ObjectSchema)[]; } ``` Defined in: [warp-drive-packages/legacy/src/index.ts:105](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L105) Setup options for a legacy store configured to use `Model` along with the legacy adapter/serializer network layer, but without the deprecated `store.findRecord`/`findAll`/`query`/etc. request methods. ## Extends * `_LegacyStoreSetupOptions`<`T`> ## Type Parameters ### T `T` *extends* `Cache` ## Properties ### legacyRequests? ```ts optional legacyRequests?: false; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:121](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L121) if true, all legacy request methods and supporting infrastructure will be available on the store. If legacyRequests is true, [linksMode](#linksmode) must be false #### Default ```ts false ``` *** ### linksMode ```ts linksMode: false; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:112](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L112) If true, it is presumed that no requests require use of the LegacyNetworkHandler and associated adapters/serializer methods. #### Default ```ts false ``` *** ### modelFragments? ```ts optional modelFragments?: boolean; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:64](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L64) Whether to include support for ModelFragments migrations. #### Default ```ts false ``` #### Inherited from ```ts _LegacyStoreSetupOptions.modelFragments ``` *** ### schemas? ```ts optional schemas?: ( | ResourceSchema | ObjectSchema)[]; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:57](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L57) The [ResourceSchemas](../../core/types/schema/fields/types/ResourceSchema.md) or [ObjectSchemas](../../core/types/schema/fields/types/ObjectSchema.md) of entities migrated to no longer use [Model](../model/classes/Model.md). :::caution [Model](../model/classes/Model.md) is still able to be used directly as a source of schema when using [useLegacyStore](../functions/useLegacyStore.md), however, its reliance on EmberObject, classic computeds and resolver behaviors mean that Model will stop working when these things are deprecated in Ember. ::: #### Inherited from ```ts _LegacyStoreSetupOptions.schemas ``` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/types/LegacyModelStoreSetupOptions.md description: >- `useLegacyStore` options for a store that uses `Model` in `linksMode`, without the legacy adapter and serializer network layer. --- # LegacyModelStoreSetupOptions\ ```ts interface LegacyModelStoreSetupOptions extends _LegacyStoreSetupOptions { legacyRequests?: false; linksMode: true; modelFragments?: boolean; schemas?: ( | ResourceSchema | ObjectSchema)[]; } ``` Defined in: [warp-drive-packages/legacy/src/index.ts:75](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L75) Setup options for a legacy store configured to use `Model` with `linksMode` enabled, meaning no legacy adapter/serializer request infrastructure is required. ## Extends * `_LegacyStoreSetupOptions`<`T`> ## Type Parameters ### T `T` *extends* `Cache` ## Properties ### legacyRequests? ```ts optional legacyRequests?: false; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:93](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L93) if true, all legacy request methods and supporting infrastructure will be available on the store. If legacyRequests is true, [linksMode](#linksmode) must be false #### Default ```ts false ``` *** ### linksMode ```ts linksMode: true; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:84](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L84) If true, it is presumed that no requests require use of the LegacyNetworkHandler and associated adapters/serializer methods. If legacyRequests is true, [linksMode](#linksmode) must be false #### Default ```ts false ``` *** ### modelFragments? ```ts optional modelFragments?: boolean; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:64](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L64) Whether to include support for ModelFragments migrations. #### Default ```ts false ``` #### Inherited from ```ts _LegacyStoreSetupOptions.modelFragments ``` *** ### schemas? ```ts optional schemas?: ( | ResourceSchema | ObjectSchema)[]; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:57](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L57) The [ResourceSchemas](../../core/types/schema/fields/types/ResourceSchema.md) or [ObjectSchemas](../../core/types/schema/fields/types/ObjectSchema.md) of entities migrated to no longer use [Model](../model/classes/Model.md). :::caution [Model](../model/classes/Model.md) is still able to be used directly as a source of schema when using [useLegacyStore](../functions/useLegacyStore.md), however, its reliance on EmberObject, classic computeds and resolver behaviors mean that Model will stop working when these things are deprecated in Ember. ::: #### Inherited from ```ts _LegacyStoreSetupOptions.schemas ``` --- --- url: >- https://canary.warp-drive.io/api/@warp-drive/legacy/types/LegacyStoreSetupOptions.md description: >- Options accepted by `useLegacyStore`, choosing via `linksMode` and `legacyRequests` how much of the legacy `Model`, adapter, and request support to enable. --- # LegacyStoreSetupOptions\ ```ts type LegacyStoreSetupOptions = | LegacyModelStoreSetupOptions | LegacyModelAndNetworkStoreSetupOptions | LegacyModelAndNetworkAndRequestStoreSetupOptions; ``` Defined in: [warp-drive-packages/legacy/src/index.ts:165](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/warp-drive-packages/legacy/src/index.ts#L165) The available options when setting up the legacy store, one of: * [LegacyModelStoreSetupOptions](LegacyModelStoreSetupOptions.md) * [LegacyModelAndNetworkStoreSetupOptions](LegacyModelAndNetworkStoreSetupOptions.md) * [LegacyModelAndNetworkAndRequestStoreSetupOptions](LegacyModelAndNetworkAndRequestStoreSetupOptions.md) ## Type Parameters ### T `T` *extends* `Cache` = `Cache` --- --- url: https://canary.warp-drive.io/api/@ember-data/adapter.md description: >- (Legacy) REST and JSON:API implementations of the Adapter interface, re-exported from `@warp-drive/legacy/adapter`; new apps should write request handlers for the `RequestManager` instead. --- :::warning Legacy package `@ember-data/adapter` is a legacy package. Adapters are no longer encouraged; new code should use [Handlers](/api/@warp-drive/core/request/types/Handler) with the `RequestManager` from [`@warp-drive/core`](/api/@warp-drive/core/) instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: This package provides REST and [{json:api}](https://jsonapi.org) Implementations of the legacy Adapter Interface when using the older packages. It re-exports [`@warp-drive/legacy/adapter`](/api/@warp-drive/legacy/adapter/), whose documentation covers implementing Adapters, why they are legacy and what replaces them. --- --- url: https://canary.warp-drive.io/api/@ember-data/adapter/error.md description: >- Legacy alias that re-exports `AdapterError` and its subclasses (invalid, timeout, abort, 401, 403, 404, 409, 5xx) from `@warp-drive/legacy/adapter/error`. --- :::warning Legacy package `@ember-data/adapter` is a legacy package. Adapters are no longer encouraged; new code should use [Handlers](/api/@warp-drive/core/request/types/Handler) with the `RequestManager` from [`@warp-drive/core`](/api/@warp-drive/core/) instead. ::: Legacy alias of [@warp-drive/legacy/adapter/error](../../../@warp-drive/legacy/adapter/error/index.md). This entry re-exports the adapter error classes from that module unchanged so existing `@ember-data/adapter/error` imports keep working; new code should import from `@warp-drive/legacy/adapter/error` directly. --- --- url: https://canary.warp-drive.io/api/@ember-data/adapter/json-api.md description: >- Legacy alias that re-exports `JSONAPIAdapter` from `@warp-drive/legacy/adapter/json-api` so `@ember-data/adapter/json-api` imports keep working. --- :::warning Legacy package `@ember-data/adapter` is a legacy package. Adapters are no longer encouraged; new code should use [Handlers](/api/@warp-drive/core/request/types/Handler) with the `RequestManager` from [`@warp-drive/core`](/api/@warp-drive/core/) instead. ::: Legacy alias of [@warp-drive/legacy/adapter/json-api](../../../@warp-drive/legacy/adapter/json-api/index.md). This entry re-exports the JSON:API adapter from that module unchanged so existing `@ember-data/adapter/json-api` imports keep working; new code should import from `@warp-drive/legacy/adapter/json-api` directly. --- --- url: https://canary.warp-drive.io/api/@ember-data/adapter/rest.md description: >- Legacy alias that re-exports `RESTAdapter`, `fetchOptions`, and their request types from `@warp-drive/legacy/adapter/rest` so `@ember-data/adapter/rest` imports keep working. --- :::warning Legacy package `@ember-data/adapter` is a legacy package. Adapters are no longer encouraged; new code should use [Handlers](/api/@warp-drive/core/request/types/Handler) with the `RequestManager` from [`@warp-drive/core`](/api/@warp-drive/core/) instead. ::: Legacy alias of [@warp-drive/legacy/adapter/rest](../../../@warp-drive/legacy/adapter/rest/index.md). This entry re-exports the REST adapter from that module unchanged so existing `@ember-data/adapter/rest` imports keep working; new code should import from `@warp-drive/legacy/adapter/rest` directly. --- --- url: https://canary.warp-drive.io/api/@ember-data/active-record.md description: >- (Legacy) ActiveRecord request builders such as `findRecord` and `query` that produce underscored, pluralized URLs; new apps should use `@warp-drive/utilities/active-record` instead. --- :::warning Legacy package `@ember-data/active-record` is a legacy package. New code should use [`@warp-drive/utilities/active-record`](/api/@warp-drive/utilities/active-record/) instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: This package used to provide the RequestManager and its related facilities. The source-code has since been moved to [@warp-drive/utilities](../../@warp-drive/utilities/index.md) and this package now exists solely to provide backwards compatibility. *** This package provides utilities for working with [ActiveRecord](https://guides.rubyonrails.org/active_record_basics.html#convention-over-configuration-in-active-record) APIs. ## Installation Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/) ::: code-group ```sh [pnpm] pnpm add -E @ember-data/active-record ``` ```sh [npm] npm add -E @ember-data/active-record ``` ```sh [yarn] yarn add -E @ember-data/active-record ``` ```sh [bun] bun add --exact @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 construct a request that would fetch a resource from your API: ```ts import { findRecord } from '@ember-data/active-record/request'; const options = findRecord('ember-developer', '1', { include: ['pets', 'friends'] }); ``` This would produce the following request object: ```js { url: 'https://api.example.com/v1/ember_developers/1?include=friends,pets', method: 'GET', headers: , // 'Accept': '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`. ```ts const data = await store.request(options); ``` 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). --- --- url: https://canary.warp-drive.io/api/@ember-data/active-record/request.md description: >- Legacy alias that re-exports the ActiveRecord-style request builders (`findRecord`, `query`, `createRecord`, `updateRecord`, `deleteRecord`) from `@warp-drive/utilities/active-record`. --- :::warning Legacy package `@ember-data/active-record` is a legacy package. New code should use [`@warp-drive/utilities/active-record`](/api/@warp-drive/utilities/active-record/) instead. ::: Legacy alias of [@warp-drive/utilities/active-record](../../../@warp-drive/utilities/active-record/index.md). This entry re-exports the request builders from that module unchanged so existing `@ember-data/active-record/request` imports keep working; new code should import from `@warp-drive/utilities/active-record` directly. --- --- url: https://canary.warp-drive.io/api/@ember-data/legacy-compat.md description: >- (Legacy) Shims such as `LegacyNetworkHandler`, `adapterFor` and `serializerFor` that keep Adapters and Serializers working with the `RequestManager`; now published as `@warp-drive/legacy/compat`. --- :::warning Legacy package `@ember-data/legacy-compat` is a legacy package. It bridges Models, Adapters, and Serializers to the `RequestManager` and cache; new code should skip it and start from [`@warp-drive/core`](/api/@warp-drive/core/) with schemas, Handlers, and request builders. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: This package exists to help apps migrate incrementally from legacy EmberData patterns to modern WarpDrive. It re-exports [`@warp-drive/legacy/compat`](/api/@warp-drive/legacy/compat/), whose documentation covers why it exists, what it provides and when to use it. --- --- url: https://canary.warp-drive.io/api/@ember-data/legacy-compat/builders.md description: >- Deprecated request builders (`findAll`, `findRecord`, `query`, `queryRecord`, `saveRecord`) that move store method calls onto `store.request` while keeping adapter behavior. --- :::warning Legacy package `@ember-data/legacy-compat` is a legacy package. It bridges Models, Adapters, and Serializers to the `RequestManager` and cache; new code should skip it and start from [`@warp-drive/core`](/api/@warp-drive/core/) with schemas, Handlers, and request builders. ::: Builders for migrating from `store` methods to `store.request`. These builders enable you to migrate your codebase to using the correct syntax for `store.request` while temporarily preserving legacy behaviors. This is useful for quickly upgrading an entire app to a unified syntax while a longer incremental migration is made to shift off of adapters and serializers. To that end, these builders are deprecated and will be removed in a future version of Ember Data. ## Deprecated --- --- url: https://canary.warp-drive.io/api/@ember-data/legacy-compat/utils.md description: >- Deprecated helpers for normalizing and checking resource types and IDs (`formattedType`, `formattedId`, `expectId`, `isEquivType`, `isEquivId`) and configuring mismatch reporting. --- :::warning Legacy package `@ember-data/legacy-compat` is a legacy package. It bridges Models, Adapters, and Serializers to the `RequestManager` and cache; new code should skip it and start from [`@warp-drive/core`](/api/@warp-drive/core/) with schemas, Handlers, and request builders. ::: Utilities for helping to migrate to stricter and more consistent use of IDs and types. ## Deprecated --- --- url: https://canary.warp-drive.io/api/@ember-data/model.md description: >- (Legacy) `Model` class and its `attr`, `belongsTo` and `hasMany` decorators, re-exported from `@warp-drive/legacy/model`; new apps should define schemas for `@warp-drive/core` instead. --- :::warning Legacy package `@ember-data/model` is a legacy package. Model classes are no longer encouraged; new code should define schemas with [`@warp-drive/core`](/api/@warp-drive/core/). Apps that still need Models should install them through [`@warp-drive/legacy`](/api/@warp-drive/legacy/) rather than this package. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: This package provides runtime classes for use as a source of ResourceSchema and as a ReactiveResource for older "legacy" EmberData/WarpDrive configurations. It re-exports [`@warp-drive/legacy/model`](/api/@warp-drive/legacy/model/), whose documentation covers defining Models, why they are legacy and what replaces them. --- --- url: https://canary.warp-drive.io/api/@ember-data/model/hooks.md description: >- Legacy alias that re-exports the `Model` lifecycle hooks `instantiateRecord`, `teardownRecord`, `modelFor`, and `buildSchema` from `@warp-drive/legacy/model`. --- :::warning Legacy package `@ember-data/model` is a legacy package. Model classes are no longer encouraged; new code should define schemas with [`@warp-drive/core`](/api/@warp-drive/core/). Apps that still need Models should install them through [`@warp-drive/legacy`](/api/@warp-drive/legacy/) rather than this package. ::: Legacy alias of [@warp-drive/legacy/model](../../../@warp-drive/legacy/model/index.md). This entry re-exports the model lifecycle hooks from that module unchanged so existing `@ember-data/model/hooks` imports keep working; new code should import from `@warp-drive/legacy/model` directly. --- --- url: https://canary.warp-drive.io/api/@ember-data/model/migration-support.md description: >- Legacy helpers (`withDefaults`, `registerDerivations`, `DelegatingSchemaService`, `WithLegacy`) for migrating from `@ember-data/model` to schema-driven records in LegacyMode. --- :::warning Legacy package `@ember-data/model` is a legacy package. Model classes are no longer encouraged; new code should define schemas with [`@warp-drive/core`](/api/@warp-drive/core/). Apps that still need Models should install them through [`@warp-drive/legacy`](/api/@warp-drive/legacy/) rather than this package. ::: This module provides support for migrating away from @ember-data/model to @warp-drive/schema-record. It includes: * A `withDefaults` function to assist in creating a schema in LegacyMode * A `registerDerivations` function to register the derivations necessary to support LegacyMode * A `DelegatingSchemaService` that can be used to provide a schema service that works with both @ember-data/model and @warp-drive/schema-record simultaneously for migration purposes. * A `WithLegacy` type util that can be used to create a type that includes the legacy properties and methods of a record. Using LegacyMode features on a ReactiveResource *requires* the use of these derivations and schema additions. LegacyMode is not intended to be a long-term solution, but rather a stepping stone to assist in more rapidly adopting modern WarpDrive features. --- --- url: https://canary.warp-drive.io/api/@ember-data/json-api.md description: >- (Legacy) JSON:API document and resource cache for the `@ember-data/*` packages, re-exporting `JSONAPICache`; new apps should import it from `@warp-drive/json-api` instead. --- :::warning Legacy package `@ember-data/json-api` is a legacy package. New code should use [`@warp-drive/json-api`](/api/@warp-drive/json-api/) for the cache and [`@warp-drive/utilities`](/api/@warp-drive/utilities/) for the request builders instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: ## Overview This package provides an in-memory [{json:api}](https://jsonapi.org/) document and resource [Cache](/api/@warp-drive/core/types/cache/types/Cache) implementation for use with the older EmberData package setup. **Why it's legacy:** This package was created when EmberData and WarpDrive were tightly coupled. Modern WarpDrive has: * Moved the cache implementation to [@warp-drive/json-api](../../@warp-drive/json-api/index.md) * Moved the request builders to [@warp-drive/utilities](../../@warp-drive/utilities/index.md) * Improved type safety and tree shaking **Modern alternative:** Use [@warp-drive/json-api](../../@warp-drive/json-api/index.md) for the cache and [@warp-drive/utilities](../../@warp-drive/utilities/index.md) for request builders. **When you still need this:** Only use this package if you're maintaining an existing Ember application that hasn't migrated to the modern WarpDrive packages. For guidance on migration, see the [Migration Guide](/upgrading/v5/). ## Installation Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/) ```sh pnpm add @ember-data/json-api ``` ## Setup > **Note:** When using [ember-data](https://github.com/warp-drive-data/warp-drive/blob/main/packages/-ember-data) the below configuration is handled for you automatically. ```ts import Store from '@ember-data/store'; import Cache from '@ember-data/json-api'; export default class extends Store { createCache(wrapper) { return new Cache(wrapper); } } ``` ## Usage Usually you will directly interact with the cache only if implementing a presentation class. Below we give an example of a read-only record (mutations never written back to the cache). More typically cache interactions are something that the `Store` coordinates as part of the `request/response` lifecycle. ```ts import Store, { recordIdentifierFor } from '@ember-data/store'; import Cache from '@ember-data/json-api'; import { TrackedObject } from 'tracked-built-ins'; class extends Store { createCache(wrapper) { return new Cache(wrapper); } instantiateRecord(identifier) { const { cache, notifications } = this; const { type, id } = identifier; // create a TrackedObject with our attributes, id and type const attrs = cache.peek(identifier).attributes; const data = Object.assign({}, attrs, { type, id }); const record = new TrackedObject(data); // update the TrackedObject whenever attributes change const token = notifications.subscribe(identifier, (_, change) => { if (change === 'attributes') { Object.assign(record, cache.peek(identifier).attributes); } }); // setup the ability to teardown the subscription when the // record is no longer needed record.destroy = () => { this.notifications.unsubscribe(token); }; return record; } teardownRecord(record: FakeRecord) { record.destroy(); } } ``` For the full list of APIs, see the documentation for [Cache](/api/@warp-drive/core/types/cache/types/Cache). --- --- url: https://canary.warp-drive.io/api/@ember-data/json-api/request.md description: >- Legacy alias re-exporting request builders from `@warp-drive/utilities/json-api` that produce fetch options with stable JSON:API URLs for `store.request`. --- :::warning Legacy package `@ember-data/json-api` is a legacy package. New code should use [`@warp-drive/json-api`](/api/@warp-drive/json-api/) for the cache and [`@warp-drive/utilities`](/api/@warp-drive/utilities/) for the request builders instead. ::: This package provides utilities for working with [JSON:API](https://jsonapi.org) APIs with [*Ember***Data**](https://github.com/warp-drive-data/warp-drive/). ## Installation Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/) ```sh 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. For instance, to fetch a resource from your API ::: code-group ```ts [input.ts] import { findRecord } from '@ember-data/json-api/request'; const options = findRecord('ember-developer', '1', { include: ['pets', 'friends'] }); ``` ```ts [output.ts] { url: 'https://api.example.com/v1/ember-developers/1?include=friends,pets', method: 'GET', headers: , // => 'Accept': 'application/vnd.api+json' // => 'Content-Type': 'application/vnd.api+json' 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 JSON:API format (dasherized pluralized resource types). --- --- url: https://canary.warp-drive.io/api/@ember-data/store.md description: >- (Legacy) EmberData `Store` class that coordinates the cache, the `RequestManager` and record presentation; new apps should use the `Store` from `@warp-drive/core` instead. --- :::warning Legacy package `@ember-data/store` is a legacy package. New code should use [`@warp-drive/core`](/api/@warp-drive/core/) instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: This package re-exports the `Store` from [`@warp-drive/core`](/api/@warp-drive/core/), whose documentation covers it. To configure a Store with these packages, see [Configure the Store](/guides/configuration/legacy-package-setup/setup/universal.md#configure-the-store). --- --- url: https://canary.warp-drive.io/api/@ember-data/store/configure.md description: >- Re-exports `setupSignals`, which configures the signals implementation WarpDrive uses for reactivity. --- :::warning Legacy package `@ember-data/store` is a legacy package. New code should use [`@warp-drive/core`](/api/@warp-drive/core/) instead. ::: Provides a configuration API for the reactivity system that WarpDrive should use. --- --- url: https://canary.warp-drive.io/api/@ember-data/store/types.md description: >- Legacy alias that re-exports the store public types (schema service, finder options, model schema, and more) from `@warp-drive/core/types`. --- :::warning Legacy package `@ember-data/store` is a legacy package. New code should use [`@warp-drive/core`](/api/@warp-drive/core/) instead. ::: Legacy alias of [@warp-drive/core/types](../../../@warp-drive/core/types/index.md). This entry re-exports the store's public types from that module unchanged so existing `@ember-data/store/types` imports keep working; new code should import from `@warp-drive/core/types` directly. --- --- url: https://canary.warp-drive.io/api/@ember-data/graph.md description: >- (Internal) Package re-exporting the relationship graph from `@warp-drive/core` for use by the JSON:API cache; not intended for direct application use. --- :::warning Legacy package `@ember-data/graph` is a legacy package. It re-exports the relationship graph that the JSON:API cache uses internally. Apps should not depend on it, or on the private graph module in `@warp-drive/core` it re-exports. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: --- --- url: https://canary.warp-drive.io/api/@ember-data/request.md description: >- (Legacy) Package that once provided the `RequestManager` and its related facilities; new apps should import them from `@warp-drive/core` instead. --- :::warning Legacy package `@ember-data/request` is a legacy package. New code should use [`@warp-drive/core`](/api/@warp-drive/core/) instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: This package used to provide the RequestManager and its related facilities. The source-code has since been moved to [@warp-drive/core](../../@warp-drive/core/index.md) and this package now exists solely to provide backwards compatibility. See also [RequestManager](../../@warp-drive/core/classes/RequestManager.md) and [Store.request](../../@warp-drive/core/classes/Store.md#request). --- --- url: https://canary.warp-drive.io/api/@ember-data/request/fetch.md description: >- Legacy entry re-exporting `Fetch`, a request handler that sends each request with `fetch` and parses the response as JSON. --- :::warning Legacy package `@ember-data/request` is a legacy package. New code should use [`@warp-drive/core`](/api/@warp-drive/core/) instead. ::: A basic Fetch Handler which converts a request into a `fetch` call presuming the response to be `json`. ```ts import Fetch from '@ember-data/request/fetch'; manager.use([Fetch]); ``` --- --- url: https://canary.warp-drive.io/api/@ember-data/request-utils.md description: >- (Legacy) URL and query-param helpers such as `buildBaseURL` and `buildQueryParams` for request builders; new apps should import them from `@warp-drive/utilities` instead. --- :::warning Legacy package `@ember-data/request-utils` is a legacy package. New code should use [`@warp-drive/utilities`](/api/@warp-drive/utilities/) instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: Simple utility functions to assist in url building, query params, and other common request operations. These primitives may be used directly or composed by request builders to provide a consistent interface for building requests. For instance: ```ts import { buildBaseURL, buildQueryParams } from '@ember-data/request-utils'; const baseURL = buildBaseURL({ host: 'https://api.example.com', namespace: 'api/v1', resourcePath: 'emberDevelopers', op: 'query', identifier: { type: 'ember-developer' } }); const url = `${baseURL}?${buildQueryParams({ name: 'Chris', include:['pets'] })}`; // => 'https://api.example.com/api/v1/emberDevelopers?include=pets&name=Chris' ``` This is useful, but not as useful as the REST request builder for query which is sugar over this (and more!): ```ts import { query } from '@ember-data/rest/request'; const options = query('ember-developer', { name: 'Chris', include:['pets'] }); // => { url: 'https://api.example.com/api/v1/emberDevelopers?include=pets&name=Chris' } // Note: options will also include other request options like headers, method, etc. ``` ## Classes * [LifetimesService](classes/LifetimesService.md) --- --- url: >- https://canary.warp-drive.io/api/@ember-data/request-utils/classes/LifetimesService.md --- :::warning Legacy package `@ember-data/request-utils` is a legacy package. New code should use [`@warp-drive/utilities`](/api/@warp-drive/utilities/) instead. ::: # LifetimesService Defined in: [index.ts:21](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/packages/request-utils/src/index.ts#L21) ## Extends * `DefaultCachePolicy` ## Constructors ### Constructor ```ts new LifetimesService(config: PolicyConfig): LifetimesService; ``` Defined in: [index.ts:22](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/packages/request-utils/src/index.ts#L22) #### Parameters ##### config `PolicyConfig` #### Returns `LifetimesService` #### Overrides ```ts DefaultCachePolicy.constructor ``` --- --- url: https://canary.warp-drive.io/api/@ember-data/request-utils/handlers.md description: >- Re-exports prebuilt request handlers such as `Gate`, `AutoCompress`, and `MetaDocHandler`, plus header and URL-length helpers, from `@warp-drive/utilities/handlers`. --- :::warning Legacy package `@ember-data/request-utils` is a legacy package. New code should use [`@warp-drive/utilities`](/api/@warp-drive/utilities/) instead. ::: A selection of pre-built request handlers for handling common request scenarios. --- --- url: https://canary.warp-drive.io/api/@ember-data/request-utils/string.md description: >- Re-exports LRU-cached string inflection and case helpers (`pluralize`, `singularize`, `camelize`, `dasherize`, and others) from `@warp-drive/utilities/string`. --- :::warning Legacy package `@ember-data/request-utils` is a legacy package. New code should use [`@warp-drive/utilities`](/api/@warp-drive/utilities/) instead. ::: String utilties for transforming and inflecting strings useful for when the format provided by the server is not the format you want to use in your application. Each transformation function stores its results in an LRUCache to avoid recomputing the same value multiple times. The cache size can be set using the `setMaxLRUCacheSize` function. The default size is 10,000. --- --- url: https://canary.warp-drive.io/api/@ember-data/rest.md description: >- (Legacy) REST request builders such as `findRecord`, `query` and `createRecord` that produce camelCase, pluralized URLs; new apps should import them from `@warp-drive/utilities/rest` instead. --- :::warning Legacy package `@ember-data/rest` is a legacy package. New code should use [`@warp-drive/utilities/rest`](/api/@warp-drive/utilities/rest/) instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: Request builders for **REST**ful APIs. A request builder is a function that takes the few things that vary about a request, such as the resource type, an id, or query params, and returns the request options object you pass to `store.request()`: the `url`, `method`, and `headers`, plus the ***Warp*Drive**-specific fields such as `op` that let the cache understand the request. The builders live in the [`@ember-data/rest/request`](/api/@ember-data/rest/request/) entry point. The output works with either `store.request()` or `requestManager.request()`. URLs are stable: the same query produces 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 REST format, camelCase pluralized resource types. --- --- url: https://canary.warp-drive.io/api/@ember-data/rest/request.md description: >- Legacy alias re-exporting request builders from `@warp-drive/utilities/rest` that produce fetch options with * stable, camelCase pluralized REST URLs. * --- :::warning Legacy package `@ember-data/rest` is a legacy package. New code should use [`@warp-drive/utilities/rest`](/api/@warp-drive/utilities/rest/) instead. ::: This package provides utilities for working with **REST**ful APIs with [*Ember***Data**](https://github.com/warp-drive-data/warp-drive/). ## 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 ::: code-group ```ts [input.ts] import { findRecord } from '@ember-data/rest/request'; const options = findRecord('ember-developer', '1', { include: ['pets', 'friends'] }); ``` ```ts [output.ts] { url: 'https://api.example.com/v1/emberDevelopers/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 is ready to go for use with [store.request](../../../@warp-drive/core/classes/Store.md#request), [manager.request](../../../@warp-drive/core/classes/RequestManager.md#request) and most conventional REST APIs. Resource types are pluralized and camelized for the url. 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 REST format (camelCase pluralized resource types). These builders are re-exported from [@warp-drive/utilities/rest](../../../@warp-drive/utilities/rest/index.md); new code should import from there. * --- --- url: https://canary.warp-drive.io/api/@ember-data/serializer.md description: >- (Legacy) JSON, REST and JSON:API implementations of the Serializer interface, re-exported from `@warp-drive/legacy/serializer`; new apps should normalize data in request handlers instead. --- :::warning Legacy package `@ember-data/serializer` is a legacy package. Serializers are no longer encouraged; new code should use [Handlers](/api/@warp-drive/core/request/types/Handler) with the `RequestManager` from [`@warp-drive/core`](/api/@warp-drive/core/) instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: This package provides JSON, REST and JSON:API Implementations of the legacy Serializer Interface. It re-exports [`@warp-drive/legacy/serializer`](/api/@warp-drive/legacy/serializer/), whose documentation covers setting up and implementing Serializers, why they are legacy and what replaces them. --- --- url: https://canary.warp-drive.io/api/@ember-data/serializer/json-api.md description: >- Legacy alias that re-exports `JSONAPISerializer` from `@warp-drive/legacy/serializer/json-api` so `@ember-data/serializer/json-api` imports keep working. --- :::warning Legacy package `@ember-data/serializer` is a legacy package. Serializers are no longer encouraged; new code should use [Handlers](/api/@warp-drive/core/request/types/Handler) with the `RequestManager` from [`@warp-drive/core`](/api/@warp-drive/core/) instead. ::: Legacy alias of [@warp-drive/legacy/serializer/json-api](../../../@warp-drive/legacy/serializer/json-api/index.md). This entry re-exports the JSON:API serializer from that module unchanged so existing `@ember-data/serializer/json-api` imports keep working; new code should import from `@warp-drive/legacy/serializer/json-api` directly. --- --- url: https://canary.warp-drive.io/api/@ember-data/serializer/json.md description: >- Legacy alias that re-exports `JSONSerializer` from `@warp-drive/legacy/serializer/json` so `@ember-data/serializer/json` imports keep working. --- :::warning Legacy package `@ember-data/serializer` is a legacy package. Serializers are no longer encouraged; new code should use [Handlers](/api/@warp-drive/core/request/types/Handler) with the `RequestManager` from [`@warp-drive/core`](/api/@warp-drive/core/) instead. ::: Legacy alias of [@warp-drive/legacy/serializer/json](../../../@warp-drive/legacy/serializer/json/index.md). This entry re-exports the JSON serializer from that module unchanged so existing `@ember-data/serializer/json` imports keep working; new code should import from `@warp-drive/legacy/serializer/json` directly. --- --- url: https://canary.warp-drive.io/api/@ember-data/serializer/rest.md description: >- Legacy alias that re-exports `RESTSerializer` and `EmbeddedRecordsMixin` from `@warp-drive/legacy/serializer/rest` so `@ember-data/serializer/rest` imports keep working. --- :::warning Legacy package `@ember-data/serializer` is a legacy package. Serializers are no longer encouraged; new code should use [Handlers](/api/@warp-drive/core/request/types/Handler) with the `RequestManager` from [`@warp-drive/core`](/api/@warp-drive/core/) instead. ::: Legacy alias of [@warp-drive/legacy/serializer/rest](../../../@warp-drive/legacy/serializer/rest/index.md). This entry re-exports the REST serializer from that module unchanged so existing `@ember-data/serializer/rest` imports keep working; new code should import from `@warp-drive/legacy/serializer/rest` directly. --- --- url: https://canary.warp-drive.io/api/@ember-data/serializer/transform.md description: >- Legacy alias that re-exports the base `Transform` and the boolean, string, number, and date attribute transforms from `@warp-drive/legacy/serializer/transform`. --- :::warning Legacy package `@ember-data/serializer` is a legacy package. Serializers are no longer encouraged; new code should use [Handlers](/api/@warp-drive/core/request/types/Handler) with the `RequestManager` from [`@warp-drive/core`](/api/@warp-drive/core/) instead. ::: Legacy alias of [@warp-drive/legacy/serializer/transform](../../../@warp-drive/legacy/serializer/transform/index.md). This entry re-exports the attribute transforms from that module unchanged so existing `@ember-data/serializer/transform` imports keep working; new code should import from `@warp-drive/legacy/serializer/transform` directly. --- --- url: https://canary.warp-drive.io/api/@ember-data/tracking.md description: >- (Deprecated) Package that once wired WarpDrive into Ember's reactivity system; remove it and install `@warp-drive/ember` instead, following the migration steps on this page. --- :::warning Deprecated package `@ember-data/tracking` is deprecated. Deprecated since 5.5: the Ember reactivity bindings it provided now come from [`@warp-drive/ember`](/api/@warp-drive/ember/), so remove it and install that instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: Historically, this package configured ***Warp*Drive** to use EmberJS's reactivity system. ## Migration Guide To resolve this deprecation, follow these steps: ### 1. Remove @ember-data/tracking * Remove `@ember-data/tracking` from package.json (if using `ember-data` this may not be present) * Remove the `@ember-data/tracking` entry from the `types` array in tsconfig.json, if present * If using `untracked`, change to using `untrack` from `@glimmer/validator` ### 2. Add @warp-drive/ember * Add `@warp-drive/ember` to package.json - the version to install should match the version of `ember-data` or `@ember-data/store` * Do NOT add `@warp-drive/ember` to tsconfig.json - the types in this package install automatically, you can remove any entry for this if it is there * Add `import '@warp-drive/ember/install';` to the top of your `app.js` or `app.ts` file ### 3. Clear the deprecation Once the above steps are complete, the deprecation can be silenced and the automatic fallback registration of reactivity from `@ember-data/tracking` can be removed by updating your [WarpDrive Build Config](../../@warp-drive/core/build-config/index.md) in your `ember-cli-build` file. On current versions `setConfig` is exported from `@warp-drive/core/build-config`; `@warp-drive/build-config` is its older home and still works. Set `compatWith` to the most recent `major.minor` your app has fully resolved deprecations for, not to the `4.12` shown. ```js [ember-cli-build.js] 'use strict'; const EmberApp = require('ember-cli/lib/broccoli/ember-app'); const { compatBuild } = require('@embroider/compat'); module.exports = async function (defaults) { const { setConfig } = await import('@warp-drive/build-config'); // [!code focus] const { buildOnce } = await import('@embroider/vite'); const app = new EmberApp(defaults, {}); setConfig(app, __dirname, { // [!code focus:9] // this should be the most recent . version for // which all deprecations have been fully resolved // and should be updated when that changes compatWith: '4.12', deprecations: { // ... list individual deprecations that have been resolved here DEPRECATE_TRACKING_PACKAGE: false // [!code highlight] } }); return compatBuild(app, buildOnce); }; ``` ## Functions * [~~buildSignalConfig~~](functions/buildSignalConfig.md) --- --- url: >- https://canary.warp-drive.io/api/@ember-data/tracking/functions/buildSignalConfig.md description: >- Deprecated: builds signal hooks that back WarpDrive reactivity with Ember tags; `@ember-data/store` registers it automatically, and `@warp-drive/ember` replaces it. --- :::warning Deprecated package `@ember-data/tracking` is deprecated. Deprecated since 5.5: the Ember reactivity bindings it provided now come from [`@warp-drive/ember`](/api/@warp-drive/ember/), so remove it and install that instead. ::: # ~~buildSignalConfig()~~ ```ts function buildSignalConfig(options: { wellknown: { Array: string | symbol; }; }): { createMemo: (object: object, key: string | symbol, fn: () => F) => () => F; waitFor: (promise: Promise) => Promise; willSyncFlushWatchers: () => boolean; consumeSignal: void; createSignal: Tag | [Tag, Tag, Tag]; notifySignal: void; }; ``` Defined in: [index.ts:36](https://github.com/warp-drive-data/warp-drive/blob/48dc0d277b98008082669dadc6a52e5c5682ef8e/packages/tracking/src/index.ts#L36) Creates a signal configuration object for WarpDrive that integrates with Ember's reactivity system. This will be automatically imported and registered by `@ember-data/store` if the deprecation has not been resolved. This function should not be called directly in your application code and this package is deprecated entirely. Use [@warp-drive/ember](../../../@warp-drive/ember/index.md) instead. ## Parameters ### options #### wellknown { `Array`: `string` | `symbol`; } #### wellknown.Array `string` | `symbol` ## Returns ```ts { createMemo: (object: object, key: string | symbol, fn: () => F) => () => F; waitFor: (promise: Promise) => Promise; willSyncFlushWatchers: () => boolean; consumeSignal: void; createSignal: Tag | [Tag, Tag, Tag]; notifySignal: void; } ``` ### ~~createMemo~~ ```ts createMemo: (object: object, key: string | symbol, fn: () => F) => () => F; ``` #### Type Parameters ##### F `F` #### Parameters ##### object `object` ##### key `string` | `symbol` ##### fn () => `F` #### Returns () => `F` ### ~~waitFor~~ ```ts waitFor: (promise: Promise) => Promise; ``` #### Type Parameters ##### K `K` #### Parameters ##### promise [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<`K`> #### Returns [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<`K`> ### ~~willSyncFlushWatchers~~ ```ts willSyncFlushWatchers: () => boolean; ``` #### Returns `boolean` ### ~~consumeSignal()~~ ```ts consumeSignal(signal: Tag | [Tag, Tag, Tag]): void; ``` #### Parameters ##### signal `Tag` | \[`Tag`, `Tag`, `Tag`] #### Returns `void` ### ~~createSignal()~~ ```ts createSignal(obj: object, key: string | symbol): Tag | [Tag, Tag, Tag]; ``` #### Parameters ##### obj `object` ##### key `string` | `symbol` #### Returns `Tag` | \[`Tag`, `Tag`, `Tag`] ### ~~notifySignal()~~ ```ts notifySignal(signal: Tag | [Tag, Tag, Tag]): void; ``` #### Parameters ##### signal `Tag` | \[`Tag`, `Tag`, `Tag`] #### Returns `void` ## Deprecated --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types.md description: >- (Legacy) Type-only re-exports of the `@warp-drive/core/types` modules, kept so existing `@warp-drive/core-types` imports compile; new code should import from `@warp-drive/core/types`. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: Every entry point in this package is a type-only re-export of the matching `@warp-drive/core/types/*` module, kept so existing `@warp-drive/core-types/*` imports keep compiling. Nothing is declared here; the documentation for each type lives on the `@warp-drive/core` page it comes from. | `@warp-drive/core-types` entry | re-exports | | ------------------------------ | ------------------------------------------------------------------------------------------- | | `.` (root) | [@warp-drive/core/types](../core/types/index.md) | | `/cache` | [@warp-drive/core/types/cache](../core/types/cache/index.md) | | `/cache/aliases` | [@warp-drive/core/types/cache/aliases](../core/types/cache/aliases/index.md) | | `/cache/change` | [@warp-drive/core/types/cache/change](../core/types/cache/change/index.md) | | `/cache/mutations` | [@warp-drive/core/types/cache/mutations](../core/types/cache/mutations/index.md) | | `/cache/operations` | [@warp-drive/core/types/cache/operations](../core/types/cache/operations/index.md) | | `/cache/relationship` | [@warp-drive/core/types/cache/relationship](../core/types/cache/relationship/index.md) | | `/graph` | [@warp-drive/core/types/graph](../core/types/graph/index.md) | | `/identifier` | [@warp-drive/core/types/identifier](../core/types/identifier/index.md) | | `/json/raw` | [@warp-drive/core/types/json/raw](../core/types/json/raw/index.md) | | `/params` | [@warp-drive/core/types/params](../core/types/params/index.md) | | `/record` | [@warp-drive/core/types/record](../core/types/record/index.md) | | `/request` | [@warp-drive/core/types/request](../core/types/request/index.md) | | `/schema/concepts` | [@warp-drive/core/types/schema/concepts](../core/types/schema/concepts/index.md) | | `/schema/fields` | [@warp-drive/core/types/schema/fields](../core/types/schema/fields/index.md) | | `/spec/document` | [@warp-drive/core/types/spec/document](../core/types/spec/document/index.md) | | `/spec/error` | [@warp-drive/core/types/spec/error](../core/types/spec/error/index.md) | | `/spec/json-api-raw` | [@warp-drive/core/types/spec/json-api-raw](../core/types/spec/json-api-raw/index.md) | | `/symbols` | [@warp-drive/core/types/symbols](../core/types/symbols/index.md) | | `/utils` | [@warp-drive/core/types/utils](../core/types/utils/index.md) | --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/cache/aliases.md description: >- Legacy alias re-exporting `@warp-drive/core/types/cache/aliases`, the opaque raw resource blob type; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/cache/aliases](../../../core/types/cache/aliases/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/cache/aliases` imports keep working; new code should import from `@warp-drive/core/types/cache/aliases` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/cache/change.md description: >- Legacy alias re-exporting `@warp-drive/core/types/cache/change`, the type for resource and document changes the cache records; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/cache/change](../../../core/types/cache/change/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/cache/change` imports keep working; new code should import from `@warp-drive/core/types/cache/change` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/cache.md description: >- Legacy alias re-exporting `@warp-drive/core/types/cache`, the Cache interface and its change types; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/cache](../../core/types/cache/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/cache` imports keep working; new code should import from `@warp-drive/core/types/cache` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/cache/mutations.md description: >- Legacy alias re-exporting `@warp-drive/core/types/cache/mutations`, the relationship mutations passed to `cache.mutate`; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/cache/mutations](../../../core/types/cache/mutations/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/cache/mutations` imports keep working; new code should import from `@warp-drive/core/types/cache/mutations` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/cache/operations.md description: >- Legacy alias re-exporting `@warp-drive/core/types/cache/operations`, the operations that add, update, merge, and remove cache data; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/cache/operations](../../../core/types/cache/operations/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/cache/operations` imports keep working; new code should import from `@warp-drive/core/types/cache/operations` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/cache/relationship.md description: >- Legacy alias re-exporting `@warp-drive/core/types/cache/relationship`, the cache-side to-one and to-many relationship state types; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/cache/relationship](../../../core/types/cache/relationship/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/cache/relationship` imports keep working; new code should import from `@warp-drive/core/types/cache/relationship` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/graph.md description: >- Legacy alias re-exporting `@warp-drive/core/types/graph`, the operation types that update the relationship graph; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/graph](../../core/types/graph/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/graph` imports keep working; new code should import from `@warp-drive/core/types/graph` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/identifier.md description: >- Legacy alias re-exporting `@warp-drive/core/types/identifier`, the resource and request cache key types; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/identifier](../../core/types/identifier/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/identifier` imports keep working; new code should import from `@warp-drive/core/types/identifier` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/json/raw.md description: >- Legacy alias re-exporting `@warp-drive/core/types/json/raw`, the types describing JSON-serializable values; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/json/raw](../../../core/types/json/raw/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/json/raw` imports keep working; new code should import from `@warp-drive/core/types/json/raw` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/params.md description: >- Legacy alias re-exporting `@warp-drive/core/types/params`, the types for serializable query params; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/params](../../core/types/params/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/params` imports keep working; new code should import from `@warp-drive/core/types/params` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/record.md description: >- Legacy alias re-exporting `@warp-drive/core/types/record`, the type utilities for typed records and include paths; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/record](../../core/types/record/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/record` imports keep working; new code should import from `@warp-drive/core/types/record` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/request.md description: >- Legacy alias re-exporting `@warp-drive/core/types/request`, the request option, cache option, and structured document types; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/request](../../core/types/request/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/request` imports keep working; new code should import from `@warp-drive/core/types/request` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/schema/concepts.md description: >- Legacy alias re-exporting `@warp-drive/core/types/schema/concepts`, the transformation, derivation, and hash function types; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/schema/concepts](../../../core/types/schema/concepts/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/schema/concepts` imports keep working; new code should import from `@warp-drive/core/types/schema/concepts` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/schema/fields.md description: >- Legacy alias re-exporting `@warp-drive/core/types/schema/fields`, the field and resource schema types; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/schema/fields](../../../core/types/schema/fields/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/schema/fields` imports keep working; new code should import from `@warp-drive/core/types/schema/fields` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/spec/document.md description: >- Legacy alias re-exporting `@warp-drive/core/types/spec/document`, the types for raw {json:api} response documents; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/spec/document](../../../core/types/spec/document/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/spec/document` imports keep working; new code should import from `@warp-drive/core/types/spec/document` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/spec/error.md description: >- Legacy alias re-exporting `@warp-drive/core/types/spec/error`, the {json:api} error object type; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/spec/error](../../../core/types/spec/error/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/spec/error` imports keep working; new code should import from `@warp-drive/core/types/spec/error` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/spec/json-api-raw.md description: >- Legacy alias re-exporting `@warp-drive/core/types/spec/json-api-raw`, the raw {json:api} resource, link, and meta types; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/spec/json-api-raw](../../../core/types/spec/json-api-raw/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/spec/json-api-raw` imports keep working; new code should import from `@warp-drive/core/types/spec/json-api-raw` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/symbols.md description: >- Legacy alias re-exporting `@warp-drive/core/types/symbols`, the symbols that brand typed records with their store, type, and request signature; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/symbols](../../core/types/symbols/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/symbols` imports keep working; new code should import from `@warp-drive/core/types/symbols` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/core-types/utils.md description: >- Legacy alias re-exporting `@warp-drive/core/types/utils`, small TypeScript helper types like `Mutable`; new code should import from there. --- :::warning Legacy package `@warp-drive/core-types` is a legacy package. New code should use [`@warp-drive/core/types`](/api/@warp-drive/core/types/) instead. ::: Legacy alias of [@warp-drive/core/types/utils](../../core/types/utils/index.md). This entry re-exports that module unchanged so existing `@warp-drive/core-types/utils` imports keep working; new code should import from `@warp-drive/core/types/utils` directly. --- --- url: https://canary.warp-drive.io/api/@warp-drive/build-config.md description: >- (Legacy) Home of the `setConfig` build plugin that configures WarpDrive deprecations, optional features and debug logging; new apps should use `@warp-drive/core/build-config` instead. --- :::warning Legacy package `@warp-drive/build-config` is a legacy package. New code should use [`@warp-drive/core/build-config`](/api/@warp-drive/core/build-config/) instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: This package is the implementation home of the `setConfig` build plugin that configures deprecations, optional features, development/testing support and debug logging. Apps import it as [@warp-drive/core/build-config](../core/build-config/index.md), which re-exports every entry point below; the documentation for each lives on the `@warp-drive/core` page it maps to. Apps still importing from this package configure it with `setConfig` in `ember-cli-build`: ```ts [ember-cli-build.js] 'use strict'; const EmberApp = require('ember-cli/lib/broccoli/ember-app'); module.exports = async function (defaults) { const { setConfig } = await import('@warp-drive/build-config'); // [!code focus] const app = new EmberApp(defaults, {}); setConfig(app, __dirname, { // [!code focus:3] // settings here }); const { buildOnce } = await import('@embroider/vite'); const { compatBuild } = await import('@embroider/compat'); return compatBuild(app, buildOnce); }; ``` Available settings include: * [debugging](../core/build-config/debugging/index.md) * [deprecations](../core/build-config/deprecations/index.md) * [features](../core/build-config/canary-features/index.md) * [polyfillUUID](../core/build-config/types/WarpDriveConfig.md#polyfilluuid) * [includeDataAdapterInProduction](../core/build-config/types/WarpDriveConfig.md#includedataadapterinproduction) * [compatWith](../core/build-config/types/WarpDriveConfig.md#compatwith) Every entry point maps to its `@warp-drive/core` equivalent: | `@warp-drive/build-config` entry | re-exported as | | -------------------------------- | --------------------------------------------------------------------------------------------------- | | `.` (root) | [@warp-drive/core/build-config](../core/build-config/index.md) | | `/babel-macros` | [@warp-drive/core/build-config/babel-macros](../core/build-config/babel-macros/index.md) | | `/canary-features` | [@warp-drive/core/build-config/canary-features](../core/build-config/canary-features/index.md) | | `/debugging` | [@warp-drive/core/build-config/debugging](../core/build-config/debugging/index.md) | | `/deprecations` | [@warp-drive/core/build-config/deprecations](../core/build-config/deprecations/index.md) | | `/env` | `@warp-drive/core/build-config/env` (internal, no API page) | | `/macros` | `@warp-drive/core/build-config/macros` (internal, no API page) | --- --- url: https://canary.warp-drive.io/api/@warp-drive/schema-record.md description: >- (Legacy) Re-export of the reactive-resource API such as `SchemaService`, `instantiateRecord` and `withDefaults`; new code should import these from `@warp-drive/core/reactive`. --- :::warning Legacy package `@warp-drive/schema-record` is a legacy package. New code should use [`@warp-drive/core/reactive`](/api/@warp-drive/core/reactive/) instead. For an app still on these packages, see [Legacy Package Setup](/guides/configuration/legacy-package-setup/). ::: This package declares nothing of its own. Its single entry point re-exports the reactive-resource API from [@warp-drive/core/reactive](../core/reactive/index.md) so existing `@warp-drive/schema-record` imports keep working: | `@warp-drive/schema-record` export | `@warp-drive/core/reactive` source | | ---------------------------------- | ---------------------------------------------------------------------------- | | `instantiateRecord` | [instantiateRecord](../core/reactive/functions/instantiateRecord.md) | | `teardownRecord` | [teardownRecord](../core/reactive/functions/teardownRecord.md) | | `SchemaService` | [SchemaService](../core/reactive/classes/SchemaService.md) | | `withDefaults` | [withDefaults](../core/reactive/functions/withDefaults.md) | | `fromIdentity` | [fromIdentity](../core/reactive/variables/fromIdentity.md) | | `registerDerivations` | [registerDerivations](../core/reactive/functions/registerDerivations.md) | | `Checkout` | [Checkout](../core/reactive/variables/Checkout.md) | | `Transformation` (type) | [Transformation](../core/reactive/types/Transformation.md) | | `SchemaRecord` (type) | [ReactiveResource](../core/reactive/types/ReactiveResource.md), renamed | New code should import these from `@warp-drive/core/reactive` directly.