Skip to content

Commit

Permalink
chore: improve types and lint (#8733)
Browse files Browse the repository at this point in the history
  • Loading branch information
runspired authored Jul 26, 2023
1 parent 2652913 commit 226cdc5
Show file tree
Hide file tree
Showing 60 changed files with 521 additions and 442 deletions.
13 changes: 9 additions & 4 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,19 @@ module.exports = {
rules: {
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-unused-vars': ['error', { args: 'none' }],
'@typescript-eslint/prefer-includes': 'error',
'@typescript-eslint/prefer-ts-expect-error': 'error',
'ember-data/prefer-static-type-import': 'error',
'no-unused-vars': 'off',
'prefer-const': 'off',
'prefer-rest-params': 'off',
'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error',
'no-loop-func': 'off',
'@typescript-eslint/no-loop-func': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/no-throw-literal': 'error',
// '@typescript-eslint/prefer-readonly-parameter-types': 'error',
},
},
// Typescript files in non-strict mode
Expand Down Expand Up @@ -210,7 +219,6 @@ module.exports = {
'ember-data-types/q/identifier.ts',
'ember-data-types/q/fetch-manager.ts',
'ember-data-types/q/ember-data-json-api.ts',
'ember-data-types/q/ds-model.ts',
'packages/store/src/-private/managers/record-data-store-wrapper.ts',
'packages/store/src/-private/legacy-model-support/schema-definition-service.ts',
'packages/store/src/-private/network/request-cache.ts',
Expand Down Expand Up @@ -268,7 +276,6 @@ module.exports = {
'packages/adapter/src/-private/fastboot-interface.ts',
'packages/adapter/src/-private/build-url-mixin.ts',
'packages/-ember-data/addon/store.ts',
'tests/main/tests/unit/custom-class-support/custom-class-model-test.ts',
'tests/main/tests/integration/request-state-service-test.ts',
'tests/main/tests/integration/record-data/store-wrapper-test.ts',
'tests/main/tests/integration/record-data/record-data-test.ts',
Expand All @@ -279,9 +286,7 @@ module.exports = {
'tests/main/tests/integration/identifiers/record-identifier-for-test.ts',
'tests/main/tests/integration/identifiers/polymorphic-scenarios-test.ts',
'tests/main/tests/integration/identifiers/new-records-test.ts',
'tests/main/tests/integration/identifiers/lid-reflection-test.ts',
'tests/main/tests/integration/identifiers/configuration-test.ts',
'tests/main/tests/integration/identifiers/cache-test.ts',
'tests/main/tests/helpers/accessors.ts',
],
},
Expand Down
79 changes: 12 additions & 67 deletions ember-data-types/q/ds-model.ts
Original file line number Diff line number Diff line change
@@ -1,67 +1,12 @@
import type EmberObject from '@ember/object';

import type { Errors } from '@ember-data/model/-private';
import type Store from '@ember-data/store';

import { Cache } from './cache';
import { StableRecordIdentifier } from './identifier';
import type { JsonApiError } from './record-data-json-api';
import type { AttributeSchema, RelationshipSchema, RelationshipsSchema } from './record-data-schemas';

export type ModelFactory = { class: DSModelSchema };
export type FactoryCache = Record<string, ModelFactory>;
// we put this on the store for interop because it's used by modelFor and
// instantiateRecord as well.
export type ModelStore = Store & { _modelFactoryCache: FactoryCache };

// Placeholder until model.js is typed
export interface DSModel extends EmberObject {
constructor: DSModelSchema;
store: Store;
errors: Errors;
toString(): string;
save(): Promise<DSModel>;
eachRelationship<T>(callback: (this: T, key: string, meta: RelationshipSchema) => void, binding?: T): void;
eachAttribute<T>(callback: (this: T, key: string, meta: AttributeSchema) => void, binding?: T): void;
invalidErrorsChanged(errors: JsonApiError[]): void;
rollbackAttributes(): void;
changedAttributes(): Record<string, [unknown, unknown]>;
[key: string]: unknown;
isDeleted: boolean;
deleteRecord(): void;
unloadRecord(): void;
_notifyProperties(keys: string[]): void;
}

// Implemented by both ShimModelClass and DSModel
export interface ModelSchema {
modelName: string;
fields: Map<string, 'attribute' | 'belongsTo' | 'hasMany'>;
attributes: Map<string, AttributeSchema>;
relationshipsByName: Map<string, RelationshipSchema>;
eachAttribute<T>(callback: (this: T, key: string, attribute: AttributeSchema) => void, binding?: T): void;
eachRelationship<T>(callback: (this: T, key: string, relationship: RelationshipSchema) => void, binding?: T): void;
eachTransformedAttribute<T>(callback: (this: T, key: string, type?: string) => void, binding?: T): void;
toString(): string;
}

export type DSModelCreateArgs = {
_createProps: Record<string, unknown>;
// TODO @deprecate consider deprecating accessing record properties during init which the below is necessary for
_secretInit: {
identifier: StableRecordIdentifier;
cache: Cache;
store: Store;
cb: (record: DSModel, cache: Cache, identifier: StableRecordIdentifier, store: Store) => void;
};
};

// This is the static side of DSModel should become DSModel
// once we can type it.
export interface DSModelSchema extends ModelSchema {
isModel: true;
relationshipsObject: RelationshipsSchema;
extend(...mixins: unknown[]): DSModelSchema;
reopenClass(...mixins: unknown[]): void;
create(createArgs: DSModelCreateArgs): DSModel;
}
import type Model from '@ember-data/model';

export type ModelSchema = Pick<
typeof Model,
| 'modelName'
| 'fields'
| 'attributes'
| 'relationshipsByName'
| 'eachAttribute'
| 'eachRelationship'
| 'eachTransformedAttribute'
>;
2 changes: 1 addition & 1 deletion ember-data-types/q/identifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export interface GenerationMethod {
*/

export type UpdateMethod = {
(identifier: StableRecordIdentifier, newData: ResourceData, bucket: 'record'): void;
(identifier: StableRecordIdentifier, newData: unknown, bucket: 'record'): void;
(identifier: StableIdentifier, newData: unknown, bucket: never): void;
};

Expand Down
4 changes: 2 additions & 2 deletions ember-data-types/q/record-instance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { DSModel } from './ds-model';
import type Model from '@ember-data/model';
/**
@module @ember-data/store
*/
Expand All @@ -14,4 +14,4 @@ import type { DSModel } from './ds-model';
The type belows allows for anything extending object.
*/

export type RecordInstance = DSModel | Record<string, unknown>;
export type RecordInstance = Model | unknown;
8 changes: 5 additions & 3 deletions packages/-ember-data/addon/-private/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import { graphFor } from '@ember-data/graph/-private';
import JSONAPICache from '@ember-data/json-api';
import { LegacyNetworkHandler } from '@ember-data/legacy-compat';
import { FetchManager } from '@ember-data/legacy-compat/-private';
import type Model from '@ember-data/model';
import type { ModelStore } from '@ember-data/model/-private/model';
import { buildSchema, instantiateRecord, modelFor, teardownRecord } from '@ember-data/model/hooks';
import RequestManager from '@ember-data/request';
import Fetch from '@ember-data/request/fetch';
import BaseStore, { CacheHandler, recordIdentifierFor } from '@ember-data/store';
import type { Cache } from '@ember-data/types/cache/cache';
import type { CacheCapabilitiesManager } from '@ember-data/types/q/cache-store-wrapper';
import type { DSModel, ModelSchema, ModelStore } from '@ember-data/types/q/ds-model';
import type { ModelSchema } from '@ember-data/types/q/ds-model';
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
import type { RecordInstance } from '@ember-data/types/q/record-instance';

Expand All @@ -35,12 +37,12 @@ export class Store extends BaseStore {
this: ModelStore,
identifier: StableRecordIdentifier,
createRecordArgs: Record<string, unknown>
): DSModel {
): Model {
return instantiateRecord.call(this, identifier, createRecordArgs);
}

teardownRecord(record: RecordInstance): void {
teardownRecord.call(this, record as DSModel);
teardownRecord.call(this, record as Model);
}

modelFor(type: string): ModelSchema {
Expand Down
1 change: 1 addition & 0 deletions packages/active-record/src/-private/builders/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { copyForwardUrlOptions, extractCacheOptions } from './-utils';

export function query(
type: string,
// eslint-disable-next-line @typescript-eslint/no-shadow
query: QueryParamsSource = {},
options: ConstrainedRequestOptions = {}
): QueryRequestOptions {
Expand Down
53 changes: 26 additions & 27 deletions packages/adapter/src/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -940,43 +940,21 @@ class RESTAdapter extends Adapter.extend(BuildURLMixin) {
*/
groupRecordsForFindMany(store: Store, snapshots: Snapshot[]): Snapshot[][] {
let groups = new Map();
let adapter = this;
let maxURLLength = this.maxURLLength;

snapshots.forEach((snapshot) => {
let baseUrl = adapter._stripIDFromURL(store, snapshot);
let baseUrl = this._stripIDFromURL(store, snapshot);
if (!groups.has(baseUrl)) {
groups.set(baseUrl, []);
}

groups.get(baseUrl).push(snapshot);
});

function splitGroupToFitInUrl(group, maxURLLength, paramNameLength) {
let idsSize = 0;
let baseUrl = adapter._stripIDFromURL(store, group[0]);
let splitGroups: Snapshot[][] = [[]];

group.forEach((snapshot) => {
let additionalLength = encodeURIComponent(snapshot.id).length + paramNameLength;
if (baseUrl.length + idsSize + additionalLength >= maxURLLength) {
idsSize = 0;
splitGroups.push([]);
}

idsSize += additionalLength;

let lastGroupIndex = splitGroups.length - 1;
splitGroups[lastGroupIndex].push(snapshot);
});

return splitGroups;
}

let groupsArray: Snapshot[][] = [];
groups.forEach((group, key) => {
let paramNameLength = '&ids%5B%5D='.length;
let splitGroups = splitGroupToFitInUrl(group, maxURLLength, paramNameLength);
let splitGroups = splitGroupToFitInUrl(store, this, group, maxURLLength, paramNameLength);

splitGroups.forEach((splitGroup) => groupsArray.push(splitGroup));
});
Expand Down Expand Up @@ -1408,7 +1386,7 @@ function handleAbort(requestData: RequestData, responseData: ResponseData): Abor
//From http://stackoverflow.com/questions/280634/endswith-in-javascript
function endsWith(string: string, suffix: string): boolean {
if (typeof String.prototype.endsWith !== 'function') {
return string.indexOf(suffix, string.length - suffix.length) !== -1;
return string.includes(suffix, string.length - suffix.length);
} else {
return string.endsWith(suffix);
}
Expand All @@ -1430,7 +1408,7 @@ function fetchErrorHandler(
response: Response,
errorThrown,
requestData: RequestData
) {
): Error {
let responseData = fetchResponseData(response);

if (responseData.status === 200 && payload instanceof Error) {
Expand Down Expand Up @@ -1519,7 +1497,7 @@ export function fetchOptions(
// If no options are passed, Ember Data sets `data` to an empty object, which we test for.
if (Object.keys(options.data).length && options.url) {
// Test if there are already query params in the url (mimics jQuey.ajax).
const queryParamDelimiter = options.url.indexOf('?') > -1 ? '&' : '?';
const queryParamDelimiter = options.url.includes('?') ? '&' : '?';
options.url += `${queryParamDelimiter}${serializeQueryParams(options.data)}`;
}
} else {
Expand Down Expand Up @@ -1567,4 +1545,25 @@ function ajaxOptions(options: JQueryRequestInit, adapter: RESTAdapter): JQueryRe
return options;
}

function splitGroupToFitInUrl(store, adapter, group, maxURLLength, paramNameLength) {
let idsSize = 0;
let baseUrl = adapter._stripIDFromURL(store, group[0]);
let splitGroups: Snapshot[][] = [[]];

group.forEach((snapshot) => {
let additionalLength = encodeURIComponent(snapshot.id).length + paramNameLength;
if (baseUrl.length + idsSize + additionalLength >= maxURLLength) {
idsSize = 0;
splitGroups.push([]);
}

idsSize += additionalLength;

let lastGroupIndex = splitGroups.length - 1;
splitGroups[lastGroupIndex].push(snapshot);
});

return splitGroups;
}

export default RESTAdapter;
40 changes: 20 additions & 20 deletions packages/graph/src/-private/graph/-edge-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,18 +194,18 @@ function assertConfiguration(info: EdgeDefinition, type: string, key: string) {
return true;
}

let isRHS =
let _isRHS =
key === info.rhs_relationshipName &&
(type === info.rhs_baseModelName || // base or non-polymorphic
// if the other side is polymorphic then we need to scan our modelNames
(info.lhs_isPolymorphic && info.rhs_modelNames.indexOf(type) !== -1)); // polymorphic
let isLHS =
(info.lhs_isPolymorphic && info.rhs_modelNames.includes(type))); // polymorphic
let _isLHS =
key === info.lhs_relationshipName &&
(type === info.lhs_baseModelName || // base or non-polymorphic
// if the other side is polymorphic then we need to scan our modelNames
(info.rhs_isPolymorphic && info.lhs_modelNames.indexOf(type) !== -1)); // polymorphic;
(info.rhs_isPolymorphic && info.lhs_modelNames.includes(type))); // polymorphic;

if (!isRHS && !isLHS) {
if (!_isRHS && !_isLHS) {
/*
this occurs when we are likely polymorphic but not configured to be polymorphic
most often due to extending a class that has a relationship definition on it.
Expand Down Expand Up @@ -259,10 +259,10 @@ function assertConfiguration(info: EdgeDefinition, type: string, key: string) {
```
*/
if (key === info.lhs_relationshipName && info.lhs_modelNames.indexOf(type) !== -1) {
if (key === info.lhs_relationshipName && info.lhs_modelNames.includes(type)) {
// parentIdentifier, parentDefinition, addedIdentifier, store
assertInheritedSchema(info.lhs_definition, type);
} else if (key === info.rhs_relationshipName && info.rhs_modelNames.indexOf(type) !== -1) {
} else if (key === info.rhs_relationshipName && info.rhs_modelNames.includes(type)) {
assertInheritedSchema(info.lhs_definition, type);
}
// OPEN AN ISSUE :: we would like to improve our errors but need to understand what corner case got us here
Expand All @@ -271,7 +271,7 @@ function assertConfiguration(info: EdgeDefinition, type: string, key: string) {
);
}

if (isRHS && isLHS) {
if (_isRHS && _isLHS) {
// not sure how we get here but it's probably the result of some form of inheritance
// without having specified polymorphism correctly leading to it not being self-referential
// OPEN AN ISSUE :: we would like to improve our errors but need to understand what corner case got us here
Expand All @@ -295,7 +295,7 @@ export function isLHS(info: EdgeDefinition, type: string, key: string): boolean
isSelfReferential === true || // itself
type === info.lhs_baseModelName || // base or non-polymorphic
// if the other side is polymorphic then we need to scan our modelNames
(info.rhs_isPolymorphic && info.lhs_modelNames.indexOf(type) !== -1) // polymorphic
(info.rhs_isPolymorphic && info.lhs_modelNames.includes(type)) // polymorphic
);
}

Expand All @@ -315,7 +315,7 @@ export function isRHS(info: EdgeDefinition, type: string, key: string): boolean
isSelfReferential === true || // itself
type === info.rhs_baseModelName || // base or non-polymorphic
// if the other side is polymorphic then we need to scan our modelNames
(info.lhs_isPolymorphic && info.rhs_modelNames.indexOf(type) !== -1) // polymorphic
(info.lhs_isPolymorphic && info.rhs_modelNames.includes(type)) // polymorphic
);
}

Expand Down Expand Up @@ -355,11 +355,11 @@ export function upgradeDefinition(
if (polymorphicLookup[type]) {
const altTypes = Object.keys(polymorphicLookup[type] as {});
for (let i = 0; i < altTypes.length; i++) {
let cached = expandingGet<EdgeDefinition | null>(cache, altTypes[i], propertyName);
if (cached) {
expandingSet<EdgeDefinition | null>(cache, type, propertyName, cached);
cached.rhs_modelNames.push(type);
return cached;
const _cached = expandingGet<EdgeDefinition | null>(cache, altTypes[i], propertyName);
if (_cached) {
expandingSet<EdgeDefinition | null>(cache, type, propertyName, _cached);
_cached.rhs_modelNames.push(type);
return _cached;
}
}
}
Expand Down Expand Up @@ -410,13 +410,13 @@ export function upgradeDefinition(
.getSchemaDefinitionService()
.relationshipsDefinitionFor({ type: inverseType });
assert(`Expected to have a relationship definition for ${inverseType} but none was found.`, inverseDefinitions);
let meta = inverseDefinitions[inverseKey];
let metaFromInverse = inverseDefinitions[inverseKey];
assert(
`Expected a relationship schema for '${inverseType}.${inverseKey}' to match the inverse of '${type}.${propertyName}', but no relationship schema was found.`,
meta
metaFromInverse
);

inverseDefinition = upgradeMeta(meta);
inverseDefinition = upgradeMeta(metaFromInverse);
}
}

Expand Down Expand Up @@ -484,8 +484,8 @@ export function upgradeDefinition(
cached.hasInverse !== false
);

let isLHS = cached.lhs_baseModelName === baseType;
let modelNames = isLHS ? cached.lhs_modelNames : cached.rhs_modelNames;
let _isLHS = cached.lhs_baseModelName === baseType;
let modelNames = _isLHS ? cached.lhs_modelNames : cached.rhs_modelNames;
// make this lookup easier in the future by caching the key
modelNames.push(type);
expandingSet<EdgeDefinition | null>(cache, type, propertyName, cached);
Expand Down
Loading

0 comments on commit 226cdc5

Please sign in to comment.