loopbackio / loopbackio/loopback-next
Allow RegExp values for `jsonSchema.pattern` field in property definition
Personne n'a encore pris cette issue.
- Langage dominant
- TypeScript
- Étoiles
- 5.1k
- Forks
- 1.1k
- Merge moyen
- 2 j 21 h
- PR mergées (30 j)
- 27
Description
When creating a model, I'd like to specify pattern-based validation for my `phoneNum` property:
```ts
@property({
type: 'string',
jsonSchema: {
pattern: /\d{3}-\d{3}-\d{4}/,
},
})
phoneNum?: string;
```
At the moment, we require the pattern to be a string source:
```js
pattern: '\\d{3}-\\d{3}-\\d{4}'
```
I find these strings problematic:
- Editors/IDEs don't highlight RegExp keywords
- It's easy to forget to escape `\` characters. When they are not escaped, users end up with a different RegExp that expected - see #4218 for an example.
## Workaround
Use `RegExp.source` property to convert from a RegExp instance to a source string.
```ts
@property({
type: 'string',
jsonSchema: {
pattern: /\d{3}-\d{3}-\d{4}/.source,
},
})
phoneNum?: string;
```
## Acceptance criteria
### Models (the important and also easy part)
Allow LB4 app developers to use RegExp `pattern` values in their model definitions, scoped to `jsonSchema` only for now (i.e. to apply during REST API validation only, not as a database constraint). Example property definition:
```ts
@property({
jsonSchema: {
pattern: /\d{3}-\d{3}-\d{4}/,
},
})
phoneNum?: string;
```
- [ ] Implementation: The conversion from `RegExp` to `string` should probably happen inside [`metaToJsonProperty()`](https://github.com/strongloop/loopback-next/blob/b0a84b5adc30cac3614ea90e414b59cf76009ecf/packages/repository-json-schema/src/build-schema.ts#L296-L298) function. Use [`RegExp.prototype.source`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source) property to convert a `RegExp` instance to a string.
- [ ] Test coverage: Add tests to verify the new behavior, e.g. to [`packages/repository-json-schema/src/__tests__/unit/build-schema.unit.ts`](https://github.com/strongloop/loopback-next/blob/b0a84b5adc30cac3614ea90e414b59cf76009ecf/packages/repository-json-schema/src/__tests__/unit/build-schema.unit.ts)
- [ ] Docs: Update documentation to explain users how to use `jsonSchema` and `jsonSchema.pattern` in `@property()` decorators - see e.g. https://loopback.io/doc/en/lb4/Model.html#supported-json-keywords
### REST API layer (optional, could be difficult to implement)
Allow LB4 app developers to use RegExp values in OpenAPI spec metadata, e.g. provided via Controller decorators.
```ts
class MyController {
greet(
@param({
name: 'date',
in: 'path',
schema: {
type: 'string',
pattern: /^\d{4}-\d{2}-\d{2}$/,
}
})
today: string,
) {
return `Good morning, today is ${date}`;
}
}
```
Start by writing a group of (acceptance-level) tests to verify handling of RegExp patterns by our REST API layer:
- [ ] Define a controller with a method with a parameter using `pattern`-based validation and a RegExp pattern value.
- [ ] Send a request with a valid value expecting 200 response.
- [ ] Send a request with an invalid value expecting 4xx response.
- [ ] Verify that the OpenAPI spec document returned by the app includes the pattern converted to string via `.source` property. Quoting from https://github.com/OAI/OpenAPI-Specification/blob/3.0.1/versions/3.0.1.md#properties: _pattern (This string SHOULD be a valid regular expression, according to the ECMA 262 regular expression dialect)_
- [ ] Fix the implementation (and type definitions) as necessary to allow such test to pass.
- [ ] I think we will need to update `@param` definitions to allow `RegExp` values for `pattern` fields.
- [ ] Figure out how to pass `RegExp` patterns to AJV so that it can perform pattern-base validation. It's possible that AJV supports RegExp values out of the box, in which case no changes may be required
## Out of scope
`pattern` as a top-level model property:
```ts
@property({
pattern: /\d{3}-\d{3}-\d{4}/,
...
})
```
Quoting from https://github.com/strongloop/loopback-next/issues/4228#issuecomment-646700989:
> The catch is that once `pattern` is a regular property metadata, it must be enforced both at REST API level (`@loopback/rest` must translate that pattern to AJV JSON Schema field) and at data-access level (by loopback-datasource-juggler), so it's more work to make this happen 🤷 The upside is that with a new property-level metadata, connectors can translate the `pattern` constraint to a database constraint too ([a PostgreSQL example](https://stackoverflow.com/a/35822507/69868)). Related: Epic: Validation at Model/ORM level #1872.
---
## 🎆 Hacktoberfest 2020
Greetings :wave: to all Hacktoberfest 2020 participants!
Here are few tips 👀 to make your start easier:
- Before you start working on this issue, please leave a comment to let others know.
- Feel free to implement support for RegExp patterns in model property definitions only, it's ok to leave the rest for others to pick up.
- If you are new to GitHub pull requests, then you can learn about the process in [Submitting a pull request to LoopBack 4](https://loopback.io/doc/en/lb4/submitting_a_pr.html).
- If this is your first contribution to LoopBack, then please take a look at our [Developer guide](https://loopback.io/doc/en/lb4/code-contrib-lb4.html)
- Feel free to ask for help in `#loopback-contributors` channel, you can join our Slack workspace [here](https://join.slack.com/t/loopbackio/shared_invite/zt-8lbow73r-SKAKz61Vdao~_rGf91pcsw).
See also #6456.
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Pour le travail ciblé sur le modèle, commencez dans packages/repository-json-schema/src/build-schema.ts, au niveau de metaToJsonProperty(), puis ajoutez des cas dans packages/repository-json-schema/src/__tests__/unit/build-schema.unit.ts. Exécutez les tests unitaires de repository-json-schema et vérifiez que les motifs RegExp sont représentés par leurs chaînes source. La partie REST plus large nécessite des tests d’acceptation pour les requêtes valides et invalides ainsi que le document OpenAPI généré, tandis que la mise à jour de la documentation devrait couvrir l’utilisation de jsonSchema.pattern.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- openapi, typescript
- Domaine
- api, backend-api-design, documentation, testing
- Type d'issue
- Fonctionnalité
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 45/100