@@ -64,9 +64,15 @@ export function encryptArray(options: EncryptArrayOptions): void {
64
64
const { secret, obj, keys } = options ;
65
65
66
66
for ( const attr of keys ) {
67
- const val = obj [ attr ] ;
68
- if ( typeof val === 'string' ) {
69
- obj [ attr ] = encrypt ( secret , val ) ;
67
+ const val = getObjectAttribute ( obj , attr ) ;
68
+ if ( Array . isArray ( val ) ) {
69
+ const encrypted : string [ ] = [ ] ;
70
+ for ( let i = 0 ; i < val . length ; i ++ ) {
71
+ encrypted [ i ] = typeof val [ i ] === 'string' ? encrypt ( secret , val [ i ] ) : val [ i ] ;
72
+ }
73
+ setObjectAttribute ( obj , attr , encrypted ) ;
74
+ } else if ( typeof val === 'string' ) {
75
+ setObjectAttribute ( obj , attr , encrypt ( secret , val ) ) ;
70
76
}
71
77
}
72
78
}
@@ -80,9 +86,15 @@ export function decryptArray(options: EncryptArrayOptions): void {
80
86
const { secret, obj, keys } = options ;
81
87
82
88
for ( const attr of keys ) {
83
- const val = obj [ attr ] ;
84
- if ( typeof val === 'string' ) {
85
- obj [ attr ] = decrypt ( secret , val ) ;
89
+ const val = getObjectAttribute ( obj , attr ) ;
90
+ if ( Array . isArray ( val ) ) {
91
+ const decrypted : string [ ] = [ ] ;
92
+ for ( let i = 0 ; i < val . length ; i ++ ) {
93
+ decrypted [ i ] = typeof val [ i ] === 'string' ? decrypt ( secret , val [ i ] ) : val [ i ] ;
94
+ }
95
+ setObjectAttribute ( obj , attr , decrypted ) ;
96
+ } else if ( typeof val === 'string' ) {
97
+ setObjectAttribute ( obj , attr , decrypt ( secret , val ) ) ;
86
98
}
87
99
}
88
100
}
@@ -149,3 +161,129 @@ export async function requestModuleNameByUrl(url: string): Promise<string> {
149
161
150
162
return res . stdout . trim ( ) ;
151
163
}
164
+
165
+ /**
166
+ * Get attribute of an object with complex names
167
+ *
168
+ * @param obj - object to get the attribute from
169
+ * @param attrParts - attribute parts
170
+ * @param index - index of attribute part
171
+ */
172
+ function _getObjectAttribute ( obj : Record < string , any > , attrParts : string [ ] , index : number ) : any {
173
+ if ( index === attrParts . length - 1 ) {
174
+ return obj [ attrParts [ index ] ] ;
175
+ }
176
+ if ( ! obj [ attrParts [ index ] ] || typeof obj [ attrParts [ index ] ] !== 'object' ) {
177
+ return ;
178
+ }
179
+ if ( Array . isArray ( obj [ attrParts [ index ] ] ) ) {
180
+ const result : any = [ ] ;
181
+ for ( let i = 0 ; i < obj [ attrParts [ index ] ] . length ; i ++ ) {
182
+ result . push ( _getObjectAttribute ( obj [ attrParts [ index ] ] [ i ] , attrParts , index + 1 ) ) ;
183
+ }
184
+ return result ;
185
+ }
186
+
187
+ return _getObjectAttribute ( obj [ attrParts [ index ] ] , attrParts , index + 1 ) ;
188
+ }
189
+
190
+ /**
191
+ * Get attribute of an object with complex or simple names
192
+ *
193
+ * @param obj - object to get the attribute from
194
+ * @param attr - attribute name, can be complex like `attr1.attr2.attr3`
195
+ * @return could be a value or an array
196
+ */
197
+ export function getObjectAttribute ( obj : Record < string , any > , attr : string ) : any {
198
+ // Optimization for 98% of the cases
199
+ if ( ! attr . includes ( '.' ) ) {
200
+ return obj [ attr ] ;
201
+ }
202
+ return _getObjectAttribute ( obj , attr . split ( '.' ) , 0 ) ;
203
+ }
204
+
205
+ /**
206
+ * Set attribute in an object with complex names
207
+ *
208
+ * @param obj - object to get the attribute from
209
+ * @param value - value to set (Could be an array)
210
+ * @param attrParts - attribute parts
211
+ * @param index - index of attribute part
212
+ */
213
+ function _setObjectAttribute ( obj : Record < string , any > , value : any , attrParts : string [ ] , index : number ) : any {
214
+ if ( index === attrParts . length - 1 ) {
215
+ obj [ attrParts [ index ] ] = value ;
216
+ return ;
217
+ }
218
+ if ( ! obj [ attrParts [ index ] ] || typeof obj [ attrParts [ index ] ] !== 'object' ) {
219
+ return ;
220
+ }
221
+ if ( Array . isArray ( obj [ attrParts [ index ] ] ) ) {
222
+ if ( ! Array . isArray ( value ) ) {
223
+ throw new Error ( 'Value is not an array' ) ;
224
+ }
225
+ for ( let i = 0 ; i < obj [ attrParts [ index ] ] . length ; i ++ ) {
226
+ _setObjectAttribute ( obj [ attrParts [ index ] ] [ i ] , value [ i ] , attrParts , index + 1 ) ;
227
+ }
228
+ return ;
229
+ }
230
+
231
+ _setObjectAttribute ( obj [ attrParts [ index ] ] , value , attrParts , index + 1 ) ;
232
+ }
233
+
234
+ /**
235
+ * Set attribute in an object with complex or simple names
236
+ *
237
+ * @param obj - object to get the attribute from
238
+ * @param attr - attribute name, can be complex like `attr1.attr2.attr3`
239
+ * @param value - value to set (could be a value or an array)
240
+ */
241
+ export function setObjectAttribute ( obj : Record < string , any > , attr : string , value : any ) : void {
242
+ // Optimization for 98% of the cases
243
+ if ( ! attr . includes ( '.' ) ) {
244
+ obj [ attr ] = value ;
245
+ return ;
246
+ }
247
+ _setObjectAttribute ( obj , value , attr . split ( '.' ) , 0 ) ;
248
+ }
249
+
250
+ /**
251
+ * Delete attribute in an object with complex names
252
+ *
253
+ * @param obj - object to get the attribute from
254
+ * @param attrParts - attribute parts
255
+ * @param index - index of attribute part
256
+ */
257
+ function _deleteObjectAttribute ( obj : Record < string , any > , attrParts : string [ ] , index : number ) : any {
258
+ if ( index === attrParts . length - 1 ) {
259
+ delete obj [ attrParts [ index ] ] ;
260
+ return ;
261
+ }
262
+ if ( ! obj [ attrParts [ index ] ] || typeof obj [ attrParts [ index ] ] !== 'object' ) {
263
+ return ;
264
+ }
265
+ if ( Array . isArray ( obj [ attrParts [ index ] ] ) ) {
266
+ for ( let i = 0 ; i < obj [ attrParts [ index ] ] . length ; i ++ ) {
267
+ _deleteObjectAttribute ( obj [ attrParts [ index ] ] [ i ] , attrParts , index + 1 ) ;
268
+ }
269
+ return ;
270
+ }
271
+
272
+ _deleteObjectAttribute ( obj [ attrParts [ index ] ] , attrParts , index + 1 ) ;
273
+ }
274
+
275
+ /**
276
+ * Delete attribute in an object with complex names
277
+ *
278
+ * @param obj - object to get the attribute from
279
+ * @param attr - attribute name, can be complex like `attr1.attr2.attr3`
280
+ */
281
+ export function deleteObjectAttribute ( obj : Record < string , any > , attr : string ) : void {
282
+ // Optimization for 98% of the cases
283
+ if ( ! attr . includes ( '.' ) ) {
284
+ delete obj [ attr ] ;
285
+ return ;
286
+ }
287
+
288
+ _deleteObjectAttribute ( obj , attr . split ( '.' ) , 0 ) ;
289
+ }
0 commit comments