loopbackio / loopbackio/loopback-next
Allow RegExp values for `jsonSchema.pattern` field in property definition
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- TypeScript
- Sterne
- 5.1k
- Forks
- 1.1k
- Ø Merge
- 2 T. 21 Std.
- Gemergte PRs (30 T.)
- 27
Beschreibung
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.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne für die Arbeit am abgegrenzten Modell in packages/repository-json-schema/src/build-schema.ts bei metaToJsonProperty(), und füge dann Fälle zu packages/repository-json-schema/src/__tests__/unit/build-schema.unit.ts hinzu. Führe die Unit-Tests von repository-json-schema aus und überprüfe, dass RegExp-Muster durch ihre Quellstrings dargestellt werden. Der umfassendere REST-Teil erfordert Akzeptanztests für gültige und ungültige Anfragen sowie das generierte OpenAPI-Dokument, während die Aktualisierung der Dokumentation die Verwendung von jsonSchema.pattern abdecken sollte.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- openapi, typescript
- Bereich
- api, backend-api-design, documentation, testing
- Issue-Typ
- Feature
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 45/100