Skip to content

feat: simpler validation #70

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

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,59 @@

This lib is fully documented and so you'll find detailed [migration guides](./MIGRATION.md).

## 7.5.0 (2019-01-18)

### Features

- Added predefined constants for basic JSON schemas to simplify validation:
- `SCHEMA_BOOLEAN` (shortcut for: `{ type: 'boolean' }`)
- `SCHEMA_INTEGER` (shortcut for: `{ type: 'integer' }`)
- `SCHEMA_NUMBER` (shortcut for: `{ type: 'number' }`)
- `SCHEMA_STRING` (shortcut for: `{ type: 'string' }`)
- `SCHEMA_ARRAY_OF_BOOLEANS` (shortcut for: `{ items: { type: 'boolean' } }`)
- `SCHEMA_ARRAY_OF_INTEGER` (shortcut for: `{ items: { type: 'integer' } }`)
- `SCHEMA_ARRAY_OF_NUMBER` (shortcut for: `{ items: { type: 'number' } }`)
- `SCHEMA_ARRAY_OF_STRINGS` (shortcut for: `{ items: { type: 'string' } }`)

This is especially useful for advanced types (arrays, objects, nested types),
to avoid TypeScript limitations.

- For the same types as above, the result type is now automatically infered,
meaning you don't need to cast anymore!

Before v7.5:
```typescript
this.localStorage.getItem('test', { schema: { type: 'string' } })
.subscribe((result) => {
result; // type: any :(
});

this.localStorage.getItem<string>('test', { schema: { type: 'string' } })
.subscribe((result) => {
result; // type: string :)
});
```

From v7.5:
```typescript
import { SCHEMA_STRING } from '@ngx-pwa/local-storage';

this.localStorage.getItem('test', { schema: SCHEMA_STRING })
.subscribe((result) => {
result; // type: string :D
});
```

- Added better interfaces for some JSON schemas:
- `JSONSchemaArrayOf<T>`
- `JSONSchemaConstOf<T>`
- `JSONSchemaEnumOf<T>`

**See the [new validation guide](./docs/VALIDATION.md).**

This is only a feature release, so don't worry: nothing changes in existing code.
It's just new tools to simplify validation and thus ease migration to v7.

## 7.4.0 (2019-01-12)

### Feature
Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,6 @@ this.localStorage.getItem<User>('user').subscribe((user) => {
});
```

As any data can be stored, you can type your data.

Not finding an item is not an error, it succeeds but returns `null`.

```typescript
Expand All @@ -133,7 +131,7 @@ Starting with *version 5*, you can use a [JSON Schema](http://json-schema.org/)
A [migration guide](./docs/MIGRATION_TO_V7.md) is available.

```typescript
this.localStorage.getItem<string>('test', { schema: { type: 'string' } })
this.localStorage.getItem('test', { schema: { type: 'string' } })
.subscribe((user) => {
// Called if data is valid or null
}, (error) => {
Expand Down
15 changes: 9 additions & 6 deletions docs/MIGRATION_TO_V7.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,10 @@ this.localStorage.getItem<string>('test').subscribe((result) => {
});
```

It's only a convenience allowed by the library. It's useful when you're already validating the data with a JSON schema,
to cast the data type.

But **when you were not validating the data, it was really bad**.
`getItem<string>` **doesn't perform any real validation**.
Casting like this only means: "TypeScript, trust me, I'm telling you it will be a string".
But TypeScript won't do any real validation as it can't:
**TypeScript can only manage checks at compilation time, while client-side storage checks can only happen at runtime**.
**TypeScript can only manage checks at *compilation* time, while client-side storage checks can only happen at *runtime***.

So you ended up with a `string` type while the real data may not be a `string` at all, leading to security issues and errors.

Expand All @@ -89,7 +86,9 @@ The simpler and better way to validate your data is to search `getItem` in your
and **use the JSON schema option proposed by the lib**. For example:

```typescript
this.localStorage.getItem<string>('test', { schema: { type: 'string' } })
import { SCHEMA_STRING } from '@ngx-pwa/local-storage';

this.localStorage.getItem('test', { schema: SCHEMA_STRING })
.subscribe((result) => {
result; // type: string
result.substr(0, 2); // OK
Expand All @@ -98,6 +97,10 @@ this.localStorage.getItem<string>('test', { schema: { type: 'string' } })

**A [full validation guide](./VALIDATION.md) is available with all the options.**

Note the above example only works with version >= 7.5, which has done a lot of things to simplify validation:
- predefined constants (like `SCHEMA_STRING`) are available for common structures,
- casting (`.getItem<string>`) is no longer required for most types, as it's now automatically infered.

### Solution 2: custom validation (painful)

You can use all the native JavaScript operators and functions to validate. For example:
Expand Down
Loading