@tdengine/websocket 3.1.4 → 3.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/lib/example/basicSchemaless.js +1 -2
  2. package/lib/example/basicSql.js +1 -1
  3. package/lib/src/client/wsClient.d.ts +2 -0
  4. package/lib/src/client/wsClient.d.ts.map +1 -1
  5. package/lib/src/client/wsClient.js +20 -8
  6. package/lib/src/client/wsConnector.d.ts +0 -1
  7. package/lib/src/client/wsConnector.d.ts.map +1 -1
  8. package/lib/src/client/wsConnector.js +0 -3
  9. package/lib/src/client/wsConnectorPool.d.ts +2 -1
  10. package/lib/src/client/wsConnectorPool.d.ts.map +1 -1
  11. package/lib/src/client/wsConnectorPool.js +16 -10
  12. package/lib/src/client/wsEventCallback.d.ts.map +1 -1
  13. package/lib/src/client/wsEventCallback.js +1 -2
  14. package/lib/src/common/utils.d.ts +11 -0
  15. package/lib/src/common/utils.d.ts.map +1 -1
  16. package/lib/src/common/utils.js +76 -0
  17. package/lib/src/common/wsError.d.ts +2 -1
  18. package/lib/src/common/wsError.d.ts.map +1 -1
  19. package/lib/src/common/wsError.js +1 -0
  20. package/lib/src/sql/wsRows.js +2 -2
  21. package/lib/src/sql/wsSql.d.ts +0 -1
  22. package/lib/src/sql/wsSql.d.ts.map +1 -1
  23. package/lib/src/sql/wsSql.js +6 -14
  24. package/lib/src/stmt/wsStmt.d.ts +0 -4
  25. package/lib/src/stmt/wsStmt.d.ts.map +1 -1
  26. package/lib/src/stmt/wsStmt.js +3 -8
  27. package/lib/src/tmq/config.d.ts +8 -6
  28. package/lib/src/tmq/config.d.ts.map +1 -1
  29. package/lib/src/tmq/config.js +46 -17
  30. package/lib/src/tmq/wsTmq.d.ts.map +1 -1
  31. package/lib/src/tmq/wsTmq.js +26 -2
  32. package/lib/test/bulkPulling/sql.test.js +32 -0
  33. package/lib/test/bulkPulling/stmt.type.test.js +1 -1
  34. package/lib/test/bulkPulling/tmq.test.js +9 -3
  35. package/lib/test/bulkPulling/utils.test.d.ts +2 -0
  36. package/lib/test/bulkPulling/utils.test.d.ts.map +1 -0
  37. package/lib/test/bulkPulling/utils.test.js +13 -0
  38. package/lib/test/bulkPulling/wsConnectPool.test.js +6 -5
  39. package/package.json +5 -9
  40. package/lib/example/logs/.007e668bb78549e9a304b8466671945ab2a1553e-audit.json +0 -15
  41. package/lib/example/logs/app-2025-01-24.log +0 -5580
