Skip to content

Commit

Permalink
Backport request, request-utils, store cache-handler changes to 4.12 (#…
Browse files Browse the repository at this point in the history
…9389)

* Backport @ember-data/request changes from main

* Backport cache-handler changes from main

* Backport fetch handler changes from main

* Backport @ember-data/request-utils

* Don't build types for @ember-data/request-utils

* Downgrade @ember-data/request-utils node engines

* Fix @ember-data/request-utils build

* Fix lint

* Fix problems

* Fix special-build-tests

* Remove request-utils changelog
  • Loading branch information
gitKrystan authored May 1, 2024
1 parent 9779c67 commit f557cee
Show file tree
Hide file tree
Showing 33 changed files with 5,493 additions and 1,006 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ module.exports = {
'packages/*/blueprints/*/index.js',
'packages/*/config/**/*.js',
'packages/*/tests/dummy/config/**/*.js',
'packages/request-utils/rollup/external.cjs',
],
excludedFiles: [
'packages/*/addon/**',
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ dist-*
tmp
packages/tracking/addon
packages/request/addon
packages/request-utils/addon
packages/store/addon
packages/adapter/addon
packages/serializer/addon
Expand Down
5 changes: 2 additions & 3 deletions packages/json-api/src/-private/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import type { LocalRelationshipOperation } from '@ember-data/graph/-private/grap
import type { ImplicitRelationship } from '@ember-data/graph/-private/graph/index';
import type BelongsToRelationship from '@ember-data/graph/-private/relationships/state/belongs-to';
import type ManyRelationship from '@ember-data/graph/-private/relationships/state/has-many';
import { StructuredErrorDocument } from '@ember-data/request/-private/types';
import { StoreRequestInfo } from '@ember-data/store/-private/cache-handler';
import { type ImmutableRequestInfo, StructuredErrorDocument } from '@ember-data/request/-private/types';
import type { IdentifierCache } from '@ember-data/store/-private/caches/identifier-cache';
import type { ResourceBlob } from '@ember-data/types/cache/aliases';
import type { Change } from '@ember-data/types/cache/change';
Expand Down Expand Up @@ -236,7 +235,7 @@ export default class JSONAPICache implements Cache {
(resourceDocument as SingleResourceDataDocument | CollectionResourceDataDocument).data = data;
}

const request = doc.request as StoreRequestInfo | undefined;
const request = doc.request as ImmutableRequestInfo | undefined;
const identifier = request ? this.__storeWrapper.identifierCache.getOrCreateDocumentIdentifier(request) : null;

if (identifier) {
Expand Down
10 changes: 3 additions & 7 deletions packages/legacy-compat/src/builders/find-all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
*/
import { assert } from '@ember/debug';

import type Model from '@ember-data/model';
import { SkipCache } from '@ember-data/request';
import type { ImmutableRequestInfo } from '@ember-data/request/-private/types';

import { normalizeModelName } from './utils';

// Keeping unused generics for consistency with 5x types
type FindAllRequestInput<T extends string = string, RT = unknown[]> = ImmutableRequestInfo & {
type FindAllRequestInput<T extends string = string> = ImmutableRequestInfo & {
op: 'findAll';
data: {
type: T;
Expand Down Expand Up @@ -43,11 +43,7 @@ type FindAllBuilderOptions = {
@param {FindAllBuilderOptions} [options] optional, may include `adapterOptions` hash which will be passed to adapter.findAll
@return {FindAllRequestInput} request config
*/
// Keeping this generic for consistency with 5x types
export function findAllBuilder<T extends Model>(
type: string,
options?: FindAllBuilderOptions
): FindAllRequestInput<string, Model[]>;
export function findAllBuilder(type: string, options?: FindAllBuilderOptions): FindAllRequestInput<string>;
export function findAllBuilder(type: string, options?: FindAllBuilderOptions): FindAllRequestInput;
export function findAllBuilder(type: string, options: FindAllBuilderOptions = {}): FindAllRequestInput {
assert(`You need to pass a model name to the findAll builder`, type);
Expand Down
15 changes: 7 additions & 8 deletions packages/legacy-compat/src/builders/find-record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
*/
import { assert } from '@ember/debug';

import type Model from '@ember-data/model';
import { SkipCache } from '@ember-data/request';
import type { ImmutableRequestInfo } from '@ember-data/request/-private/types';
import { constructResource, ensureStringId } from '@ember-data/store/-private';
import type { ResourceIdentifierObject } from '@ember-data/types/q/ember-data-json-api';

import { isMaybeIdentifier, normalizeModelName } from './utils';

// Keeping unused generics for consistency with 5x types
type FindRecordRequestInput<T extends string = string, RT = unknown> = ImmutableRequestInfo & {
type FindRecordRequestInput = ImmutableRequestInfo & {
op: 'findRecord';
data: {
record: ResourceIdentifierObject;
Expand Down Expand Up @@ -63,20 +62,20 @@ type FindRecordBuilderOptions = {
@param {FindRecordBuilderOptions} [options] - if the first param is a string this will be the optional options for the request. See examples for available options.
@return {FindRecordRequestInput} request config
*/
export function findRecordBuilder<T extends Model>(
export function findRecordBuilder(
resource: string,
id: string,
options?: FindRecordBuilderOptions
): FindRecordRequestInput<string, T>;
): FindRecordRequestInput;
export function findRecordBuilder(
resource: string,
id: string,
options?: FindRecordBuilderOptions
): FindRecordRequestInput;
export function findRecordBuilder<T extends Model>(
export function findRecordBuilder(
resource: ResourceIdentifierObject,
options?: FindRecordBuilderOptions
): FindRecordRequestInput<string, T>;
): FindRecordRequestInput;
export function findRecordBuilder(
resource: ResourceIdentifierObject,
options?: FindRecordBuilderOptions
Expand Down Expand Up @@ -104,7 +103,7 @@ export function findRecordBuilder(

options = options || {};

assert('findRecord builder does not support options.preload', !(options as any).preload);
assert('findRecord builder does not support options.preload', !(options as { preload?: boolean }).preload);

return {
op: 'findRecord' as const,
Expand Down
14 changes: 7 additions & 7 deletions packages/legacy-compat/src/builders/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
*/
import { assert } from '@ember/debug';

import type Model from '@ember-data/model';
import { SkipCache } from '@ember-data/request';
import type { ImmutableRequestInfo } from '@ember-data/request/-private/types';

import { normalizeModelName } from './utils';

type QueryRequestInput<T extends string = string, RT = unknown[]> = ImmutableRequestInfo & {
type QueryRequestInput<T extends string = string> = ImmutableRequestInfo & {
op: 'query';
data: {
type: T;
Expand Down Expand Up @@ -40,11 +40,11 @@ type QueryBuilderOptions = {
@param {QueryBuilderOptions} [options] optional, may include `adapterOptions` hash which will be passed to adapter.query
@return {QueryRequestInput} request config
*/
export function queryBuilder<T extends Model>(
export function queryBuilder(
type: string,
query: Record<string, unknown>,
options?: QueryBuilderOptions
): QueryRequestInput<string, T[]>;
): QueryRequestInput<string>;
export function queryBuilder(
type: string,
query: Record<string, unknown>,
Expand Down Expand Up @@ -73,7 +73,7 @@ export function queryBuilder(
};
}

type QueryRecordRequestInput<T extends string = string, RT = unknown> = ImmutableRequestInfo & {
type QueryRecordRequestInput<T extends string = string> = ImmutableRequestInfo & {
op: 'queryRecord';
data: {
type: T;
Expand Down Expand Up @@ -101,11 +101,11 @@ type QueryRecordRequestInput<T extends string = string, RT = unknown> = Immutabl
@param {QueryBuilderOptions} [options] optional, may include `adapterOptions` hash which will be passed to adapter.query
@return {QueryRecordRequestInput} request config
*/
export function queryRecordBuilder<T extends Model>(
export function queryRecordBuilder(
type: string,
query: Record<string, unknown>,
options?: QueryBuilderOptions
): QueryRecordRequestInput<string, T | null>;
): QueryRecordRequestInput<string>;
export function queryRecordBuilder(
type: string,
query: Record<string, unknown>,
Expand Down
4 changes: 2 additions & 2 deletions packages/legacy-compat/src/builders/save-record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type { InstanceCache } from '@ember-data/store/-private/caches/instance-c
import type { Cache } from '@ember-data/types/cache/cache';
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';

type SaveRecordRequestInput<T extends string = string, RT = unknown> = ImmutableRequestInfo & {
type SaveRecordRequestInput = ImmutableRequestInfo & {
op: 'createRecord' | 'deleteRecord' | 'updateRecord';
data: {
record: StableRecordIdentifier;
Expand Down Expand Up @@ -52,7 +52,7 @@ function resourceIsFullyDeleted(instanceCache: InstanceCache, identifier: Stable
export function saveRecordBuilder<T extends Model>(
record: T,
options: Record<string, unknown> = {}
): SaveRecordRequestInput<string, T> {
): SaveRecordRequestInput {
const store = storeFor(record);
assert(`Unable to initiate save for a record in a disconnected state`, store);
const identifier = recordIdentifierFor(record);
Expand Down
3 changes: 2 additions & 1 deletion packages/legacy-compat/src/builders/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ResourceIdentifierObject } from '@ember-data/types/q/ember-data-json-api';
import { dasherize } from '@ember/string';

import type { ResourceIdentifierObject } from '@ember-data/types/q/ember-data-json-api';

export function isMaybeIdentifier(
maybeIdentifier: string | ResourceIdentifierObject
): maybeIdentifier is ResourceIdentifierObject {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import { DEPRECATE_RSVP_PROMISE, DEPRECATE_V1_RECORD_DATA } from '@ember-data/de
import { DEBUG, TESTING } from '@ember-data/env';
import { HAS_GRAPH_PACKAGE } from '@ember-data/packages';
import { createDeferred } from '@ember-data/request';
import type { Deferred } from '@ember-data/request/-private/types';
import type { Deferred, ImmutableRequestInfo } from '@ember-data/request/-private/types';
import type Store from '@ember-data/store';
import { coerceId } from '@ember-data/store/-private';
import { StoreRequestInfo } from '@ember-data/store/-private/cache-handler';
import type { InstanceCache } from '@ember-data/store/-private/caches/instance-cache';
import type ShimModelClass from '@ember-data/store/-private/legacy-model-support/shim-model-class';
import type RequestStateService from '@ember-data/store/-private/network/request-cache';
Expand Down Expand Up @@ -115,7 +114,7 @@ export default class FetchManager {
scheduleFetch(
identifier: StableExistingRecordIdentifier,
options: FindOptions,
request: StoreRequestInfo
request: ImmutableRequestInfo
): Promise<StableExistingRecordIdentifier> {
let query: FindRecordQuery = {
op: 'findRecord',
Expand Down Expand Up @@ -251,7 +250,7 @@ export default class FetchManager {
fetchDataIfNeededForIdentifier(
identifier: StableExistingRecordIdentifier,
options: FindOptions = {},
request: StoreRequestInfo
request: ImmutableRequestInfo
): Promise<StableExistingRecordIdentifier> {
// pre-loading will change the isEmpty value
const isEmpty = _isEmpty(this._store._instanceCache, identifier);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { importSync } from '@embroider/macros';
import { LOG_PAYLOADS } from '@ember-data/debugging';
import { DEPRECATE_V1_RECORD_DATA } from '@ember-data/deprecations';
import { DEBUG, TESTING } from '@ember-data/env';
import type { Handler, NextFn } from '@ember-data/request/-private/types';
import type { Handler, ImmutableRequestInfo, NextFn } from '@ember-data/request/-private/types';
import type Store from '@ember-data/store';
import type { StoreRequestContext, StoreRequestInfo } from '@ember-data/store/-private/cache-handler';
import type { StoreRequestContext } from '@ember-data/store/-private/cache-handler';
import type { Collection } from '@ember-data/store/-private/record-arrays/identifier-array';
import { SingleResourceDataDocument } from '@ember-data/types/cache/document';
import type { ModelSchema } from '@ember-data/types/q/ds-model';
Expand Down Expand Up @@ -419,7 +419,7 @@ function _findAll<T>(
store: Store,
type: string,
snapshotArray: SnapshotRecordArray,
request: StoreRequestInfo,
request: ImmutableRequestInfo,
isAsyncFlush: boolean
): Promise<T> {
const schema = store.modelFor(type);
Expand Down
11 changes: 11 additions & 0 deletions packages/request-utils/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
The MIT License (MIT)

Copyright (C) 2017-2023 Ember.js contributors
Portions Copyright (C) 2011-2017 Tilde, Inc. and contributors.
Portions Copyright (C) 2011 LivingSocial Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
76 changes: 76 additions & 0 deletions packages/request-utils/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<p align="center">
<img
class="project-logo"
src="./ember-data-logo-dark.svg#gh-dark-mode-only"
alt="EmberData RequestUtils"
width="240px"
title="EmberData RequestUtils"
/>
<img
class="project-logo"
src="./ember-data-logo-light.svg#gh-light-mode-only"
alt="EmberData RequestUtils"
width="240px"
title="EmberData RequestUtils"
/>
</p>

<p align="center">Utilities for Requests</p>

This package provides Simple utility function to assist in url building, query params, and other common request operations.

It's built for [*Ember***Data**](https://github.com/emberjs/data/) but useful more broadly if you're looking for lightweight functions to assist in working with urls and query params.

## Installation

Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/)

```no-highlight
pnpm add @ember-data/request-utils
```

**Tagged Releases**

- ![NPM Canary Version](https://img.shields.io/npm/v/%40ember-data/request-utils/canary?label=%40canary&color=FFBF00)
- ![NPM Beta Version](https://img.shields.io/npm/v/%40ember-data/request-utils/beta?label=%40beta&color=ff00ff)
- ![NPM Stable Version](https://img.shields.io/npm/v/%40ember-data/request-utils/latest?label=%40latest&color=90EE90)
- ![NPM LTS Version](https://img.shields.io/npm/v/%40ember-data/request-utils/lts?label=%40lts&color=0096FF)
- ![NPM LTS 4.12 Version](https://img.shields.io/npm/v/%40ember-data/request-utils/lts-4-12?label=%40lts-4-12&color=bbbbbb)


## Utils

- [buildBaseUrl]()
- [sortQueryParams]()
- [buildQueryParams]()
- [filterEmpty]()

### As a Library Primitive

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.
```
19 changes: 19 additions & 0 deletions packages/request-utils/addon-main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module.exports = {
name: require('./package.json').name,

treeForVendor() {
return;
},
treeForPublic() {
return;
},
treeForStyles() {
return;
},
treeForAddonStyles() {
return;
},
treeForApp() {
return;
},
};
8 changes: 8 additions & 0 deletions packages/request-utils/babel.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"plugins": [
"@babel/plugin-transform-runtime",
["@babel/plugin-transform-typescript", { "allowDeclareFields": true }],
["@babel/plugin-proposal-decorators", { "legacy": true }],
"@babel/plugin-transform-class-properties"
]
}
Loading

0 comments on commit f557cee

Please sign in to comment.