Skip to content

Commit 33d4e8e

Browse files
authored
Version 2.0 (#36)
* Clean up code and update build packages * Remove sjsId * Move sjsOptions * Add return type to toJSON * Change return type of clone
1 parent 5381887 commit 33d4e8e

23 files changed

+1225
-748
lines changed

.eslintignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.generated
2+
.github
3+
.jest-cache
4+
.scripts
5+
.vscode
6+
docs
7+
node_modules
8+
tools
9+
build
10+
*.d.ts

.eslintrc.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// https://nextjs.org/docs/basic-features/eslint
2+
// https://paulintrognon.fr/blog/typescript-prettier-eslint-next-js
3+
4+
module.exports = {
5+
plugins: ['typescript-sort-keys', 'unused-imports'],
6+
extends: [
7+
'plugin:@typescript-eslint/recommended',
8+
'plugin:typescript-sort-keys/recommended',
9+
// Make sure this is always the last configuration in the extends array.
10+
'prettier',
11+
],
12+
rules: {
13+
// 0 = off, 1 = warn, 2 = error
14+
'@typescript-eslint/no-explicit-any': 'off',
15+
'@typescript-eslint/no-unused-vars': ['error', { args: 'none', ignoreRestSiblings: true }],
16+
'@typescript-eslint/no-empty-interface': 'off',
17+
'@typescript-eslint/no-inferrable-types': 'off',
18+
'@typescript-eslint/no-empty-function': 'off',
19+
'@typescript-eslint/interface-name-prefix': 0,
20+
'@typescript-eslint/explicit-function-return-type': 0,
21+
'@typescript-eslint/no-shadow': 2,
22+
'array-bracket-spacing': [2, 'never'],
23+
'no-return-await': 2,
24+
'id-length': ['error', { exceptions: ['_', 'x', 'y', 'a', 'b'] }],
25+
curly: 2,
26+
'eol-last': 2,
27+
'keyword-spacing': [
28+
2,
29+
{
30+
before: true,
31+
after: true,
32+
},
33+
],
34+
'import/no-cycle': [0, { maxDepth: 1 }],
35+
'no-console': [2, { allow: ['warn', 'error', 'info', 'groupCollapsed', 'group', 'groupEnd'] }],
36+
'no-const-assign': 2,
37+
'no-empty-pattern': 2,
38+
'no-eval': 2,
39+
'no-global-assign': 2,
40+
'no-mixed-spaces-and-tabs': 2,
41+
'no-multi-assign': 2,
42+
'no-multi-str': 2,
43+
'no-trailing-spaces': 2,
44+
'no-unreachable': 2,
45+
'no-var': 2,
46+
'no-whitespace-before-property': 2,
47+
'object-curly-spacing': [2, 'always'],
48+
'one-var': [2, 'never'],
49+
'padded-blocks': [2, 'never'],
50+
'padding-line-between-statements': [
51+
2,
52+
{ blankLine: 'always', prev: '*', next: 'return' },
53+
{ blankLine: 'always', prev: ['const', 'let', 'var'], next: 'return' },
54+
{ blankLine: 'any', prev: ['const', 'let', 'var'], next: ['const', 'let', 'var'] },
55+
{ blankLine: 'always', prev: '*', next: 'multiline-block-like' },
56+
{ blankLine: 'always', prev: 'multiline-block-like', next: '*' },
57+
{ blankLine: 'never', prev: '*', next: 'case' },
58+
],
59+
'prefer-const': 2,
60+
'prefer-template': 2,
61+
'react/prop-types': 0,
62+
'space-before-blocks': [2, 'always'],
63+
'newline-after-var': [2, 'always'],
64+
'space-before-function-paren': [
65+
2,
66+
{
67+
anonymous: 'never',
68+
named: 'never',
69+
asyncArrow: 'always',
70+
},
71+
],
72+
'space-infix-ops': 2,
73+
'space-in-parens': [2, 'never'],
74+
'template-curly-spacing': [2, 'never'],
75+
'spaced-comment': [
76+
2,
77+
'always',
78+
{
79+
line: {
80+
markers: ['/'],
81+
exceptions: ['-'],
82+
},
83+
block: {
84+
markers: ['/', '*'],
85+
},
86+
},
87+
],
88+
'no-param-reassign': [2, { props: false }],
89+
'dot-notation': [2, { allowPattern: '^[a-z]+(_[a-z]+)+$' }],
90+
quotes: [2, 'single', { avoidEscape: true }],
91+
'unused-imports/no-unused-imports': 2,
92+
},
93+
overrides: [
94+
{
95+
files: ['./**/*.test.ts'],
96+
rules: {
97+
'dot-notation': 'off',
98+
},
99+
},
100+
],
101+
};

.npmignore

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
node_modules
2-
.rpt2_cache
3-
__tests__
41
.editorconfig
2+
.eslintignore
3+
.eslintrc.js
54
.npmrc
65
.nvmrc
6+
.rpt2_cache
77
.yarnrc
8+
__tests__
9+
node_modules
810
rollup.config.js
911
tsconfig.json
10-
tslint.json
1112
yarn.lock

README.md

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,6 @@ export default class SomeModel extends BaseModel {
191191

192192
There are a couple of properties on the `BaseModel`. If you call the `.toJSON();` method on the model it will remove all `sjs-base-model` specific properties.
193193

194-
#### sjsId
195-
196-
Each `sjs-base-model` that is created has a unique model id. You can access it by the `sjsId` property.
197-
198-
```javascript
199-
const carModel = new CarModel();
200-
201-
carModel.sjsId; // unique model id
202-
```
203-
204194
#### sjsOptions
205195

206196
Each `sjs-base-model` has an object on it that keeps track of options you can set. You can set these options by passing an object to the `super` method of the class constructor. Currently there is only the option `expand` which accepts a `boolean`. See the [BaseModel Expand Scaffolding](##masemodel-expand-scaffolding) section to learn more.
@@ -225,7 +215,7 @@ carModel.update({ year: 2015, feature: { abs: true } });
225215

226216
#### toJSON()
227217

228-
Converts the BaseModel data into a JSON object and deletes the sjsId property.
218+
Converts the BaseModel data into a JSON object.
229219

230220
```javascript
231221
const json = carModel.toJSON();
@@ -323,6 +313,8 @@ export default class CarModel extends BaseModel {
323313

324314
## Release History
325315

316+
- 2022-04-20 v2.0.0 Remove `sjsId`, Move `sjsOptions` out of BaseModel, Add return type to `.toJSON()`, Change return type of `.clone()`, Change types exported paths.
317+
-
326318
- 2020-07-29 v1.9.1 Fix deletePropertyFromObject bug; If null was inside an array would cause the code to break.
327319

328320
- 2019-06-23 v1.9.0 IConvertOption now happens before data is assigned to properties. Now if you use ConversionTypeEnum.JSON and have a default model it will create that new model instead of having a plain object.

__tests__/BaseModel.test.ts

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,20 @@ import { NameModel } from './data/models/NameModel';
99
import { AdminModel } from './data/models/AdminModel';
1010

1111
describe('BaseModel', () => {
12-
let json: any = null;
12+
let json = data;
1313

1414
beforeEach(() => {
15-
json = Util.clone(data as any);
16-
});
17-
18-
afterEach(() => {
19-
json = null;
15+
json = Util.clone(data);
2016
});
2117

2218
test('update returns itself', () => {
2319
const baseModel = new BaseModel();
20+
2421
expect(baseModel.update()).toEqual(baseModel);
2522
});
2623

2724
test('should populate InfoModel', () => {
28-
const model = new InfoModel(json.info);
25+
const model = new InfoModel(json.info as any);
2926

3027
expect(model.toJSON()).toEqual({
3128
...json.info,
@@ -52,16 +49,14 @@ describe('BaseModel', () => {
5249

5350
expect(model.info).toEqual(null);
5451
expect(model.results).toEqual([]);
55-
expect(model.sjsOptions).toEqual({ expand: false });
5652
});
5753

5854
test('should clone and not mutate data', () => {
59-
const model = new UserResponseModel(json);
60-
const clone = model.clone<UserResponseModel>();
55+
const model = new UserResponseModel(json as any);
56+
const clone = model.clone();
6157

6258
clone.info.version = '888';
6359

64-
expect(model.info.sjsId).not.toEqual(clone.info.sjsId);
6560
expect(model.info).not.toEqual(clone.info);
6661
expect(model.toJSON()).not.toEqual(clone.toJSON());
6762
});
@@ -87,23 +82,31 @@ describe('BaseModel', () => {
8782
});
8883

8984
test('should have default of UserResponseModel with null passed in', () => {
90-
console.error('Ignore the "Something is wrong!" errors. They are expected.');
85+
const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {});
9186

9287
const model = new UserResponseModel(null as any);
9388

9489
expect(model.info).toEqual(null);
9590
expect(model.results).toEqual([]);
96-
expect(model.sjsOptions).toEqual({ expand: false });
91+
expect(consoleError).toBeCalledWith(
92+
'Something is wrong! UserResponseModel only allows Objects but "null" was passed in.'
93+
);
94+
95+
consoleError.mockReset();
9796
});
9897

9998
test('should have populate UserResponseModel', () => {
100-
const model = new UserResponseModel(json);
99+
const model = new UserResponseModel(json as any);
101100

102101
const expectedData = {
103102
...json,
104-
results: json.results.map((resultItem: any) =>
105-
Util.deletePropertyFromObject(resultItem, ['location', 'login', 'dob', 'registered', 'phone', 'cell', 'id'])
106-
),
103+
results: json.results.map((resultItem) => ({
104+
gender: resultItem.gender,
105+
name: resultItem.name,
106+
picture: resultItem.picture,
107+
email: resultItem.email,
108+
nat: resultItem.nat,
109+
})),
107110
info: {
108111
...json.info,
109112
stringified: JSON.parse(json.info.stringified),
@@ -114,12 +117,16 @@ describe('BaseModel', () => {
114117
});
115118

116119
test('should call update with empty object and have no changes', () => {
117-
const model = new UserResponseModel(json);
120+
const model = new UserResponseModel(json as any);
118121
const expectedData = {
119122
...json,
120-
results: json.results.map((resultItem: any) =>
121-
Util.deletePropertyFromObject(resultItem, ['location', 'login', 'dob', 'registered', 'phone', 'cell', 'id'])
122-
),
123+
results: json.results.map((resultItem) => ({
124+
gender: resultItem.gender,
125+
name: resultItem.name,
126+
picture: resultItem.picture,
127+
email: resultItem.email,
128+
nat: resultItem.nat,
129+
})),
123130
info: {
124131
...json.info,
125132
stringified: JSON.parse(json.info.stringified),
@@ -132,15 +139,19 @@ describe('BaseModel', () => {
132139
});
133140

134141
test('should have populate UserResponseModel from same UserResponseModel', () => {
135-
let model = new UserResponseModel(json);
142+
let model = new UserResponseModel(json as any);
136143

137144
model = new UserResponseModel(model);
138145

139146
const expectedData = {
140147
...json,
141-
results: json.results.map((resultItem: any) =>
142-
Util.deletePropertyFromObject(resultItem, ['location', 'login', 'dob', 'registered', 'phone', 'cell', 'id'])
143-
),
148+
results: json.results.map((resultItem) => ({
149+
gender: resultItem.gender,
150+
name: resultItem.name,
151+
picture: resultItem.picture,
152+
email: resultItem.email,
153+
nat: resultItem.nat,
154+
})),
144155
info: {
145156
...json.info,
146157
stringified: JSON.parse(json.info.stringified),
@@ -151,7 +162,7 @@ describe('BaseModel', () => {
151162
});
152163

153164
test('should update email results to one item in the array', () => {
154-
const model = new UserResponseModel(json);
165+
const model = new UserResponseModel(json as any);
155166

156167
expect(model.results.length).toBe(3);
157168

@@ -192,27 +203,22 @@ describe('BaseModel', () => {
192203

193204
test('should populate UserModel', () => {
194205
const theData = json.results[0];
195-
const model = new UserModel(theData);
196-
197-
// const hey = model.toJSON()
198-
// hey.
206+
const model = new UserModel(theData as any);
199207

200-
const expectedData = Util.deletePropertyFromObject(theData, [
201-
'location',
202-
'login',
203-
'dob',
204-
'registered',
205-
'phone',
206-
'cell',
207-
'id',
208-
]);
208+
const expectedData = {
209+
gender: theData.gender,
210+
name: theData.name,
211+
picture: theData.picture,
212+
email: theData.email,
213+
nat: theData.nat,
214+
};
209215

210216
expect(model.toJSON()).toEqual(expectedData);
211217
});
212218

213219
test('should update UserModel', () => {
214220
const theData = json.results[0];
215-
const model = new UserModel(theData);
221+
const model = new UserModel(theData as any);
216222

217223
expect(model.email).toBe(theData.email);
218224
expect(model.name.last).toBe(theData.name.last);
@@ -257,18 +263,19 @@ describe('BaseModel', () => {
257263
expect(model.toJSON()).toEqual(expected);
258264
});
259265

260-
test('should test isObject', () => {
266+
describe('should test isObject', () => {
261267
const model = new BaseModel();
262268

263269
const objects: object[] = [{}, new UserResponseModel()];
264270
const nonObjects: any[] = [[], true, false, undefined, null, 8, 20.18, '🚀'];
265271

266-
// tslint:disable-next-line:no-string-literal
267-
objects.forEach((object: object) => expect(model['_isObject'](object)).toBeTruthy());
268-
// tslint:disable-next-line:no-string-literal
269-
nonObjects.forEach((nonObject: any) => expect(model['_isObject'](nonObject)).toBeFalsy());
272+
test.each(objects)('toBeTruthy', (object) => {
273+
expect(model['_isObject'](object)).toBeTruthy();
274+
});
270275

271-
console.error('Ignore the "Something is wrong!" errors. They are expected.');
276+
test.each(nonObjects)('toBeTruthy', (nonObject) => {
277+
expect(model['_isObject'](nonObject)).toBeFalsy();
278+
});
272279
});
273280

274281
test('should test IConversionOption', () => {
@@ -291,7 +298,6 @@ describe('BaseModel', () => {
291298

292299
test('should test non existent keys on IConversionOption', () => {
293300
expect(() => {
294-
// tslint:disable-next-line:no-unused-expression
295301
new NonExistentKeyConversionModel({});
296302
}).toThrow(SyntaxError);
297303
});

0 commit comments

Comments
 (0)