-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: findRecord and query request builders (#8687)
* WIP Starting out request-utils package * updates to gitignore and tracking version * new contributing docs for identity and basic implementation for buildURL and JSON:API findREcord builder * update builders with REST builder for findRecord * fix pnpm install * implement query params serialization with Jake and Chris * rename to buildQueryParams * refactor JSON:API findRecord op into multiple files * update factoring for REST * add test harness and some basic tests * ensure tests run * update tests * add tests for buildQueryParams * tests for builders * adds ActiveRecord builder support * fix root config * fix root config --------- Co-authored-by: Jacob Beltran <[email protected]> Co-authored-by: Natasha Wolfe <[email protected]>
- Loading branch information
1 parent
8033558
commit 4237849
Showing
73 changed files
with
2,965 additions
and
675 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Key Concepts | ||
|
||
- [Identity](#-identity) | ||
|
||
------------- | ||
|
||
## 🔸 Identity | ||
|
||
### Working with Identifiers and TypeScript | ||
|
||
Identifying information can be encountered in several different manners depending on which APIs are being worked with and whether the code is "internal" or "public facing". | ||
|
||
* The "ResourceIdentifier" type is used when the identifying information is end-user-supplied and not guaranteed to have "lid". | ||
|
||
Example: `findRecord({ type: 'user', id: '1' })` | ||
|
||
Most commonly this is the case when a record has not been encountered yet or when processing a payload received from the API. | ||
|
||
* The "RecordIdentifier" type is used when identifying information MUST have "lid" but may not be the "stable" identifier object instance. | ||
|
||
Example: `saveRecord({ type: 'user', id: null, lid: 'user:1' })` | ||
|
||
Most commonly this is the case when the user might manually construct an identifier. Often this is the result of having previously serialized record state and later attempting to restore it. | ||
|
||
* The "StableRecordIdentifier" type is used when identifying information MUST have "lid" AND MUST be the "stable" identifier object | ||
instance produced and managed by the `IdentifierCache` associated to a | ||
specific `Store` instance. | ||
|
||
Example: | ||
|
||
```ts | ||
const identifier = recordIdentifierFor(record); | ||
unloadRecord(identifier); | ||
``` | ||
|
||
Any identifier supplied by an EmberData API will always be the stable variant. APIs which are operating based on identity and which can reasonably presume that the data exists expect stable identifiers and should error if an unknown identifier is encountered to prevent potential system-correctness errors. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
@ember-data/active-record | ||
============================================================================ | ||
|
||
ActiveRecord Format Support for EmberData | ||
|
||
> Note: This is a V2 Addon, but we have intentionally configured it to act and report as a V1 Addon due | ||
to bugs with ember-auto-import. | ||
> | ||
> We can remove the V1 tag if ember-auto-import will no longer attempt | ||
to load V2 addons or if it is fixed to work with V1 addons with custom addon trees and also dedupes modules for test apps. | ||
> | ||
> You can still consume this as a normal library. | ||
> In other projects. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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-proposal-class-properties" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
{ | ||
"name": "@ember-data/active-record", | ||
"description": "ActiveRecord Format Support for EmberData", | ||
"version": "5.3.0-alpha.3", | ||
"private": false, | ||
"license": "MIT", | ||
"author": "Chris Thoburn <[email protected]>", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+ssh://[email protected]:emberjs/data.git", | ||
"directory": "packages/active-record" | ||
}, | ||
"homepage": "https://github.com/emberjs/data", | ||
"bugs": "https://github.com/emberjs/data/issues", | ||
"engines": { | ||
"node": "16.* || >= 18" | ||
}, | ||
"keywords": [ | ||
"ember-addon" | ||
], | ||
"volta": { | ||
"extends": "../../package.json" | ||
}, | ||
"dependencies": { | ||
"ember-cli-babel": "^7.26.11" | ||
}, | ||
"peerDependencies": { | ||
"ember-inflector": "^4.0.2" | ||
}, | ||
"files": [ | ||
"addon-main.js", | ||
"addon", | ||
"README.md", | ||
"LICENSE.md", | ||
"ember-data-logo-dark.svg", | ||
"ember-data-logo-light.svg" | ||
], | ||
"scripts": { | ||
"build": "rollup --config && babel ./addon --out-dir addon --plugins=../private-build-infra/src/transforms/babel-plugin-transform-ext.js", | ||
"start": "rollup --config --watch", | ||
"prepack": "pnpm build", | ||
"prepare": "pnpm build" | ||
}, | ||
"ember-addon": { | ||
"main": "addon-main.js", | ||
"type": "addon", | ||
"version": 1 | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.21.8", | ||
"@babel/cli": "^7.21.5", | ||
"@babel/plugin-proposal-class-properties": "^7.18.6", | ||
"@babel/plugin-proposal-decorators": "^7.21.0", | ||
"@babel/plugin-transform-runtime": "^7.21.4", | ||
"@babel/plugin-transform-typescript": "^7.21.3", | ||
"@babel/preset-env": "^7.21.5", | ||
"@babel/preset-typescript": "^7.21.5", | ||
"@babel/runtime": "^7.21.5", | ||
"@embroider/addon-dev": "^3.0.0", | ||
"@rollup/plugin-babel": "^6.0.3", | ||
"@rollup/plugin-node-resolve": "^15.0.2", | ||
"rollup": "^3.21.7", | ||
"tslib": "^2.5.0", | ||
"typescript": "^5.0.4", | ||
"walk-sync": "^3.0.0" | ||
}, | ||
"ember": { | ||
"edition": "octane" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { Addon } from '@embroider/addon-dev/rollup'; | ||
import babel from '@rollup/plugin-babel'; | ||
import { nodeResolve } from '@rollup/plugin-node-resolve'; | ||
|
||
const addon = new Addon({ | ||
srcDir: 'src', | ||
destDir: 'addon', | ||
}); | ||
|
||
export default { | ||
// This provides defaults that work well alongside `publicEntrypoints` below. | ||
// You can augment this if you need to. | ||
output: addon.output(), | ||
|
||
external: [], | ||
|
||
plugins: [ | ||
// These are the modules that users should be able to import from your | ||
// addon. Anything not listed here may get optimized away. | ||
addon.publicEntrypoints(['request.js']), | ||
|
||
nodeResolve({ extensions: ['.ts'] }), | ||
babel({ | ||
extensions: ['.ts'], | ||
babelHelpers: 'runtime', // we should consider "external", | ||
}), | ||
|
||
// Remove leftover build artifacts when starting a new build. | ||
addon.clean(), | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { QueryParamsSerializationOptions } from '@ember-data/request-utils'; | ||
import type { ResourceIdentifierObject } from '@ember-data/types/q/ember-data-json-api'; | ||
|
||
export type CacheOptions = { | ||
key?: string; | ||
reload?: boolean; | ||
backgroundReload?: boolean; | ||
}; | ||
export type FindRecordRequestOptions = { | ||
url: string; | ||
method: 'GET'; | ||
headers: Headers; | ||
cacheOptions: CacheOptions; | ||
op: 'findRecord'; | ||
records: [ResourceIdentifierObject]; | ||
}; | ||
|
||
export type QueryRequestOptions = { | ||
url: string; | ||
method: 'GET'; | ||
headers: Headers; | ||
cacheOptions: CacheOptions; | ||
op: 'query'; | ||
}; | ||
|
||
export type RemotelyAccessibleIdentifier = { | ||
id: string; | ||
type: string; | ||
lid?: string; | ||
}; | ||
|
||
export type ConstrainedRequestOptions = { | ||
reload?: boolean; | ||
backgroundReload?: boolean; | ||
host?: string; | ||
namespace?: string; | ||
resourcePath?: string; | ||
urlParamsSettings?: QueryParamsSerializationOptions; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { type UrlOptions } from '@ember-data/request-utils'; | ||
|
||
import type { CacheOptions, ConstrainedRequestOptions } from './-types'; | ||
|
||
export function copyForwardUrlOptions(urlOptions: UrlOptions, options: ConstrainedRequestOptions): void { | ||
if ('host' in options) { | ||
urlOptions.host = options.host; | ||
} | ||
if ('namespace' in options) { | ||
urlOptions.namespace = options.namespace; | ||
} | ||
if ('resourcePath' in options) { | ||
urlOptions.resourcePath = options.resourcePath; | ||
} | ||
} | ||
|
||
export function extractCacheOptions(options: ConstrainedRequestOptions) { | ||
const cacheOptions: CacheOptions = {}; | ||
if ('reload' in options) { | ||
cacheOptions.reload = options.reload; | ||
} | ||
if ('backgroundReload' in options) { | ||
cacheOptions.backgroundReload = options.backgroundReload; | ||
} | ||
return cacheOptions; | ||
} |
49 changes: 49 additions & 0 deletions
49
packages/active-record/src/-private/builders/find-record.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { underscore } from '@ember/string'; | ||
|
||
import { pluralize } from 'ember-inflector'; | ||
|
||
import { buildBaseURL, buildQueryParams, type FindRecordUrlOptions } from '@ember-data/request-utils'; | ||
|
||
import type { ConstrainedRequestOptions, FindRecordRequestOptions, RemotelyAccessibleIdentifier } from './-types'; | ||
import { copyForwardUrlOptions, extractCacheOptions } from './-utils'; | ||
|
||
type FindRecordOptions = ConstrainedRequestOptions & { | ||
include?: string | string[]; | ||
}; | ||
|
||
export function findRecord( | ||
identifier: RemotelyAccessibleIdentifier, | ||
options?: FindRecordOptions | ||
): FindRecordRequestOptions; | ||
export function findRecord(type: string, id: string, options?: FindRecordOptions): FindRecordRequestOptions; | ||
export function findRecord( | ||
arg1: string | RemotelyAccessibleIdentifier, | ||
arg2: string | FindRecordOptions | undefined, | ||
arg3?: FindRecordOptions | ||
): FindRecordRequestOptions { | ||
const identifier: RemotelyAccessibleIdentifier = typeof arg1 === 'string' ? { type: arg1, id: arg2 as string } : arg1; | ||
const options = ((typeof arg1 === 'string' ? arg3 : arg2) || {}) as FindRecordOptions; | ||
const cacheOptions = extractCacheOptions(options); | ||
const urlOptions: FindRecordUrlOptions = { | ||
identifier, | ||
op: 'findRecord', | ||
resourcePath: pluralize(underscore(identifier.type)), | ||
}; | ||
|
||
copyForwardUrlOptions(urlOptions, options); | ||
|
||
const url = buildBaseURL(urlOptions); | ||
const headers = new Headers(); | ||
headers.append('Content-Type', 'application/json; charset=utf-8'); | ||
|
||
return { | ||
url: options.include?.length | ||
? `${url}?${buildQueryParams({ include: options.include }, options.urlParamsSettings)}` | ||
: url, | ||
method: 'GET', | ||
headers, | ||
cacheOptions, | ||
op: 'findRecord', | ||
records: [identifier], | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { underscore } from '@ember/string'; | ||
|
||
import { pluralize } from 'ember-inflector'; | ||
|
||
import { buildBaseURL, buildQueryParams, QueryParamsSource, type QueryUrlOptions } from '@ember-data/request-utils'; | ||
|
||
import type { ConstrainedRequestOptions, QueryRequestOptions } from './-types'; | ||
import { copyForwardUrlOptions, extractCacheOptions } from './-utils'; | ||
|
||
export function query( | ||
type: string, | ||
query: QueryParamsSource = {}, | ||
options: ConstrainedRequestOptions = {} | ||
): QueryRequestOptions { | ||
const cacheOptions = extractCacheOptions(options); | ||
const urlOptions: QueryUrlOptions = { | ||
identifier: { type }, | ||
op: 'query', | ||
resourcePath: pluralize(underscore(type)), | ||
}; | ||
|
||
copyForwardUrlOptions(urlOptions, options); | ||
|
||
const url = buildBaseURL(urlOptions); | ||
const headers = new Headers(); | ||
headers.append('Content-Type', 'application/json; charset=utf-8'); | ||
|
||
return { | ||
url: `${url}?${buildQueryParams(query, options.urlParamsSettings)}`, | ||
method: 'GET', | ||
headers, | ||
cacheOptions, | ||
op: 'query', | ||
}; | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { findRecord } from './-private/builders/find-record'; | ||
export { query } from './-private/builders/query'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.