-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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: Fix embedding of rule option schema array so that $ref's work #17208
Conversation
… are now possible
…to different embedding
|
Hi @matwilko!, thanks for the Pull Request The pull request title isn't properly formatted. We ask that you update the message to match this format, as we use it to generate changelogs and automate releases.
To Fix: You can fix this problem by clicking 'Edit' next to the pull request title at the top of this page. Read more about contributing to ESLint here |
✅ Deploy Preview for docs-eslint ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
Hi @matwilko! Thanks for the PR, but I'm not in favor of this change. In my opinion, supporting
|
Agreed that it's eslint specific, but it also breaks the implied promise of "provide some valid JSON Schemas and they'll work". I think it's valuable to be able to be able to drop in potentially already working schemas and have things "just work", otherwise this corner case seems like a pit of failure. I can definitely see how the ability to reference between the various array elements is probably a bit much - that kind of just fell out of the way I structured the definitions and would be easy enough to disable (so only internal To my mind, the corner case should be eliminated, either by supporting it (and the schema changes necessary to do so aren't that complex), or there needs to be some logic that will reject arrays-of-schemas that have any For the latter, it would be possible to construct a reduced meta-schema for the array case with the "advanced" features removed - perhaps just reducing to the basic types with none of the combining/referencing elements ( |
I think that eslint/lib/rules/no-restricted-exports.js Lines 29 to 90 in 5b68d51
|
See, now that I'm coming round to "array of schemas should be simple", I think that rule schema is kind of hard to read, at least in the sense that it's easy to miss the containing array and the implicit behaviour that entails - and I'd probably now suggest that that should graduate to a full object schema to explicitly spell out the behaviour 😄 Totally understand that it's not necessarily going to be possible to restrict the behaviour of arrays of schemas given the existing ecosystem, though I'd be interested to do a survey of existing plugins to see if the "advanced" behaviour is in use on a wider basis. I assume that kind of change would require an RFC though, if you thought it might be worth pursuing? |
I'm not sure if you're suggesting dropping the array form or limiting it to simple features only. Either way, while I agree that the array form might be more confusing (as it itself is not valid JSON Schema) than useful, I don't think we can make those changes at this point. |
Sure, I was just riffing on your "array-of-schemas should be simple" thought and seeing where it lead in terms of simplifying - let's drop that train of thought so we don't muddle the issue :) As a more concrete change that would address the original case of I know ESLint doesn't do any validation of the schema at runtime beyond the implied check that As a starting point, I can go suggest some new rules over in Given that there seems to be movement towards tightening up schemas for rules in v9, would there be any appetite for going one step further and adding some enforcement at runtime of "valid schemas"? A lot of the kinds of invalid schema possible today will cause an error at runtime anyway (e.g. the A more informative error message pointing out that "Rule A from Plugin B is malformed, please go bother the plugin author" would probably be better than some cryptic message about the user's config that they can't fix. Moving this enforcement to runtime also means invalid schemas will be picked up by I realise this would be a breaking change to core, so would need an RFC, just floating the idea - I know that it might just be a "we already considered this in the past and it's a hard no" case. |
We prefer not to validate schemas at runtime as there's not much the end user can do about it aside from turning the rule off, while the rule might actually be working perfectly well for them with their configuration for that rule. On the other hand, we can consider adding more validations directly in |
Just catching up on this, and I think all of the relevant points have already been made. Overall I agree with @mdjermanovic that this change isn't worth the additional complexity. ESLint is ten years old, and making changes to how we do schemas now, while making things technically more correct, has the potential to cause problems for existing plugins. We already had to abort upgrading Ajv because it was more strictly following JSON Schema which led to more errors in existing rules. I also agree with @mdjermanovic that we can always add more validation into Thanks! |
Prerequisites checklist
What is the purpose of this pull request? (put an "X" next to an item)
[X] Documentation update
[X] Bug fix (template)
[ ] New rule (template)
[ ] Changes an existing rule (template)
[ ] Add autofix to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:
What changes did you make? (Give an overview)
As documented at Options Schemas, ESLint will break
$ref
's in schemas when providing an array of schemas ($ref
will work fine in explicit schemas).These
$ref
's break because ESLint currently embeds these schemas directly into a new schema, and therefore the path that a$ref
might have previously been referencing is no longer valid. It is technically possible to construct a working$ref
by having it account for the new structure, but this relies on implementation details and shouldn't be supported.JSON Schemas do however support bundling multiple schemas together into a single document, allowing them to separately process
$ref
's locally. This does require each bundled schema to have a unique$id
, and any$ref
's below will be resolved relative to that schema. If the$id
is chosen carefully, the schemas can also reference each other via{ $ref: '/n/some/json/path' }
, so common definitions can be shared between them.There's a few details I'm omitting here (but are in the code and the docs in the PR), but here's a before and after transform to show the change of layout:
For simple schemas without any
$ref
's involved, there's no performance penalty, as ajv will inline those schemas when compiling the validation function.Is there anything you'd like reviewers to focus on?
Since it's technically possible to make
$ref
's work currently (by relying on implementation details), does this count as non-backwards-compatible, as it can in theory break existing rule schemas? Relying on undocumented behaviour seems like the kind of thing it's ok to break to me, but I'm not sure what ESLint's appetite for that is. I'd anticipate that it wouldn't be a big problem since the docs pretty clearly warn off using$ref
for array schemas entirely.I've only added tests for the new
$ref
support ingetRuleOptionsSchema
, but #17198 includes a more comprehensive set of tests to ensure this change doesn't break existing functionality if that is merged before this. I'll rebase and properly merge the tests in if/when that PR is merged, in the meantime, feedback on this change by itself would be welcome :)