Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use keyof ModelRegistry for modelName to fix type issues when any index is removed from registry #288

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 21 additions & 20 deletions addon/adapters/cloud-firestore-modular.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { inject as service } from '@ember/service';
import Adapter from '@ember-data/adapter';
import DS from 'ember-data';
import ModelRegistry from 'ember-data/types/registries/model';
import RSVP from 'rsvp';
import Store from '@ember-data/store';

Expand All @@ -34,9 +35,9 @@
import buildCollectionName from 'ember-cloud-firestore-adapter/-private/build-collection-name';
import flattenDocSnapshot from 'ember-cloud-firestore-adapter/-private/flatten-doc-snapshot';

interface ModelClass {
modelName: string;
}
type ModelClass<K extends keyof ModelRegistry> = ModelRegistry[K] & {
modelName: K;
};

interface AdapterOption {
isRealtime?: boolean;
Expand All @@ -53,12 +54,12 @@
adapterOptions: AdapterOption;
}

interface SnapshotRecordArray extends DS.SnapshotRecordArray<string | number> {
interface SnapshotRecordArray extends DS.SnapshotRecordArray<keyof ModelRegistry> {
adapterOptions: AdapterOption;
}

interface BelongsToRelationshipMeta {
type: string;
type: keyof ModelRegistry;
options: { isRealtime?: boolean };
}

Expand Down Expand Up @@ -92,17 +93,17 @@
return doc(collection(db, collectionName)).id;
}

