Skip to content

Commit c603a42

Browse files
authored
feat: remove lodash (#8)
* feat: remove lodash * feat: run ci on pr * test: remove clone * ci: separate steps
1 parent 693ad47 commit c603a42

12 files changed

+187
-43
lines changed

.github/workflows/ngx-form-ci.yml

+123-9
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,136 @@
1-
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3-
41
name: build
52

63
on:
74
push:
85
branches: [ master ]
6+
pull_request:
7+
branches: [ '**' ]
98

109
jobs:
11-
build_and_test:
12-
10+
build:
11+
name: Build NgxForm
1312
runs-on: ubuntu-latest
14-
1513
strategy:
1614
matrix:
1715
node-version: [ 18.19.1 ]
1816

1917
steps:
20-
- uses: actions/checkout@v2
18+
- name: Checkout Repository
19+
uses: actions/checkout@v2
20+
2121
- name: Use Node.js ${{ matrix.node-version }}
2222
uses: actions/setup-node@v1
2323
with:
2424
node-version: ${{ matrix.node-version }}
25+
2526
- name: Installation
2627
run: npm ci
28+
2729
- name: Build NgxForm
2830
run: npm run build:ngx-form
2931
env:
3032
CI: true
31-
- name: Linter
33+
34+
- name: Archive build artifact
35+
uses: actions/upload-artifact@master
36+
with:
37+
name: ngx-form-build
38+
path: ./dist/ngx-form
39+
40+
lint:
41+
name: Lint
42+
runs-on: ubuntu-latest
43+
strategy:
44+
matrix:
45+
node-version: [ 18.19.1 ]
46+
47+
steps:
48+
- name: Checkout Repository
49+
uses: actions/checkout@v2
50+
51+
- name: Use Node.js ${{ matrix.node-version }}
52+
uses: actions/setup-node@v1
53+
with:
54+
node-version: ${{ matrix.node-version }}
55+
56+
- name: Installation
57+
run: npm ci
58+
59+
- name: Run Linter
3260
run: npm run lint
33-
- name: Test
61+
62+
test:
63+
name: Test
64+
runs-on: ubuntu-latest
65+
strategy:
66+
matrix:
67+
node-version: [ 18.19.1 ]
68+
69+
steps:
70+
- name: Checkout Repository
71+
uses: actions/checkout@v2
72+
73+
- name: Use Node.js ${{ matrix.node-version }}
74+
uses: actions/setup-node@v1
75+
with:
76+
node-version: ${{ matrix.node-version }}
77+
78+
- name: Installation
79+
run: npm ci
80+
81+
- name: Run Tests
3482
run: npm run test:ci
83+
84+
- name: Archive Coverage Artifact
85+
uses: actions/upload-artifact@master
86+
with:
87+
name: ngx-form-coverage
88+
path: ./coverage
89+
90+
coverall:
91+
name: Coverall
92+
needs: test
93+
runs-on: ubuntu-latest
94+
if: github.ref == 'refs/heads/master'
95+
strategy:
96+
matrix:
97+
node-version: [ 18.19.1 ]
98+
99+
steps:
100+
- name: Checkout Repository
101+
uses: actions/checkout@v2
102+
103+
- name: Download Coverage Artifact
104+
uses: actions/download-artifact@master
105+
with:
106+
name: ngx-form-coverage
107+
path: ./coverage
108+
35109
- name: Send coverage to Coverall
36110
uses: coverallsapp/github-action@v1.0.1
37111
with:
38112
github-token: ${{ secrets.GITHUB_TOKEN }}
39113
path-to-lcov: ./coverage/ngx-form/lcov.info
40114

115+
deploy_paddls:
116+
name: Deploy NgxForm @paddls
117+
needs: [ build, lint, test ]
118+
if: github.ref == 'refs/heads/master'
119+
runs-on: ubuntu-latest
120+
strategy:
121+
matrix:
122+
node-version: [ 18.19.1 ]
123+
124+
steps:
125+
- name: Checkout Repository
126+
uses: actions/checkout@v2
127+
128+
- name: Download Build Artifact
129+
uses: actions/download-artifact@master
130+
with:
131+
name: ngx-form-build
132+
path: ./dist/ngx-form
133+
41134
- name: "Publish @paddls/ngx-form"
42135
uses: pascalgn/npm-publish-action@1.3.9
43136
with:
@@ -49,12 +142,33 @@ jobs:
49142
env:
50143
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51144
NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN_PADDLS }}
145+
146+
deploy_witty:
147+
name: Deploy NgxForm @witty-services
148+
needs: [ build, lint, test ]
149+
if: github.ref == 'refs/heads/master'
150+
runs-on: ubuntu-latest
151+
strategy:
152+
matrix:
153+
node-version: [ 18.19.1 ]
154+
155+
steps:
156+
- name: Checkout Repository
157+
uses: actions/checkout@v2
158+
159+
- name: Download Build Artifact
160+
uses: actions/download-artifact@master
161+
with:
162+
name: ngx-form-build
163+
path: ./dist/ngx-form
164+
52165
- name: "PrePublish @witty-services/ngx-form"
53166
uses: jossef/action-set-json-field@v1
54167
with:
55168
file: "./dist/ngx-form/package.json"
56169
field: name
57170
value: "@witty-services/ngx-form"
171+
58172
- name: "Publish @witty-services/ngx-form"
59173
uses: pascalgn/npm-publish-action@1.3.9
60174
with:

