Skip to content

Commit aa5f80d

Browse files
authored
feat: Endpoint.name (#914)
1 parent 63e8bc9 commit aa5f80d

File tree

5 files changed

+56
-4
lines changed

5 files changed

+56
-4
lines changed

packages/endpoint/src/__tests__/endpoint.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,22 @@ describe('Endpoint', () => {
102102
}).rejects.toBeDefined();
103103
});
104104

105+
it('should have a name', () => {
106+
const UserDetail = new Endpoint(fetchUsersIdParam);
107+
expect(UserDetail.name).toBe('fetchUsersIdParam');
108+
const Next = new Endpoint(fetchUsersIdParam, { name: 'specialName' });
109+
expect(Next.name).toBe('specialName');
110+
const Another = Next.extend({ name: 'new' });
111+
expect(Another.name).toBe('new');
112+
const Third = Another.extend({ method: 'POST' }).extend({ extra: 5 });
113+
expect(Third.name).toBe('new');
114+
expect(Third.key('5')).toMatchInlineSnapshot(`"new [\\"5\\"]"`);
115+
const Fourth = Third.extend({ fetch: fetchUserList });
116+
expect(Fourth.name).toBe('fetchUserList');
117+
const Weird = new Endpoint(fetchUsersIdParam, { fetch: fetchUserList });
118+
expect(Weird.name).toBe(`fetchUsersIdParam`);
119+
});
120+
105121
it('should work when called with string parameter', async () => {
106122
const UserDetail = new Endpoint(fetchUsersIdParam);
107123

packages/endpoint/src/endpoint.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,27 @@ export default class Endpoint extends Function {
3838
self.getFetchKey = params => self.key(params);
3939

4040
if (fetchFunction) self.fetch = fetchFunction;
41+
42+
if (options && 'name' in options) {
43+
self.__name = options.name;
44+
delete options.name;
45+
} else if (fetchFunction) {
46+
self.__name = fetchFunction.name;
47+
}
4148
Object.assign(self, options);
49+
Object.defineProperty(self, 'name', {
50+
get: function () {
51+
return this.__name;
52+
},
53+
});
4254

4355
/** The following is for compatibility with FetchShape */
4456
runCompat(self, options);
4557
return self;
4658
}
4759

4860
key(...args) {
49-
return `${this.fetch.name} ${JSON.stringify(args)}`;
61+
return `${this.name} ${JSON.stringify(args)}`;
5062
}
5163

5264
bind(thisArg, ...args) {

packages/experimental/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
},
8181
"peerDependencies": {
8282
"@rest-hooks/core": "^1.2.1",
83-
"@rest-hooks/endpoint": "^1.1.3",
83+
"@rest-hooks/endpoint": "^1.2.0",
8484
"@types/react": "^16.8.4 || ^17.0.0 || ^18.0.0-0",
8585
"react": "^16.8.4 || ^17.0.0 || ^18.0.0-0"
8686
},

packages/experimental/src/rest/BaseResource.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,22 @@ export default abstract class BaseResource extends Entity {
147147
*
148148
* Relies on existance of runInit() member.
149149
*/
150-
protected static memo<T>(name: string, construct: () => T): T {
150+
protected static memo<T extends { extend: (...args: any) => any }>(
151+
name: string,
152+
construct: () => T,
153+
): T {
151154
if (!Object.hasOwnProperty.call(this, this.cacheSymbol)) {
152155
(this as any)[this.cacheSymbol] = {};
153156
}
154157
const cache = (this as any)[this.cacheSymbol];
155158
if (!(name in cache)) {
156-
cache[name] = construct();
159+
// eslint-disable-next-line @typescript-eslint/no-this-alias
160+
const resource: any = this;
161+
cache[name] = construct().extend({
162+
get name() {
163+
return `${resource.name}.${name.replace(/#/, '')}`;
164+
},
165+
});
157166
}
158167
return cache[name].useFetchInit() as T;
159168
}

packages/experimental/src/rest/__tests__/Resource.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,21 @@ describe('Resource', () => {
9696
nock.cleanAll();
9797
});
9898

99+
it('should automatically name methods', () => {
100+
expect(PaginatedArticleResource.detail().name).toBe(
101+
'PaginatedArticleResource.detail',
102+
);
103+
expect(PaginatedArticleResource.list().name).toBe(
104+
'PaginatedArticleResource.list',
105+
);
106+
expect(PaginatedArticleResource.create().name).toBe(
107+
'PaginatedArticleResource.create',
108+
);
109+
expect(PaginatedArticleResource.delete().name).toBe(
110+
'PaginatedArticleResource.delete',
111+
);
112+
});
113+
99114
it('should update on get for a paginated resource', async () => {
100115
mynock.get(`/article-paginated/`).reply(200, paginatedFirstPage);
101116
mynock.get(`/article-paginated/?cursor=2`).reply(200, paginatedSecondPage);

0 commit comments

Comments
 (0)