public createRecord(
public createRecord<K extends keyof ModelRegistry>(
store: Store,
type: ModelClass,
type: ModelClass<K>,
snapshot: Snapshot,
): RSVP.Promise<unknown> {
return this.updateRecord(store, type, snapshot);
}

public updateRecord(
public updateRecord<K extends keyof ModelRegistry>(
_store: Store,
type: ModelClass,
type: ModelClass<K>,
snapshot: Snapshot,
): RSVP.Promise<unknown> {
return new RSVP.Promise((resolve, reject) => {
Expand All @@ -125,9 +126,9 @@
});
}

public deleteRecord(
public deleteRecord<K extends keyof ModelRegistry>(
_store: Store,
type: ModelClass,
type: ModelClass<K>,
snapshot: Snapshot,
): RSVP.Promise<unknown> {
return new RSVP.Promise((resolve, reject) => {
Expand All @@ -147,9 +148,9 @@
});
}

public findRecord(
public findRecord<K extends keyof ModelRegistry>(
_store: Store,
type: ModelClass,
type: ModelClass<K>,
id: string,
snapshot: Snapshot,
): RSVP.Promise<unknown> {
Expand All @@ -172,9 +173,9 @@
});
}

public findAll(
public findAll<K extends keyof ModelRegistry>(
_store: Store,
type: ModelClass,
type: ModelClass<K>,
_sinceToken: string,
snapshotRecordArray?: SnapshotRecordArray,
): RSVP.Promise<unknown> {
Expand All @@ -195,9 +196,9 @@
});
}

public query(
public query<K extends keyof ModelRegistry>(
_store: Store,
type: ModelClass,
type: ModelClass<K>,
queryOption: AdapterOption,
recordArray: DS.AdapterPopulatedRecordArray<unknown>,
): RSVP.Promise<unknown> {
Expand Down Expand Up @@ -267,7 +268,7 @@
const queryRef = this.buildHasManyCollectionRef(store, snapshot, url, relationship);
const config = {
queryRef,
modelName: snapshot.modelName as string,
modelName: snapshot.modelName,
id: snapshot.id,
field: relationship.key,
referenceKeyName: this.referenceKeyName,
Expand Down Expand Up @@ -334,10 +335,10 @@
return relationship.options.filter?.(collectionRef, snapshot.record) || collectionRef;
}

const cardinality = snapshot.type.determineRelationshipType(relationship, store);
const cardinality = (snapshot.type as any).determineRelationshipType(relationship, store);

Check warning on line 338 in addon/adapters/cloud-firestore-modular.ts

View workflow job for this annotation

GitHub Actions / Tests

Unexpected any. Specify a different type

if (cardinality === 'manyToOne') {
const inverse = snapshot.type.inverseFor(relationship.key, store);
const inverse = (snapshot.type as any).inverseFor(relationship.key, store);

Check warning on line 341 in addon/adapters/cloud-firestore-modular.ts

View workflow job for this annotation

GitHub Actions / Tests

Unexpected any. Specify a different type
const snapshotCollectionName = buildCollectionName(snapshot.modelName.toString());
const snapshotDocRef = doc(db, `${snapshotCollectionName}/${snapshot.id}`);
const collectionRef = collection(db, url);
Expand Down
37 changes: 22 additions & 15 deletions addon/services/-firestore-data-manager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
/*
eslint
ember/use-ember-data-rfc-395-imports: off
*/

import { next } from '@ember/runloop';
// eslint-disable-next-line ember/use-ember-data-rfc-395-imports
import DS from 'ember-data';
import ModelRegistry from 'ember-data/types/registries/model';
import Service, { inject as service } from '@ember/service';
import StoreService from '@ember-data/store';

Expand Down Expand Up @@ -38,15 +43,15 @@ interface QueryListeners {
}

interface QueryFetchConfig {
modelName: string;
modelName: keyof ModelRegistry;
referenceKeyName: string;
recordArray: DS.AdapterPopulatedRecordArray<unknown>;
queryRef: Query,
queryId?: string,
}

interface HasManyFetchConfig {
modelName: string;
modelName: keyof ModelRegistry;
id: string;
field: string;
referenceKeyName: string;
Expand Down Expand Up @@ -75,7 +80,7 @@ export default class FirestoreDataManager extends Service {
}

public async findRecordRealtime(
modelName: string,
modelName: keyof ModelRegistry,
docRef: DocumentReference,
): Promise<DocumentSnapshot> {
const { path: listenerKey } = docRef;
Expand All @@ -88,7 +93,7 @@ export default class FirestoreDataManager extends Service {
}

public async findAllRealtime(
modelName: string,
modelName: keyof ModelRegistry,
colRef: CollectionReference,
): Promise<QuerySnapshot> {
const { path: listenerKey } = colRef;
Expand Down Expand Up @@ -143,14 +148,14 @@ export default class FirestoreDataManager extends Service {
): Promise<DocumentSnapshot[]> {
const querySnapshot = await getDocs(queryRef);
const promises = querySnapshot.docs.map((docSnapshot) => (
this.getReferenceToDoc(docSnapshot, '', referenceKey)
this.getReferenceToDoc(docSnapshot, '' as keyof ModelRegistry, referenceKey)
));

return Promise.all(promises);
}

private setupDocRealtimeUpdates(
modelName: string,
modelName: keyof ModelRegistry,
docRef: DocumentReference,
): Promise<void> {
return new Promise((resolve, reject) => {
Expand All @@ -171,7 +176,7 @@ export default class FirestoreDataManager extends Service {
}

private setupColRealtimeUpdates(
modelName: string,
modelName: keyof ModelRegistry,
colRef: CollectionReference,
): Promise<void> {
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -251,7 +256,7 @@ export default class FirestoreDataManager extends Service {

private handleSubsequentDocRealtimeUpdates(
docSnapshot: DocumentSnapshot,
modelName: string,
modelName: keyof ModelRegistry,
listenerKey: string,
): void {
if (docSnapshot.exists()) {
Expand All @@ -263,7 +268,7 @@ export default class FirestoreDataManager extends Service {
}

private handleSubsequentColRealtimeUpdates(
modelName: string,
modelName: keyof ModelRegistry,
listenerKey: string,
querySnapshot: QuerySnapshot,
): void {
Expand Down Expand Up @@ -339,15 +344,17 @@ export default class FirestoreDataManager extends Service {
// To avoid the issue, we run .reload() in the next runloop so that we allow the unload
// to happen first.
next(() => {
const hasManyRef = this.store.peekRecord(config.modelName, config.id).hasMany(config.field);
const hasManyRef = this.store.peekRecord(config.modelName, config.id)?.hasMany(
config.field as never,
);

hasManyRef.reload();
hasManyRef?.reload();
});
}

public async getReferenceToDoc(
docSnapshot: DocumentSnapshot,
modelName: string,
modelName: keyof ModelRegistry,
referenceKeyName: string,
isRealtime = false,
): Promise<DocumentSnapshot> {
Expand All @@ -360,7 +367,7 @@ export default class FirestoreDataManager extends Service {
return docSnapshot;
}

private pushRecord(modelName: string, snapshot: DocumentSnapshot): void {
private pushRecord(modelName: keyof ModelRegistry, snapshot: DocumentSnapshot): void {
const flatRecord = flattenDocSnapshot(snapshot);
const normalizedRecord = this.store.normalize(modelName, flatRecord);

Expand All @@ -373,7 +380,7 @@ export default class FirestoreDataManager extends Service {
}
}

private unloadRecord(modelName: string, id: string, path?: string): void {
private unloadRecord(modelName: keyof ModelRegistry, id: string, path?: string): void {
const record = this.store.peekRecord(modelName, id);

if (record !== null) {
Expand Down
12 changes: 6 additions & 6 deletions tests/unit/services/-firestore-data-manager-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ module('Unit | Service | -firestore-data-manager', function (hooks) {
const queryRef = query(colRef);
const config = {
queryRef,
modelName: 'user',
modelName: 'user' as const,
referenceKeyName: 'referenceTo',
recordArray: {
update: () => DS.PromiseArray.create({ promise: RSVP.Promise.resolve([]) }),
Expand All @@ -180,7 +180,7 @@ module('Unit | Service | -firestore-data-manager', function (hooks) {
const queryRef = query(colRef);
const config = {
queryRef,
modelName: 'user',
modelName: 'user' as const,
referenceKeyName: 'referenceTo',
recordArray: {
update: () => DS.PromiseArray.create({ promise: RSVP.Promise.resolve([]) }),
Expand All @@ -206,7 +206,7 @@ module('Unit | Service | -firestore-data-manager', function (hooks) {
const queryRef = query(colRef);
const config = {
queryRef,
modelName: 'user',
modelName: 'user' as const,
referenceKeyName: 'referenceTo',
queryId: 'test',
recordArray: {
Expand Down Expand Up @@ -240,7 +240,7 @@ module('Unit | Service | -firestore-data-manager', function (hooks) {
const queryRef = query(colRef);
const config = {
queryRef,
modelName: 'user',
modelName: 'user' as const,
id: 'user_a',
field: 'posts',
referenceKeyName: 'referenceTo',
Expand All @@ -264,7 +264,7 @@ module('Unit | Service | -firestore-data-manager', function (hooks) {
const queryRef = query(colRef);
const config = {
queryRef,
modelName: 'user',
modelName: 'user' as const,
id: 'user_a',
field: 'groups',
referenceKeyName: 'referenceTo',
Expand Down Expand Up @@ -296,7 +296,7 @@ module('Unit | Service | -firestore-data-manager', function (hooks) {
const queryRef = query(colRef);
const config = {
queryRef,
modelName: 'user',
modelName: 'user' as const,
id: 'user_a',
field: 'groups',
referenceKeyName: 'referenceTo',
Expand Down
Loading