@@ -1 +1 @@
1
- {"version":3,"file":"wsTmq.d.ts","sourceRoot":"","sources":["../../../src/tmq/wsTmq.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAkF,cAAc,EAA0D,MAAM,eAAe,CAAC;AAKvL,qBAAa,UAAU;IACnB,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,WAAW,CAAC,CAAQ;IAC5B,OAAO;YAMO,IAAI;WAML,WAAW,CAAC,QAAQ,EAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAE,OAAO,CAAC,UAAU,CAAC;IAUjE,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,EAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB9D,WAAW,CAAC,KAAK,CAAC,EAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAgBvE,YAAY,CAAC,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAYlD,MAAM,CAAC,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAK5C,QAAQ;IAYhB,SAAS,CAAC,UAAU,EAAC,KAAK,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IA0BzF,aAAa,CAAC,UAAU,EAAC,KAAK,CAAC,cAAc,CAAC,GAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAc9E,YAAY,CAAC,SAAS,EAAC,cAAc,EAAE,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,IAAI,CAAC;IAkBnE,SAAS,CAAC,UAAU,EAAC,KAAK,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IA0BzF,IAAI,CAAC,SAAS,EAAC,cAAc,EAAE,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,IAAI,CAAC;IAkB3D,eAAe,CAAC,UAAU,EAAC,KAAK,CAAC,cAAc,CAAC,GAAE,OAAO,CAAC,IAAI,CAAC;IAQ/D,SAAS,CAAC,UAAU,EAAC,KAAK,CAAC,cAAc,CAAC,GAAE,OAAO,CAAC,IAAI,CAAC;IASzD,KAAK,IAAG,OAAO,CAAC,IAAI,CAAC;YAIb,cAAc;YAwBd,QAAQ;YA4BR,iBAAiB;IAczB,UAAU,CAAC,MAAM,CAAC,EAAC,MAAM,EAAE,GAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAoBnD,gBAAgB;CA6BjC"}
1
+ {"version":3,"file":"wsTmq.d.ts","sourceRoot":"","sources":["../../../src/tmq/wsTmq.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAkF,cAAc,EAA0D,MAAM,eAAe,CAAC;AAKvL,qBAAa,UAAU;IACnB,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,WAAW,CAAC,CAAQ;IAC5B,OAAO;YAWO,IAAI;WAuBL,WAAW,CAAC,QAAQ,EAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAE,OAAO,CAAC,UAAU,CAAC;IAUjE,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,EAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB9D,WAAW,CAAC,KAAK,CAAC,EAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAgBvE,YAAY,CAAC,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAYlD,MAAM,CAAC,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAK5C,QAAQ;IAYhB,SAAS,CAAC,UAAU,EAAC,KAAK,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IA0BzF,aAAa,CAAC,UAAU,EAAC,KAAK,CAAC,cAAc,CAAC,GAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAc9E,YAAY,CAAC,SAAS,EAAC,cAAc,EAAE,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,IAAI,CAAC;IAkBnE,SAAS,CAAC,UAAU,EAAC,KAAK,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IA0BzF,IAAI,CAAC,SAAS,EAAC,cAAc,EAAE,KAAK,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,IAAI,CAAC;IAkB3D,eAAe,CAAC,UAAU,EAAC,KAAK,CAAC,cAAc,CAAC,GAAE,OAAO,CAAC,IAAI,CAAC;IAQ/D,SAAS,CAAC,UAAU,EAAC,KAAK,CAAC,cAAc,CAAC,GAAE,OAAO,CAAC,IAAI,CAAC;IASzD,KAAK,IAAG,OAAO,CAAC,IAAI,CAAC;YAIb,cAAc;YAwBd,QAAQ;YA4BR,iBAAiB;IAczB,UAAU,CAAC,MAAM,CAAC,EAAC,MAAM,EAAE,GAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAoBnD,gBAAgB;CA6BjC"}
@@ -16,10 +16,33 @@ class WsConsumer {
16
16
  constructor(wsConfig) {
17
17
  this._wsConfig = new config_1.TmqConfig(wsConfig);
18
18
  log_1.default.debug(this._wsConfig);
19
+ if (wsConfig.size == 0 || !this._wsConfig.url) {
20
+ throw new wsError_1.WebSocketInterfaceError(wsError_1.ErrorCode.ERR_INVALID_URL, 'invalid url, password or username needed.');
21
+ }
19
22
  this._wsClient = new wsClient_1.WsClient(this._wsConfig.url, this._wsConfig.timeout);
20
23
  }
21
24
  async init() {
22
- await this._wsClient.ready();
25
+ let wsSql = null;
26
+ try {
27
+ if (this._wsConfig.sql_url) {
28
+ wsSql = new wsClient_1.WsClient(this._wsConfig.sql_url, this._wsConfig.timeout);
29
+ await wsSql.connect();
30
+ await wsSql.checkVersion();
31
+ await this._wsClient.ready();
32
+ }
33
+ else {
34
+ throw (new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_WEBSOCKET_CONNECTION_FAIL, `connection creation failed, url: ${this._wsConfig.url}`));
35
+ }
36
+ }
37
+ catch (e) {
38
+ await this._wsClient.close();
39
+ throw (e);
40
+ }
41
+ finally {
42
+ if (wsSql) {
43
+ await wsSql.close();
44
+ }
45
+ }
23
46
  return this;
24
47
  }
25
48
  static async newConsumer(wsConfig) {
@@ -44,7 +67,8 @@ class WsConsumer {
44
67
  topics: topics,
45
68
  offset_rest: this._wsConfig.offset_rest,
46
69
  auto_commit: this._wsConfig.auto_commit,
47
- auto_commit_interval_ms: this._wsConfig.auto_commit_interval_ms
70
+ auto_commit_interval_ms: this._wsConfig.auto_commit_interval_ms,
71
+ config: this._wsConfig.otherConfigs
48
72
  },
49
73
  };
50
74
  this._topics = topics;
@@ -4,12 +4,18 @@ const wsConnectorPool_1 = require("../../src/client/wsConnectorPool");
4
4
  const config_1 = require("../../src/common/config");
5
5
  const wsSql_1 = require("../../src/sql/wsSql");
6
6
  const utils_1 = require("../utils");
7
+ const log_1 = require("../../src/common/log");
7
8
  let dns = 'ws://localhost:6041';
9
+ let password1 = 'Ab1!@#$%,.:?<>;~';
10
+ let password2 = 'Bc%^&*()-_+=[]{}';
11
+ (0, log_1.setLevel)("debug");
8
12
  beforeAll(async () => {
9
13
  let conf = new config_1.WSConfig(dns);
10
14
  conf.setUser('root');
11
15
  conf.setPwd('taosdata');
12
16
  let wsSql = await wsSql_1.WsSql.open(conf);
17
+ await wsSql.exec(`CREATE USER user1 PASS '${password1}'`);
18
+ await wsSql.exec(`CREATE USER user2 PASS '${password2}'`);
13
19
  await wsSql.exec('create database if not exists power KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;');
14
20
  await (0, utils_1.Sleep)(100);
15
21
  await wsSql.exec('use power');
@@ -28,6 +34,30 @@ describe('TDWebSocket.WsSql()', () => {
28
34
  expect(wsSql.state()).toBeGreaterThan(0);
29
35
  await wsSql.close();
30
36
  });
37
+ test('special characters connect1', async () => {
38
+ let wsSql = null;
39
+ let conf = new config_1.WSConfig(dns);
40
+ conf.setUser('user1');
41
+ conf.setPwd(password1);
42
+ wsSql = await wsSql_1.WsSql.open(conf);
43
+ expect(wsSql.state()).toBeGreaterThan(0);
44
+ let version = await wsSql.version();
45
+ expect(version).not.toBeNull();
46
+ expect(version).not.toBeUndefined();
47
+ await wsSql.close();
48
+ });
49
+ test('special characters connect2', async () => {
50
+ let wsSql = null;
51
+ let conf = new config_1.WSConfig(dns);
52
+ conf.setUser('user2');
53
+ conf.setPwd(password2);
54
+ wsSql = await wsSql_1.WsSql.open(conf);
55
+ expect(wsSql.state()).toBeGreaterThan(0);
56
+ let version = await wsSql.version();
57
+ expect(version).not.toBeNull();
58
+ expect(version).not.toBeUndefined();
59
+ await wsSql.close();
60
+ });
31
61
  test('connect db with error', async () => {
32
62
  expect.assertions(1);
33
63
  let wsSql = null;
@@ -147,6 +177,8 @@ afterAll(async () => {
147
177
  conf.setPwd('taosdata');
148
178
  let wsSql = await wsSql_1.WsSql.open(conf);
149
179
  await wsSql.exec('drop database power');
180
+ await wsSql.exec('DROP USER user1;');
181
+ await wsSql.exec('DROP USER user2;');
150
182
  await wsSql.close();
151
183
  wsConnectorPool_1.WebSocketConnectionPool.instance().destroyed();
152
184
  });
@@ -228,7 +228,7 @@ describe('TDWebSocket.Stmt()', () => {
228
228
  let wsConf = new config_1.WSConfig(dsn);
229
229
  wsConf.setDb(db);
230
230
  let connector = await wsSql_1.WsSql.open(wsConf);
231
- let stmt = await (await connector).stmtInit();
231
+ let stmt = await connector.stmtInit();
232
232
  expect(stmt).toBeTruthy();
233
233
  expect(connector.state()).toBeGreaterThan(0);
234
234
  await stmt.prepare((0, utils_1.getInsertBind)(tableValues.length + 2, jsonTags.length, db, jsonTable));
@@ -62,12 +62,15 @@ describe('TDWebSocket.Tmq()', () => {
62
62
  [constant_1.TMQConstants.CLIENT_ID, 'test_tmq_client'],
63
63
  [constant_1.TMQConstants.WS_URL, tmqDsn],
64
64
  [constant_1.TMQConstants.ENABLE_AUTO_COMMIT, 'true'],
65
- [constant_1.TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000']
65
+ [constant_1.TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000'],
66
+ ["session.timeout.ms", "10000"],
67
+ ["max.poll.interval.ms", "30000"],
68
+ ["msg.with.table.name", "true"]
66
69
  ]);
67
70
  console.log(configMap);
68
71
  test('normal connect', async () => {
69
72
  let consumer = await wsTmq_1.WsConsumer.newConsumer(configMap);
70
- consumer.close();
73
+ await consumer.close();
71
74
  });
72
75
  test('connect error', async () => {
73
76
  expect.assertions(1);
@@ -80,7 +83,10 @@ describe('TDWebSocket.Tmq()', () => {
80
83
  [constant_1.TMQConstants.CLIENT_ID, 'test_tmq_client'],
81
84
  [constant_1.TMQConstants.WS_URL, tmqDsn],
82
85
  [constant_1.TMQConstants.ENABLE_AUTO_COMMIT, 'true'],
83
- [constant_1.TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000']
86
+ [constant_1.TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000'],
87
+ ["session.timeout.ms", "10000"],
88
+ ["max.poll.interval.ms", "30000"],
89
+ ["msg.with.table.name", "true"]
84
90
  ]);
85
91
  try {
86
92
  consumer = await wsTmq_1.WsConsumer.newConsumer(errConfigMap);
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../../../test/bulkPulling/utils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("../../src/common/utils");
4
+ describe('utils test', () => {
5
+ test('compare versions test', async () => {
6
+ expect((0, utils_1.compareVersions)("3.3.6.3-alpha", "3.3.6.2")).toBe(1);
7
+ expect((0, utils_1.compareVersions)("3.3.6.2", "3.3.6.3")).toBe(-1);
8
+ expect((0, utils_1.compareVersions)("3.3.6.3", "3.3.6.3")).toBe(0);
9
+ expect((0, utils_1.compareVersions)("3.3.6.3", "3.3.6.3-alpha")).toBe(1);
10
+ expect((0, utils_1.compareVersions)("3.3.6.3-beta", "3.3.6.3-alpha")).toBe(1);
11
+ expect((0, utils_1.compareVersions)("3.3", "3.3.0.0")).toBe(0);
12
+ });
13
+ });
@@ -7,6 +7,7 @@ const wsSql_1 = require("../../src/sql/wsSql");
7
7
  const constant_1 = require("../../src/tmq/constant");
8
8
  const wsTmq_1 = require("../../src/tmq/wsTmq");
9
9
  const utils_1 = require("../utils");
10
+ const log_1 = require("../../src/common/log");
10
11
  let dsn = 'ws://root:taosdata@localhost:6041';
11
12
  let tags = ['California.SanFrancisco', 3];
12
13
  let multi = [
@@ -30,6 +31,7 @@ const db = 'power_connect';
30
31
  const topics = ['pwer_meters_topic'];
31
32
  let createTopic = `create topic if not exists ${topics[0]} as select * from ${db}.${stable}`;
32
33
  let stmtIds = [];
34
+ (0, log_1.setLevel)("debug");
33
35
  async function connect() {
34
36
  let dsn = 'ws://root:taosdata@localhost:6041';
35
37
  let wsSql = null;
@@ -38,7 +40,7 @@ async function connect() {
38
40
  wsSql = await wsSql_1.WsSql.open(conf);
39
41
  expect(wsSql.state()).toBeGreaterThan(0);
40
42
  console.log(await wsSql.version());
41
- wsSql.close();
43
+ await wsSql.close();
42
44
  }
43
45
  async function stmtConnect() {
44
46
  let dsn = 'ws://root:taosdata@localhost:6041';
@@ -70,8 +72,8 @@ async function stmtConnect() {
70
72
  await stmt.batch();
71
73
  await stmt.exec();
72
74
  expect(stmt.getLastAffected()).toEqual(30);
73
- stmt.close();
74
- connector.close();
75
+ await stmt.close();
76
+ await connector.close();
75
77
  }
76
78
  async function tmqConnect() {
77
79
  let consumer = null;
@@ -101,7 +103,7 @@ async function tmqConnect() {
101
103
  }
102
104
  finally {
103
105
  if (consumer) {
104
- consumer.close();
106
+ await consumer.close();
105
107
  }
106
108
  }
107
109
  }
@@ -132,7 +134,6 @@ describe('TDWebSocket.WsSql()', () => {
132
134
  allp.push(tmqConnect());
133
135
  }
134
136
  await Promise.all(allp);
135
- wsConnectorPool_1.WebSocketConnectionPool.instance().destroyed();
136
137
  console.log(stmtIds);
137
138
  });
138
139
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tdengine/websocket",
3
- "version": "3.1.4",
3
+ "version": "3.1.6",
4
4
  "description": "The websocket Node.js connector for TDengine. TDengine versions 3.3.2.0 and above are recommended to use this connector.",
5
5
  "source": "index.ts",
6
6
  "main": "lib/index.js",
@@ -16,7 +16,6 @@
16
16
  "build": "tsc",
17
17
  "prepublish": "node ./prepare.js"
18
18
  },
19
-
20
19
  "repository": {
21
20
  "type": "git",
22
21
  "url": "git+https://github.com/taosdata/taos-connector-node.git"
@@ -39,10 +38,6 @@
39
38
  ],
40
39
  "homepage": "https://github.com/taosdata/taos-connector-node#readme",
41
40
  "dependencies": {
42
- "@types/json-bigint": "^1.0.1",
43
- "@types/node": "^18.0.0",
44
- "@types/uuid": "^9.0.8",
45
- "@types/websocket": "^1.0",
46
41
  "async-mutex": "^0.5.0",
47
42
  "json-bigint": "^1.0.0",
48
43
  "moment-timezone": "^0.5.45",
@@ -52,18 +47,19 @@
52
47
  "winston": "^3.17.0",
53
48
  "winston-daily-rotate-file": "^5.0.0"
54
49
  },
50
+
55
51
  "devDependencies": {
56
52
  "@parcel/packager-ts": "^2.7.0",
57
53
  "@parcel/transformer-typescript-types": "^2.7.0",
58
54
  "@types/jest": "^29.2.1",
59
55
  "@types/json-bigint": "^1.0.1",
60
56
  "@types/node": "^18.0.0",
61
- "@types/websocket": "^1.0",
62
57
  "@types/uuid": "^9.0.8",
58
+ "@types/websocket": "^1.0",
63
59
  "jest": "^29.2.2",
64
60
  "parcel": "^2.7.0",
61
+ "qingwa": "^1.0.7",
65
62
  "ts-jest": "^29.0.3",
66
- "typescript": "^5.3.3",
67
- "qingwa": "^1.0.7"
63
+ "typescript": "^5.3.3"
68
64
  }
69
65
  }
@@ -1,15 +0,0 @@
1
- {
2
- "keep": {
3
- "days": true,
4
- "amount": 14
5
- },
6
- "auditLog": "logs/.007e668bb78549e9a304b8466671945ab2a1553e-audit.json",
7
- "files": [
8
- {
9
- "date": 1737686882977,
10
- "name": "logs/app-2025-01-24.log",
11
- "hash": "8a2d013d385f90aa98e2df24afbdef62cb7a94443f79bd047d7b104714f9f37b"
12
- }
13
- ],
14
- "hashType": "sha256"
15
- }