-
Notifications
You must be signed in to change notification settings - Fork 621
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 non-canonical crate name pages #10369
Conversation
app/routes/crate.js
Outdated
return await this.store.findRecord('crate', crateName); | ||
return await this.store.queryRecord('crate', { name: crateName }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as mentioned in the issue, ideally we would redirect the user to the same route, but with the crate name replaced. this appears to be non-trivial though, since the user could also have requested a child route and we would potentially redirect them to the wrong route. I think this fix matches the previous behavior though, so it's probably good enough for now :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough! I have no idea why this would be somewhat non-trivial in Ember, especially for nested routes 😅
Since queryRecord
would make a request for every call, should we optimize this to something like peekRecord
+ queryRecord
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we optimize this to something like
peekRecord
+queryRecord
?
hmm, I guess that makes sense, yeah
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from the missing e2e tests, this looks good to me. The optimization part could also be implemented in a separate PR later.
tests/acceptance/crate-test.js
Outdated
test('treats dash and underscore as equal', async function (assert) { | ||
let crate = this.server.create('crate', { name: 'foo-bar' }); | ||
this.server.create('version', { crate }); | ||
|
||
await visit('/crates/foo_bar'); | ||
|
||
assert.strictEqual(currentURL(), '/crates/foo_bar'); | ||
assert.strictEqual(currentRouteName(), 'crate.index'); | ||
assert.strictEqual(getPageTitle(), 'foo-bar - crates.io: Rust Package Registry'); | ||
|
||
assert.dom('[data-test-heading] [data-test-crate-name]').hasText('foo-bar'); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should also check this in e2e.
I got an alternative workaround for this issue this morning. Since we know how to normalize // crates.io/app/initializers/ember-data-identifier.js
import { setIdentifierGenerationMethod } from '@ember-data/store';
function toCanoncialName(name) {
return name.toLowerCase().replace(/_/g, '-');
}
export function initialize(_app) {
const generationMethod = (resource, _bucket) => {
let { id, lid, type } = resource;
if (lid) {
return lid;
}
if (id) {
if (resource.type === 'crate') {
id = toCanoncialName(id);
}
return `@lid:${type}-${id}`;
}
return crypto.randomUUID();
};
setIdentifierGenerationMethod(generationMethod);
}
export default {
name: 'app.configure-ember-data-identifier',
initialize,
}; This way, IDs with dashes or underscores would be canonicalized to a single unique This approach has the benefit of not requiring modifications to other business logic. However, the downside is that if the response Footnotes |
3a3e699
to
20d368e
Compare
I like the approach, but unfortunately this seems to break our API token creation flow, at least with the proposed implementation. it seems to be missing the |
85c637a
to
4b40251
Compare
Ah, that's indeed unfortunate. It would be nice if upstream exported the default generation method, then we could just use it as a fallback.
Fair enough, unless the generation method approach could be easier to use without modifying other places, I think the adapter approach would make more sense. |
mirage/route-handlers/crates.js
Outdated
function toCanonicalName(name) { | ||
return name.toLowerCase().replace(/_/g, '-'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙋 The canonical implementation in the backend(database) actually replaces -
with _
, but here we replace _
with -
. Is this difference intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this difference intentional?
no, it's not intentional. I guess ultimately it doesn't really matter which way around we do it, but I'll adjust it so that it matches.
Before the Ember Data 5 update it was possible to visit `/crates/foo-bar` when the crate was actually called `foo_bar` and vice-versa. The Ember Data 5 update broke this behavior, and this commit is restoring it, by using `queryRecord()` instead of `findRecord()`, which can no longer deal with requesting a certain `id` and getting a different one returned from the server.
4b40251
to
fbe6234
Compare
Before the Ember Data 5 update it was possible to visit
/crates/foo-bar
when the crate was actually calledfoo_bar
and vice-versa. The Ember Data 5 update broke this behavior, and this PR is restoring it, by usingqueryRecord()
instead offindRecord()
, which can no longer deal with requesting a certainid
and getting a different one returned from the server.Fixes #10368