• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16const typeErrorCode = 401;
17class BusinessError extends Error {
18  code: number;
19  constructor(msg: string) {
20    super(msg);
21    this.name = 'BusinessError';
22    this.code = typeErrorCode;
23  }
24}
25
26type TransformsFunc = (this: Object, key: string, value: Object) => Object | undefined | null;
27type ReplacerType = (number | string)[] | null | TransformsFunc;
28
29function parse(text: string, reviver?: TransformsFunc): Object | null {
30  if (typeof text !== 'string') {
31    let error = new BusinessError(`Parameter error. The type of ${text} must be string`);
32    throw error;
33  }
34  if (reviver) {
35    if (typeof reviver !== 'function') {
36      let error = new BusinessError(`Parameter error. The type of ${reviver} must be a method`);
37      throw error;
38    }
39  }
40
41  try {
42    return JSON.parse(text, reviver);
43  } catch (e) {
44    let error = new BusinessError(`e.message: `+ (e as Error).message + `, e.name: ` + (e as Error).name);
45    throw error;
46  }
47}
48
49function stringfyFun(value: Object, replacer?: (this: Object, key: string, value: Object) => Object,
50    space?: string | number): string {
51  if (arguments.length === 1) {
52    return JSON.stringify(value);
53  } else {
54    return JSON.stringify(value, replacer, space);
55  }
56}
57
58function stringfyArr(value: Object, replacer?: (number | string)[] | null, space?: string | number): string {
59  if (arguments.length === 1) {
60    return JSON.stringify(value);
61  } else {
62    return JSON.stringify(value, replacer, space);
63  }
64}
65
66function isParameterType(self: unknown): boolean {
67  return (Array.isArray(self) && self.every((item) => typeof item === 'number' || typeof item === 'string') ||
68  self === null || typeof self === 'function');
69}
70
71function isSpaceType(self: unknown): boolean {
72  return (typeof self === 'string' || typeof self === 'number');
73}
74
75function isCirculateReference(value: Object, seenObjects: Set<Object> = new Set()): boolean {
76  if (value === null || !(value instanceof Object)) {
77    return false;
78  }
79  if (seenObjects.has(value)) {
80    return true;
81  }
82  seenObjects.add(value);
83
84  for (let key in value) {
85    if (isCirculateReference(value[key], seenObjects)) {
86      return true;
87    }
88  }
89  return false;
90}
91
92function stringify(value: Object, replacer?: ReplacerType, space?: string | number): string {
93  if (typeof (value as Object) === 'undefined' || !(value instanceof Object)) {
94    let error = new BusinessError(`Parameter error. The type of ${value} must be Object`);
95    throw error;
96  }
97  if (value === null) {
98    let error = new BusinessError(`Parameter error. The type of ${value} is null`);
99    throw error;
100  }
101  if (typeof value === 'bigint') {
102    let error = new BusinessError(`Parameter error. The type of ${value} is Bigint`);
103    throw error;
104  }
105  if (isCirculateReference(value)) {
106    let error = new BusinessError(`Parameter error. The object circular Reference`);
107    throw error;
108  }
109  if (replacer) {
110    if (!isParameterType(replacer)) {
111      let error = new BusinessError(`Parameter error. The type of ${replacer} must be a method or array`);
112      throw error;
113    }
114    if (space) {
115      if (!isSpaceType(space)) {
116        let error = new BusinessError(`Parameter error. The type of ${space} must be a string or number`);
117        throw error;
118      }
119    } else if (space === null) {
120      let error = new BusinessError(`Parameter error. The type of ${space} must be a string or number`);
121      throw error;
122    }
123  }
124
125  try {
126    if (arguments.length === 1) {
127      return stringfyArr(value);
128    } else {
129      if (typeof replacer === 'function') {
130        return stringfyFun(value, replacer, space);
131      } else {
132        return stringfyArr(value, replacer, space);
133      }
134    }
135  } catch (e) {
136    let error = new BusinessError((e as Error).message + `, e.name: ` + (e as Error).name);
137    throw error;
138  }
139}
140
141function has(value: object, key: string): boolean {
142  if (typeof value !== 'object' || typeof value === 'undefined' || value === null) {
143    let error = new BusinessError(`Parameter error. The type of ${value} must be object`);
144    throw error;
145  }
146  if (value instanceof Array) {
147    let error = new BusinessError(`Parameter error. The type of ${value} must be json object`);
148    throw error;
149  }
150  if (!(typeof key === 'string' && key.length)) {
151    let error = new BusinessError(`Parameter error. The type of ${key} must be string and not empty`);
152    throw error;
153  }
154  return Object.prototype.hasOwnProperty.call(value, key);
155}
156
157function remove(value: object, key: string): void {
158  if (typeof value !== 'object' || typeof value === 'undefined' || value === null) {
159    let error = new BusinessError(`Parameter error. The type of ${value} must be object`);
160    throw error;
161  }
162  if (value instanceof Array) {
163    let error = new BusinessError(`Parameter error. The type of ${value} must be json object`);
164    throw error;
165  }
166  if (!(typeof key === 'string' && key.length)) {
167    let error = new BusinessError(`Parameter error. The type of ${key} must be string and not empty`);
168    throw error;
169  }
170  if (Object.prototype.hasOwnProperty.call(value, key)) {
171    delete value[key];
172  }
173}
174
175export default {
176  parse: parse,
177  stringify: stringify,
178  has: has,
179  remove: remove,
180};
181