Skip to content

Commit 3ae5011

Browse files
Jon Ristajrista
authored andcommitted
feat: entity decorator
+ Add @entity decorator for models + Implement required modelName option + Implement optional pluralName option + Implement optional uriName option + Implement optional comparer function option + Implement effect exclusion feature + Add sorted$ facade stream and selectAllSorted selector * Fix prod build issue with modelName in @entity decorator * Improve robustness of all selectors when state is falsy + Added test-app for simpler app than demo to test library features with Issue #70 #58 #81
1 parent cd19510 commit 3ae5011

File tree

75 files changed

+1263
-241
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+1263
-241
lines changed

CHANGELOG.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
<a name="0.4.0"></a>
2+
3+
# [0.4.0](https://github.com/briebug/ngrx-auto-entity/compare/0.3.1...0.4.0) Beta (2020-01-13)
4+
5+
Introducing the `@Entity` decorator for model classes. This decorator provides custom naming capabilities,
6+
the ability to filter which auto-entity pre-fab effects handle each model, as well as define a default
7+
comparer for sorting entities retrieved with a new .sorted$ stream on pre-fab facades.
8+
9+
### Features
10+
- **decorators:** Add `@Entity` decorator for models with modelName, pluralName, uriName properties (#70)
11+
- **decorators:** Add `excludeEffects` functionality to `@Entity` decorator for filtering which effects handle entity
12+
- **decorators:** Add `comparer` property to `@Entity` decorator to support selecting sorted entities (#58)
13+
- **selectors:** Add `selectAllSorted` selector that uses entity comparer to sort on selection (#58)
14+
- **facades:** Add `sorted$` stream to return all entities in sorted order from `selectAllSorted` selector (#58)
15+
16+
### Internal
17+
18+
- **decorators:** Moved all decorators into internal /lib/decorators directory (will break direct imports, use public api!)
19+
20+
### Bug Fix
21+
- **selectors:** Added additional falsy checks to all selectors to limit frequency of hard failures (#81)
22+
- **decorators:** Added `modelName` to `@Entity` decorator to allow explicit definition of model name immune to mangling by code minifiers (#81)
23+
124
<a name="0.3.1"></a>
225

326
# [0.3.1](https://github.com/briebug/ngrx-auto-entity/compare/0.3.0...0.3.1) Beta (2020-01-07)
@@ -23,7 +46,7 @@ Correlated actions are usually sets of request/success/failure actions, such as
2346

2447
### Features
2548

26-
- **correlated actions:** Add `correlationId` property to `EntityAction` for tracking correlated actions.
49+
- **correlated actions:** Add `correlationId` property to `EntityAction` for tracking correlated actions. (#75)
2750

2851
### Package
2952

@@ -58,11 +81,11 @@ custom effects creation.
5881

5982
### Features
6083

61-
- **actions:** Add fromEntityTypes factory function for multi-entity multi-action effects filtering
84+
- **actions:** Add fromEntityTypes factory function for multi-entity multi-action effects filtering (#66)
6285

6386
### Bug Fixes
6487

65-
- **selectors:** Add createdAt facade getter and corresponding selectors
88+
- **selectors:** Add createdAt facade getter and corresponding selectors (#65)
6689

6790

6891

angular.json

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,106 @@
116116
}
117117
}
118118
}
119+
},
120+
"test-app": {
121+
"projectType": "application",
122+
"schematics": {},
123+
"root": "projects/test-app",
124+
"sourceRoot": "projects/test-app/src",
125+
"prefix": "app",
126+
"architect": {
127+
"build": {
128+
"builder": "@angular-devkit/build-angular:browser",
129+
"options": {
130+
"outputPath": "dist/test-app",
131+
"index": "projects/test-app/src/index.html",
132+
"main": "projects/test-app/src/main.ts",
133+
"polyfills": "projects/test-app/src/polyfills.ts",
134+
"tsConfig": "projects/test-app/tsconfig.app.json",
135+
"aot": false,
136+
"assets": [
137+
"projects/test-app/src/favicon.ico",
138+
"projects/test-app/src/assets"
139+
],
140+
"styles": [
141+
"projects/test-app/src/styles.css"
142+
],
143+
"scripts": []
144+
},
145+
"configurations": {
146+
"production": {
147+
"fileReplacements": [
148+
{
149+
"replace": "projects/test-app/src/environments/environment.ts",
150+
"with": "projects/test-app/src/environments/environment.prod.ts"
151+
}
152+
],
153+
"optimization": true,
154+
"outputHashing": "all",
155+
"sourceMap": false,
156+
"extractCss": true,
157+
"namedChunks": false,
158+
"aot": true,
159+
"extractLicenses": true,
160+
"vendorChunk": false,
161+
"buildOptimizer": true,
162+
"budgets": [
163+
{
164+
"type": "initial",
165+
"maximumWarning": "2mb",
166+
"maximumError": "5mb"
167+
}
168+
]
169+
}
170+
}
171+
},
172+
"serve": {
173+
"builder": "@angular-devkit/build-angular:dev-server",
174+
"options": {
175+
"browserTarget": "test-app:build"
176+
},
177+
"configurations": {
178+
"production": {
179+
"browserTarget": "test-app:build:production"
180+
}
181+
}
182+
},
183+
"extract-i18n": {
184+
"builder": "@angular-devkit/build-angular:extract-i18n",
185+
"options": {
186+
"browserTarget": "test-app:build"
187+
}
188+
},
189+
"test": {
190+
"builder": "@angular-devkit/build-angular:karma",
191+
"options": {
192+
"main": "projects/test-app/src/test.ts",
193+
"polyfills": "projects/test-app/src/polyfills.ts",
194+
"tsConfig": "projects/test-app/tsconfig.spec.json",
195+
"karmaConfig": "projects/test-app/karma.conf.js",
196+
"assets": [
197+
"projects/test-app/src/favicon.ico",
198+
"projects/test-app/src/assets"
199+
],
200+
"styles": [
201+
"projects/test-app/src/styles.css"
202+
],
203+
"scripts": []
204+
}
205+
},
206+
"lint": {
207+
"builder": "@angular-devkit/build-angular:tslint",
208+
"options": {
209+
"tsConfig": [
210+
"projects/test-app/tsconfig.app.json",
211+
"projects/test-app/tsconfig.spec.json"
212+
],
213+
"exclude": [
214+
"**/node_modules/**"
215+
]
216+
}
217+
}
218+
}
119219
}
120220
},
121221
"defaultProject": "ngrx-auto-entity-app"

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
"ng": "ng",
66
"start": "concurrently --prefix-colors white.bgBlue,white.bgRed --names angular,json-server --kill-others \"npm run serve-proxy\" \"npm run json-server\"",
77
"serve": "ng serve --source-map --vendorSourceMap",
8-
"serve-proxy": "ng serve --source-map --vendorSourceMap --proxy-config proxy.conf.json",
8+
"serve:prod": "ng serve --prod --source-map --vendorSourceMap",
9+
"serve:test": "ng serve test-app --prod --source-map --vendorSourceMap",
10+
"serve:test:prod": "ng serve test-app --source-map --vendorSourceMap",
11+
"serve-proxy": "ng serve --prod --source-map --vendorSourceMap --proxy-config proxy.conf.json",
12+
"serve-proxy:test": "ng serve test-app --source-map --vendorSourceMap --proxy-config proxy.conf.json",
13+
"serve-proxy:test:prod": "ng serve test-app --prod --source-map --vendorSourceMap --proxy-config proxy.conf.json",
914
"build": "ng build --prod",
1015
"build:watch": "ng build --prod --watch",
1116
"build:app": "ng build ngrx-auto-entity-app --prod",

projects/ngrx-auto-entity/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "0.3.1",
2+
"version": "0.4.0",
33
"name": "@briebug/ngrx-auto-entity",
44
"description": "Automatic Entity State and Facades for NgRx. Simplifying reactive state!",
55
"keywords": [

projects/ngrx-auto-entity/src/index.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,20 @@ export {
9999
Clear
100100
} from './lib/actions';
101101

102-
export { Key, getKey, getKeyFromModel, getKeyNames, getKeyNamesFromModel, checkKeyName } from './lib/decorators';
102+
export {
103+
IEffectExclusions,
104+
IEffectExcept,
105+
IEntityOptions,
106+
Entity,
107+
all,
108+
extra,
109+
loads,
110+
curd,
111+
except,
112+
matching
113+
} from './lib/decorators/entity';
114+
115+
export { Key, getKey, getKeyFromModel, getKeyNames, getKeyNamesFromModel, checkKeyName } from './lib/decorators/key';
103116

104117
export { EntityOperators } from './lib/operators';
105118

projects/ngrx-auto-entity/src/lib/actions.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ import {
5353
UpdateManySuccess,
5454
UpdateSuccess
5555
} from './actions';
56-
import { Key } from './decorators';
56+
import { Key } from './decorators/key';
5757

5858
class TestEntity {
5959
@Key id: number;

projects/ngrx-auto-entity/src/lib/actions.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ import { Actions } from '@ngrx/effects';
22
import { Action } from '@ngrx/store';
33
import { merge, Observable, OperatorFunction } from 'rxjs';
44
import { filter } from 'rxjs/operators';
5+
56
import { pascalCase } from '../util/case';
6-
import { checkKeyName } from './decorators';
7+
import { IEntityOptions } from './decorators/entity';
8+
import { ENTITY_OPTS_PROP } from './decorators/entity-tokens';
9+
import { checkKeyName } from './decorators/key';
710
import { IPageInfo, IRangeInfo, Page, Range } from './models';
811
import { EntityIdentity } from './util';
912

@@ -94,6 +97,8 @@ export enum EntityActionTypes {
9497
*/
9598
export interface IEntityInfo {
9699
modelName: string;
100+
pluralName?: string;
101+
uriName?: string;
97102
modelType: new () => any;
98103
}
99104

@@ -110,9 +115,14 @@ export interface IEntityAction extends Action, ICorrelatedAction {
110115

111116
// tslint:disable
112117
const uuid = (a?, b?) => {
113-
for (b = a = ''; a++ < 36; b += a * 51 & 52 ? (a ^ 15 ? 8 ^ Math.random() * (a ^ 20 ? 16 : 4) : 4).toString(16) : '-') ;
118+
for (
119+
b = a = '';
120+
a++ < 36;
121+
b += (a * 51) & 52 ? (a ^ 15 ? 8 ^ (Math.random() * (a ^ 20 ? 16 : 4)) : 4).toString(16) : '-'
122+
);
114123
return b;
115124
};
125+
116126
// tslint:enable
117127

118128
/**
@@ -130,10 +140,14 @@ export abstract class EntityAction<TModel> implements IEntityAction {
130140

131141
const setInfo = (type: any): IEntityInfo => {
132142
const instance = new type();
133-
checkKeyName(type, instance.constructor.name);
143+
const opts = (type[ENTITY_OPTS_PROP] || { modelName: instance.constructor.name }) as IEntityOptions;
144+
const modelName = opts.modelName;
145+
checkKeyName(type, modelName);
134146
return {
135147
modelType: type,
136-
modelName: instance.constructor.name
148+
modelName,
149+
pluralName: opts.pluralName,
150+
uriName: opts.uriName
137151
};
138152
};
139153

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const ENTITY_OPTS_PROP = '__nae_entity_opts';

0 commit comments

Comments
 (0)