README.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ properties are available. Just specify the properties directly in the context if
211211
```typescript
212212
import {FormControl, FormGroup, UpdateOn, Validator, AsyncValidator} from '@paddls/ngx-form';
213213
import {AddressForm} from './address.form';
214-
import {clone} from 'lodash';
215214
import {Validators} from '@angular/forms';
216215

217216
@UpdateOn('change')
@@ -229,7 +228,7 @@ export class UserForm {
229228
@Validator([Validators.required, Validators.min(0)])
230229
public age: number;
231230

232-
@FormGroup({type: () => AddressForm, defaultValue: clone(defaultAddress)})
231+
@FormGroup({type: () => AddressForm, defaultValue: structuredClone(defaultAddress)})
233232
@UpdateOn('submit')
234233
public personalAddress: AddressForm;
235234
}

package-lock.json

-13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
"@angular/platform-browser": "^18.0.2",
2323
"@angular/platform-browser-dynamic": "^18.0.2",
2424
"@angular/router": "^18.0.2",
25-
"lodash.set": "^4.3.2",
2625
"rxjs": "~7.5.3",
2726
"tslib": "^2.4.0",
2827
"zone.js": "~0.14.2"
@@ -49,7 +48,6 @@
4948
"karma-coverage": "~2.2.1",
5049
"karma-jasmine": "~5.1.0",
5150
"karma-jasmine-html-reporter": "^2.1.0",
52-
"lodash.clone": "^4.5.0",
5351
"ng-packagr": "^18.0.0",
5452
"protractor": "~7.0.0",
5553
"reflect-metadata": "^0.2.2",

projects/ngx-form/ng-package.json

+1-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,5 @@
33
"dest": "../../dist/ngx-form",
44
"lib": {
55
"entryFile": "src/public-api.ts"
6-
},
7-
"allowedNonPeerDependencies": [
8-
"lodash.set"
9-
]
6+
}
107
}

projects/ngx-form/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"reflect-metadata": "^0.2.2"
88
},
99
"dependencies": {
10-
"lodash.set": "^4.3.2",
1110
"tslib": "^2.0.0"
1211
},
1312
"repository": {

projects/ngx-form/src/lib/common/common.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import {FORM_GROUP_SUFFIX_METADATA_KEY, FormGroupContext} from '../decorator/for
44
import {FORM_ARRAY_SUFFIX_METADATA_KEY, FormArrayContext} from '../decorator/form-array.decorator';
55
import {NgxFormArray} from '../model/ngx-form-array.model';
66
import {FORM_GROUP_INSTANCE_METADATA_KEY, NgxFormGroup} from '../model/ngx-form-group.model';
7-
import set from 'lodash.set';
87
import {Observable} from 'rxjs';
98
import {NgxFormControl} from '../model/ngx-form-control.model';
9+
import {set} from './functions/set';
1010

1111
export interface Handler {
1212

@@ -41,7 +41,7 @@ export function transformValueToSmartValue<V>(formGroup: NgxFormGroup<V>, parent
4141
}
4242
});
4343

44-
const groupContexts: { [key: string]: FormContextCommon<V> } = findPropertyFormContexts(formGroupContext.type().prototype, FORM_GROUP_SUFFIX_METADATA_KEY);
44+
const groupContexts: {[key: string]: FormContextCommon<V>} = findPropertyFormContexts(formGroupContext.type().prototype, FORM_GROUP_SUFFIX_METADATA_KEY);
4545
Object.keys(groupContexts).forEach((key: string) => {
4646
const groupContext: FormGroupContext<V> = groupContexts[key] as FormGroupContext<V>;
4747
set(value, key, (formGroup.get(groupContext.name) as unknown as NgxFormArray<V>)?.getValue(parent + key))
@@ -53,14 +53,14 @@ export function transformValueToSmartValue<V>(formGroup: NgxFormGroup<V>, parent
5353
export function transformSmartValueToValue<V>(value: V): any {
5454
const obj: any = {};
5555

56-
const controlContexts: { [key: string]: FormContextCommon<V> } = {};
56+
const controlContexts: {[key: string]: FormContextCommon<V>} = {};
5757
Object.assign(controlContexts, {
5858
...findPropertyFormContexts(value.constructor.prototype, FORM_CONTROL_SUFFIX_METADATA_KEY),
5959
...findPropertyFormContexts(value.constructor.prototype, FORM_GROUP_SUFFIX_METADATA_KEY)
6060
});
6161
Object.keys(controlContexts).forEach((key: string) => {
6262
const controlContext: FormContextCommon<V> = controlContexts[key];
63-
if(value[key] !== undefined) {
63+
if (value[key] !== undefined) {
6464
set(obj, controlContext.name, value[key]);
6565
}
6666
});
@@ -103,6 +103,6 @@ type IterableElement<TargetIterable> =
103103
never;
104104

105105
export type DataToFormType<V, K extends keyof V = keyof V> = {
106-
[key in K]: V[key] extends Primitive ? NgxFormControl<V[key]> : V[key] extends Arrayable<IterableElement<V[key]>> ? NgxFormArray<IterableElement<V[key]>> : NgxFormGroup<V[key]>
106+
[key in K]: V[key] extends Primitive ? NgxFormControl<V[key]> : V[key] extends Arrayable<IterableElement<V[key]>> ? NgxFormArray<IterableElement<V[key]>> : NgxFormGroup<V[key]>
107107
};
108108
export type DataFormType<V> = Partial<V> & {[key: string]: any};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {set} from './set';
2+
3+
describe('set', () => {
4+
it('should set a value at a given path with dot notation', () => {
5+
const obj = {a: {b: undefined}};
6+
set(obj, 'a.b.c', 42);
7+
expect(obj).toEqual({a: {b: {c: 42}}});
8+
});
9+
10+
it('should set a value at a given path with array notation', () => {
11+
const obj = {a: {b: undefined}};
12+
set(obj, ['a', 'b', 'c'], 42);
13+
expect(obj).toEqual({a: {b: {c: 42}}});
14+
});
15+
16+
it('should create nested objects if they do not exist', () => {
17+
const obj = {};
18+
set(obj, 'x.y.z', 'test');
19+
expect(obj).toEqual({x: {y: {z: 'test'}}});
20+
});
21+
22+
it('should overwrite existing values at the given path', () => {
23+
const obj = {a: {b: {c: 10}}};
24+
set(obj, 'a.b.c', 42);
25+
expect(obj).toEqual({a: {b: {c: 42}}});
26+
});
27+
28+
it('should handle empty path array correctly', () => {
29+
const obj = {a: 1};
30+
set(obj, [], 42);
31+
expect(obj).toEqual({a: 1});
32+
});
33+
34+
it('should handle empty path string correctly', () => {
35+
const obj = {a: 1};
36+
set(obj, '', 42);
37+
expect(obj).toEqual({a: 1});
38+
});
39+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export const set = (obj: {[key: string]: any}, path: string | string[], value: any): void => {
2+
const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
3+
4+
if (pathArray === null) {
5+
return;
6+
}
7+
8+
pathArray.reduce((acc: {[key: string]: any}, key, i) => {
9+
if (acc[key] === undefined) acc[key] = {};
10+
if (i === pathArray.length - 1) acc[key] = value;
11+
12+
return acc[key];
13+
}, obj);
14+
};

projects/ngx-form/src/lib/core/ngx-form.builder.spec.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {FormGroup, FormGroupContext} from '../decorator/form-group.decorator';
66
import {NgxFormGroup} from '../model/ngx-form-group.model';
77
import {Validator} from '../decorator/validator.decorator';
88
import {Validators} from '@angular/forms';
9-
import clone from 'lodash.clone';
109
import {TestBed} from '@angular/core/testing';
1110
import {provideNgxForm} from '../ngx-form.module';
1211
import {AsyncValidator} from '../decorator/async-validator.decorator';
@@ -81,7 +80,7 @@ class UserForm {
8180
@FormArray(() => CompanyForm)
8281
public companies: CompanyForm[];
8382

84-
@FormGroup({type: () => AddressForm, defaultValue: clone(defaultAddress)})
83+
@FormGroup({type: () => AddressForm, defaultValue: structuredClone(defaultAddress)})
8584
@UpdateOn('submit')
8685
public personalAddress: AddressForm;
8786

0 commit comments

Comments
 (0)