@idm-plugin/vessel 1.0.0 → 1.0.2

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.
@@ -63,7 +63,8 @@ export declare class MyVesselImpl extends AISImpl {
63
63
  constructor(clientId: string, clientSecret: string);
64
64
  authToken(options?: RequestOptions): Promise<void>;
65
65
  realTimePosition(mmsi: number, options?: RequestOptions): Promise<AISRecord>;
66
- trajectory(mmsi: number, startTime: string, endTime: string, offset: number, scale?: boolean, options?: RequestOptions): Promise<any>;
66
+ trajectory(mmsi: number, startTime: string, endTime: string, offset: number, scale?: boolean, options?: RequestOptions): Promise<AISRecord[]>;
67
+ private trajectoryIn30Day;
67
68
  }
68
69
  export declare class HifleetImpl extends AISImpl {
69
70
  private readonly token;
@@ -72,3 +73,18 @@ export declare class HifleetImpl extends AISImpl {
72
73
  search(kw: string, options?: RequestOptions): Promise<VesselRecord>;
73
74
  trajectory(mmsi: number, startTime: string, endTime: string, offset: number, scale?: boolean, options?: RequestOptions): Promise<AISRecord[]>;
74
75
  }
76
+ export declare class ShipxyImpl extends AISImpl {
77
+ private readonly token;
78
+ constructor(token: string);
79
+ realTimePosition(mmsi: number, options?: RequestOptions): Promise<AISRecord>;
80
+ trajectory(mmsi: number, startTime: string, endTime: string, offset: number, scale?: boolean, options?: RequestOptions): Promise<AISRecord[]>;
81
+ }
82
+ export declare class MyShipImpl extends AISImpl {
83
+ private readonly token;
84
+ constructor(token: string);
85
+ getShipId(mmsi: any, options?: RequestOptions): Promise<string>;
86
+ getShipInfo(shipId: string, options?: RequestOptions): Promise<AISRecord>;
87
+ realTimePosition(mmsi: number, options?: RequestOptions): Promise<AISRecord>;
88
+ trajectory(mmsi: number, startTime: string, endTime: string, offset: number, scale?: boolean, options?: RequestOptions): Promise<AISRecord[]>;
89
+ private trajectoryIn30Day;
90
+ }
package/dist/index.js CHANGED
@@ -1,18 +1,18 @@
1
- var $ = Object.defineProperty;
2
- var A = (Y, h, s) => h in Y ? $(Y, h, { enumerable: !0, configurable: !0, writable: !0, value: s }) : Y[h] = s;
3
- var v = (Y, h, s) => (A(Y, typeof h != "symbol" ? h + "" : h, s), s);
4
- import y from "got";
5
- import * as P from "log4js";
6
- import l from "moment";
7
- const p = P.getLogger();
8
- class _ {
1
+ var P = Object.defineProperty;
2
+ var $ = (w, j, s) => j in w ? P(w, j, { enumerable: !0, configurable: !0, writable: !0, value: s }) : w[j] = s;
3
+ var x = (w, j, s) => ($(w, typeof j != "symbol" ? j + "" : j, s), s);
4
+ import I from "got";
5
+ import * as E from "log4js";
6
+ import f from "moment";
7
+ const g = E.getLogger();
8
+ class q {
9
9
  /**
10
10
  * 解析AIS状态码
11
11
  * @param status
12
12
  */
13
- parseStatus(h) {
13
+ parseStatus(j) {
14
14
  let s, o;
15
- switch (h) {
15
+ switch (j) {
16
16
  case 0:
17
17
  s = "在航(主机推动)", o = "The engine is in use";
18
18
  break;
@@ -46,48 +46,48 @@ class _ {
46
46
  return { labelCn: s, labelEn: o };
47
47
  }
48
48
  }
49
- class L extends _ {
49
+ class L extends q {
50
50
  constructor(s, o) {
51
51
  super();
52
- v(this, "clientId");
53
- v(this, "clientSecret");
54
- v(this, "token");
52
+ x(this, "clientId");
53
+ x(this, "clientSecret");
54
+ x(this, "token");
55
55
  this.clientId = s, this.clientSecret = o;
56
56
  }
57
57
  async authToken(s = {}) {
58
- const o = "https://svc.data.myvessel.cn/ada/oauth/token", c = {
58
+ const o = "https://svc.data.myvessel.cn/ada/oauth/token", r = {
59
59
  searchParams: {
60
60
  client_id: this.clientId,
61
61
  client_secret: this.clientSecret,
62
62
  grant_type: "client_credentials"
63
63
  }
64
- }, a = await y.post(o, c).json();
65
- p.info("[%s] fetch access token from: %s - %j", s.requestId, o, a), a.error || (this.token = {
66
- accessToken: a.access_token,
67
- tokenType: a.token_type,
68
- expiresIn: a.expires_in,
69
- scope: a.scope,
70
- jti: a.jti,
71
- issuedAt: l().utc().format()
64
+ }, i = await I.post(o, r).json();
65
+ g.info("[%s] fetch access token from: %s - %j", s.requestId, o, i), i.error || (this.token = {
66
+ accessToken: i.access_token,
67
+ tokenType: i.token_type,
68
+ expiresIn: i.expires_in,
69
+ scope: i.scope,
70
+ jti: i.jti,
71
+ issuedAt: f().utc().format()
72
72
  });
73
73
  }
74
74
  async realTimePosition(s, o = {}) {
75
- var d, f, g;
76
- (!this.token || l().diff(l(this.token.issuedAt), "seconds") > ((d = this.token) == null ? void 0 : d.expiresIn) - 300) && await this.authToken(o);
77
- const c = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", a = {
75
+ var u, c, m;
76
+ (!this.token || f().diff(f(this.token.issuedAt), "seconds") > ((u = this.token) == null ? void 0 : u.expiresIn) - 300) && await this.authToken(o);
77
+ const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", i = {
78
78
  headers: {
79
- Authorization: `${(f = this.token) == null ? void 0 : f.tokenType} ${(g = this.token) == null ? void 0 : g.accessToken}`
79
+ Authorization: `${(c = this.token) == null ? void 0 : c.tokenType} ${(m = this.token) == null ? void 0 : m.accessToken}`
80
80
  },
81
81
  searchParams: { mmsi: s }
82
82
  };
83
- p.info("[%s] fetch realtime position from: %s - %j", o.requestId, c, a);
84
- const e = await y.get(c, a).json();
83
+ g.info("[%s] fetch realtime position from: %s - %j", o.requestId, r, i);
84
+ const e = await I.get(r, i).json();
85
85
  if (e.code)
86
- return p.warn("[%s] fetch realtime position failed: %j", o.requestId, c, { message: e.message, status: e.status, code: e.code }), e;
86
+ return g.warn("[%s] fetch realtime position failed: %j", o.requestId, r, { message: e.message, status: e.status, code: e.code }), e;
87
87
  const t = e.data;
88
- for (const r in t)
89
- !isNaN(t[r]) && Number(t[r]) !== 1 / 0 && (t[r] = Number(t[r]));
90
- const m = l(`${t.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
88
+ for (const h in t)
89
+ !isNaN(t[h]) && Number(t[h]) !== 1 / 0 && (t[h] = Number(t[h]));
90
+ const a = f(`${t.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
91
91
  return {
92
92
  mmsi: t.mmsi,
93
93
  name: t.vesselName,
@@ -104,88 +104,87 @@ class L extends _ {
104
104
  rot: t.rot,
105
105
  eta: t.eta,
106
106
  destination: t.dest,
107
- positionTime: m.unix(),
107
+ positionTime: a.unix(),
108
108
  status: t.status,
109
109
  labelCn: t.statusNameCn,
110
110
  labelEn: t.statusNameEn,
111
111
  method: "position",
112
112
  vendor: "myVessel",
113
- utc: m.utc().format()
113
+ utc: a.utc().format()
114
114
  };
115
115
  }
116
- async trajectory(s, o, c, a, e = !0, t = {}) {
117
- var H, T, D;
118
- (!this.token || l().diff(l(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(t);
119
- const m = await this.realTimePosition(s, t), u = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track";
120
- let d = l(o);
121
- const f = l(c);
122
- if (e) {
123
- const n = f.diff(d, "d", !0);
124
- (n < 0 || n > 30) && (d = f.clone().subtract(30, "d"));
125
- }
126
- const g = {
116
+ async trajectory(s, o, r, i, e = !0, t = {}) {
117
+ (!this.token || f().diff(f(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(t);
118
+ const a = await this.realTimePosition(s, t), n = f(o), u = f(r), c = [];
119
+ for (; u.diff(n, "day", !0) > 30; )
120
+ await this.trajectoryIn30Day(s, n, n.clone().add(30, "day"), a, i, c, t), n.add(30, "day");
121
+ return await this.trajectoryIn30Day(s, n, u, a, i, c, t), c;
122
+ }
123
+ async trajectoryIn30Day(s, o, r, i, e, t, a = {}) {
124
+ var y, k, Y, p, b;
125
+ const n = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", u = {
127
126
  headers: {
128
- Authorization: `${(H = this.token) == null ? void 0 : H.tokenType} ${(T = this.token) == null ? void 0 : T.accessToken}`
127
+ Authorization: `${(y = this.token) == null ? void 0 : y.tokenType} ${(k = this.token) == null ? void 0 : k.accessToken}`
129
128
  },
130
129
  json: {
131
130
  mmsi: s,
132
- startTime: d.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),
133
- endTime: f.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
131
+ startTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),
132
+ endTime: r.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
134
133
  }
135
134
  };
136
- p.info("[%s] fetch trajectory from: %s - %j", t.requestId, u, g);
137
- const r = await y.post(u, g).json();
138
- if (r.code)
139
- return p.warn("[%s] fetch trajectory failed: %j", t.requestId, u, { message: r.message, status: r.status, code: r.code }), r;
140
- let j = -1;
141
- const b = l(`${(D = r.data[0]) == null ? void 0 : D.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), N = [];
142
- return r.data.forEach((n) => {
143
- for (const k in n)
144
- !isNaN(n[k]) && Number(n[k]) !== 1 / 0 && (n[k] = Number(n[k]));
145
- const M = l(`${n.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), i = n.eta ? l(`${n.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00") : void 0, w = n.status, { labelCn: S, labelEn: q } = this.parseStatus(w), x = {
146
- mmsi: n.mmsi,
147
- imo: m == null ? void 0 : m.imo,
148
- lat: n.lat,
149
- lng: n.lon,
150
- sog: n.sog,
151
- cog: n.cog,
152
- hdg: n.hdg,
153
- draught: n.draught,
154
- status: w,
155
- eta: i == null ? void 0 : i.unix(),
156
- destination: n.dest,
135
+ g.info("[%s] fetch trajectory from: %s - %j", a.requestId, n, u);
136
+ const c = await I.post(n, u).json();
137
+ if (c.code)
138
+ return g.warn("[%s] fetch trajectory failed: %j", a.requestId, n, { message: c.message, status: c.status, code: c.code }), c;
139
+ let m = -1;
140
+ const h = f(`${(p = (Y = c.data) == null ? void 0 : Y[0]) == null ? void 0 : p.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
141
+ return (b = c.data) == null || b.forEach((l) => {
142
+ for (const S in l)
143
+ !isNaN(l[S]) && Number(l[S]) !== 1 / 0 && (l[S] = Number(l[S]));
144
+ const M = f(`${l.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), N = l.eta ? f(`${l.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00") : void 0, d = l.status, { labelCn: T, labelEn: H } = this.parseStatus(d), _ = {
145
+ mmsi: l.mmsi,
146
+ imo: i == null ? void 0 : i.imo,
147
+ lat: l.lat,
148
+ lng: l.lon,
149
+ sog: l.sog,
150
+ cog: l.cog,
151
+ hdg: l.hdg,
152
+ draught: l.draught,
153
+ status: d,
154
+ eta: N == null ? void 0 : N.unix(),
155
+ destination: l.dest,
157
156
  positionTime: M.unix(),
158
- labelCn: S,
159
- labelEn: q,
157
+ labelCn: T,
158
+ labelEn: H,
160
159
  method: "trajectory",
161
160
  vendor: "myVessel",
162
161
  utc: M.utc().format()
163
- }, I = Math.floor(M.diff(b, "minute", !0) / (a || 1));
164
- I !== j && (j = I, N.push(x));
165
- }), N;
162
+ }, D = Math.floor(M.diff(h, "minute", !0) / (e || 1));
163
+ D !== m && (m = D, t.push(_));
164
+ }), t;
166
165
  }
167
166
  }
168
- class V extends _ {
167
+ class K extends q {
169
168
  constructor(s) {
170
169
  super();
171
- v(this, "token");
170
+ x(this, "token");
172
171
  this.token = s;
173
172
  }
174
173
  async realTimePosition(s, o = {}) {
175
- const c = "https://api.hifleet.com/position/position/get/token", a = {
174
+ const r = "https://api.hifleet.com/position/position/get/token", i = {
176
175
  searchParams: {
177
176
  mmsi: s,
178
177
  usertoken: this.token
179
178
  }
180
- }, e = await y.post(c, a).json();
181
- p.info("[%s] fetch realtime position from: %s - %j", o.requestId, c, a);
179
+ }, e = await I.post(r, i).json();
180
+ g.info("[%s] fetch realtime position from: %s - %j", o.requestId, r, i);
182
181
  const t = e == null ? void 0 : e.list;
183
182
  if (!t)
184
- return e;
185
- for (const r in t)
186
- !isNaN(t[r]) && Number(t[r]) !== 1 / 0 && (t[r] = Number(t[r]));
183
+ return g.warn("[%s] fetch realtime position failed: %j", o.requestId, r, e), e;
184
+ for (const h in t)
185
+ !isNaN(t[h]) && Number(t[h]) !== 1 / 0 && (t[h] = Number(t[h]));
187
186
  t.status = t.sp > 3 ? 0 : 1;
188
- const m = t.status, { labelCn: u, labelEn: d } = this.parseStatus(m), f = l(`${t.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
187
+ const a = t.status, { labelCn: n, labelEn: u } = this.parseStatus(a), c = f(`${t.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
189
188
  return {
190
189
  mmsi: t.m,
191
190
  name: t.n,
@@ -200,20 +199,20 @@ class V extends _ {
200
199
  cog: t.co,
201
200
  hdg: t.h,
202
201
  rot: isNaN(t.rot) ? 0 : t.rot,
203
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(t.eta) ? l(`${t.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").unix() : void 0,
202
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(t.eta) ? f(`${t.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").unix() : void 0,
204
203
  destination: t.destination,
205
- positionTime: f.unix(),
206
- utc: f.utc().format(),
207
- status: m,
208
- labelCn: u,
209
- labelEn: d,
204
+ positionTime: c.unix(),
205
+ utc: c.utc().format(),
206
+ status: a,
207
+ labelCn: n,
208
+ labelEn: u,
210
209
  method: "position",
211
210
  vendor: "hifleet"
212
211
  };
213
212
  }
214
213
  async search(s, o = {}) {
215
- let c = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
216
- const a = {
214
+ let r = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
215
+ const i = {
217
216
  searchParams: {
218
217
  keyword: s
219
218
  },
@@ -223,10 +222,10 @@ class V extends _ {
223
222
  Host: "www.hifleet.com"
224
223
  }
225
224
  };
226
- let e = await y.post(c, a).json();
227
- p.info("[%s] fetch vessel props from: %s - %j", o.requestId, c, a), e instanceof Array && (e = e[0]);
228
- for (const m in e)
229
- !isNaN(e[m]) && Number(e[m]) !== 1 / 0 && (e[m] = Number(e[m]));
225
+ let e = await I.post(r, i).json();
226
+ g.info("[%s] fetch vessel props from: %s - %j", o.requestId, r, i), e instanceof Array && (e = e[0]);
227
+ for (const a in e)
228
+ !isNaN(e[a]) && Number(e[a]) !== 1 / 0 && (e[a] = Number(e[a]));
230
229
  const t = {
231
230
  mmsi: e.m,
232
231
  name: e.n,
@@ -236,61 +235,257 @@ class V extends _ {
236
235
  breadth: e.b,
237
236
  draught: e.dr
238
237
  };
239
- return c = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", e = await y.post(c, a).json(), p.info("[%s] fetch vessel dead weight from: %s - %j", o.requestId, c, a), e instanceof Array && (e = e[0]), e && (t.deadweight = Number(e.dwt)), t;
238
+ return r = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", e = await I.post(r, i).json(), g.info("[%s] fetch vessel dead weight from: %s - %j", o.requestId, r, i), e instanceof Array && (e = e[0]), e && (t.deadweight = Number(e.dwt)), t;
240
239
  }
241
- async trajectory(s, o, c, a, e = !0, t = {}) {
242
- var D, n, M;
243
- const m = await this.realTimePosition(s, t);
244
- let u = l(o);
245
- const d = l(c), f = l();
240
+ async trajectory(s, o, r, i, e = !0, t = {}) {
241
+ var l, M, N;
242
+ const a = await this.realTimePosition(s, t);
243
+ let n = f(o);
244
+ const u = f(r), c = f();
246
245
  if (e) {
247
- let i = d.diff(u, "d", !0);
248
- i < 0 ? u = d.clone().subtract(40, "d") : i < 30 ? u.subtract(10, "d") : i < 60 ? u.subtract(5, "d") : u = d.clone().subtract(80, "d"), i = f.diff(d, "d", !0), d.add(i > 10 ? 240 : i * 24, "h");
246
+ let d = u.diff(n, "d", !0);
247
+ d < 0 ? n = u.clone().subtract(40, "d") : d < 30 ? n.subtract(10, "d") : d < 60 ? n.subtract(5, "d") : n = u.clone().subtract(80, "d"), d = c.diff(u, "d", !0), u.add(d > 10 ? 240 : d * 24, "h");
249
248
  }
250
- const g = {
249
+ const m = {
251
250
  searchParams: {
252
- endtime: d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
253
- starttime: u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
251
+ endtime: u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
252
+ starttime: n.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
254
253
  mmsi: s,
255
254
  usertoken: this.token
256
255
  }
257
- }, r = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", j = await y.get(r, g).json();
258
- p.info("[%s] fetch trajectory from: %s - %j", t.requestId, r, g);
259
- let b;
260
- j && (b = ((n = (D = j.ships) == null ? void 0 : D.offors) == null ? void 0 : n.ship) || [], b.length || p.warn("[%s] got vessel trajectory failed: %j", t.requestId, j));
261
- const N = [];
262
- let H = -1;
263
- const T = l(`${(M = b == null ? void 0 : b[0]) == null ? void 0 : M.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
264
- for (const i of b) {
265
- for (const k in i)
266
- !isNaN(i[k]) && Number(i[k]) !== 1 / 0 && (i[k] = Number(i[k]));
267
- const w = l(`${i.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
268
- i.status = i.sp > 4 ? 0 : 1;
269
- const { labelEn: S, labelCn: q } = this.parseStatus(i.status), x = {
270
- mmsi: i.m,
271
- name: i.n,
272
- imo: m == null ? void 0 : m.imo,
273
- lat: i.la,
274
- lng: i.lo,
275
- draught: i.draught,
276
- sog: i.sp,
277
- cog: i.co,
278
- hdg: i.hdg,
279
- positionTime: w.unix(),
280
- utc: w.utc().format(),
281
- status: i.status,
282
- labelCn: q,
283
- labelEn: S,
256
+ }, h = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", y = await I.get(h, m).json();
257
+ g.info("[%s] fetch trajectory from: %s - %j", t.requestId, h, m);
258
+ let k;
259
+ y && (k = ((M = (l = y.ships) == null ? void 0 : l.offors) == null ? void 0 : M.ship) || [], k.length || g.warn("[%s] fetch trajectory failed: %j", t.requestId, y));
260
+ const Y = [];
261
+ let p = -1;
262
+ const b = f(`${(N = k == null ? void 0 : k[0]) == null ? void 0 : N.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
263
+ for (const d of k) {
264
+ for (const v in d)
265
+ !isNaN(d[v]) && Number(d[v]) !== 1 / 0 && (d[v] = Number(d[v]));
266
+ const T = f(`${d.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
267
+ d.status = d.sp > 4 ? 0 : 1;
268
+ const { labelEn: H, labelCn: _ } = this.parseStatus(d.status), D = {
269
+ mmsi: d.m,
270
+ name: d.n,
271
+ imo: a == null ? void 0 : a.imo,
272
+ lat: d.la,
273
+ lng: d.lo,
274
+ draught: d.draught,
275
+ sog: d.sp,
276
+ cog: d.co,
277
+ hdg: d.hdg,
278
+ positionTime: T.unix(),
279
+ utc: T.utc().format(),
280
+ status: d.status,
281
+ labelCn: _,
282
+ labelEn: H,
284
283
  method: "trajectory",
285
284
  vendor: "hifleet"
286
- }, I = Math.floor(w.diff(T, "minute", !0) / (a || 1));
287
- I !== H && (H = I, N.push(x));
285
+ }, S = Math.floor(T.diff(b, "minute", !0) / (i || 1));
286
+ S !== p && (p = S, Y.push(D));
287
+ }
288
+ return Y;
289
+ }
290
+ }
291
+ class V extends q {
292
+ constructor(s) {
293
+ super();
294
+ x(this, "token");
295
+ this.token = s;
296
+ }
297
+ async realTimePosition(s, o = {}) {
298
+ const r = {
299
+ searchParams: {
300
+ id: s,
301
+ k: this.token,
302
+ enc: 1
303
+ }
304
+ }, i = "https://api.shipxy.com/apicall/GetSingleShip", e = await I.get(i, r).json();
305
+ if (g.info("[%s] fetch realtime position from: %s - %j", o.requestId, i, r), (e == null ? void 0 : e.status) !== 0)
306
+ return e;
307
+ const t = e.data[0];
308
+ for (const m in t)
309
+ !isNaN(t[m]) && Number(t[m]) !== 1 / 0 && (t[m] = Number(t[m]));
310
+ const { labelCn: a, labelEn: n } = await this.parseStatus(t.navistat), u = f.unix(t.lasttime);
311
+ return {
312
+ mmsi: t.ShipID,
313
+ name: t.name,
314
+ imo: t.imo,
315
+ callSign: t.callsign,
316
+ lat: Math.round(t.lat / 1e6 * 1e5) / 1e5,
317
+ lng: Math.round(t.lon / 1e6 * 1e5) / 1e5,
318
+ length: Math.round(t.length / 10 * 100) / 100,
319
+ width: Math.round(t.width / 10 * 100) / 100,
320
+ draught: Math.round(t.draught / 1e3 * 100) / 100,
321
+ sog: Math.round(t.sog * 3600 / 1e3 / 1852 * 100) / 100,
322
+ cog: Math.round(t.cog / 100 * 100) / 100,
323
+ hdg: Math.round(t.hdg / 100 * 100) / 100,
324
+ rot: Math.round(t.rot / 100 * 100) / 100,
325
+ positionTime: t.lasttime,
326
+ utc: u.utc().format(),
327
+ status: t.navistat,
328
+ labelEn: n,
329
+ labelCn: a,
330
+ method: "position",
331
+ vendor: "shipxy"
332
+ };
333
+ }
334
+ async trajectory(s, o, r, i, e = !0, t = {}) {
335
+ var b;
336
+ const a = await this.realTimePosition(s, t), n = f(o), u = f(r), c = "https://api.shipxy.com/apicall/GetShipTrack", m = {
337
+ searchParams: {
338
+ id: s,
339
+ k: this.token,
340
+ enc: 1,
341
+ cut: 0,
342
+ btm: n.unix(),
343
+ etm: u.unix()
344
+ }
345
+ }, h = await I.get(c, m).json();
346
+ if (g.info("[%s] fetch trajectory from: %s - %j", t.requestId, c, m), (h == null ? void 0 : h.status) !== 0)
347
+ return h;
348
+ const y = h == null ? void 0 : h.points, k = [], Y = f.unix((b = y[0]) == null ? void 0 : b.utc);
349
+ let p = -1;
350
+ for (const l of y) {
351
+ const M = f.unix(l.utc), N = {
352
+ imo: a == null ? void 0 : a.imo,
353
+ mmsi: s,
354
+ sog: Math.round(l.sog * 3600 / 1e3 / 1852 * 100) / 100,
355
+ cog: Math.round(l.cog / 100 * 100) / 100,
356
+ lat: Math.round(l.lat / 1e6 * 1e5) / 1e5,
357
+ lng: Math.round(l.lon / 1e6 * 1e5) / 1e5,
358
+ positionTime: M.unix(),
359
+ utc: M.utc().format(),
360
+ method: "trajectory",
361
+ vendor: "shipxy"
362
+ }, d = Math.floor(M.diff(Y, "minute", !0) / (i || 1));
363
+ d !== p && (p = d, k.push(N));
364
+ }
365
+ return k;
366
+ }
367
+ }
368
+ class z extends q {
369
+ constructor(s) {
370
+ super();
371
+ x(this, "token");
372
+ this.token = s;
373
+ }
374
+ async getShipId(s, o = {}) {
375
+ const r = {
376
+ headers: {
377
+ appKey: this.token
378
+ },
379
+ json: {
380
+ mmsiList: s
381
+ }
382
+ }, i = "https://api3.myships.com/sp/ships/getShipIdByMMSI", e = await I.post(i, r).json();
383
+ return g.info("[%s] fetch ship id from: %s - %j", o.requestId, i, r), e.code !== "0" ? e : e.data[0].shipId;
384
+ }
385
+ async getShipInfo(s, o = {}) {
386
+ const r = {
387
+ headers: {
388
+ appKey: this.token
389
+ },
390
+ json: {
391
+ shipId: s
392
+ }
393
+ }, i = "https://api3.myships.com/sp/ships/aissta", e = await I.post(i, r).json();
394
+ if (g.info("[%s] fetch ship info from: %s - %j", o.requestId, i, r), e.code !== "0")
395
+ return e;
396
+ const t = e.data;
397
+ let a = t.imo;
398
+ return s === "407170" && (a = "9198379", g.warn("[%s] ship(%s) imo error: %s, should be %s", o.requestId, s, t.imo, a)), {
399
+ mmsi: t.mmsi,
400
+ name: t.shipnameEn,
401
+ imo: a,
402
+ callSign: t.callSign,
403
+ length: t.length,
404
+ width: t.breadth,
405
+ draught: (t.draught || 100) / 10
406
+ };
407
+ }
408
+ async realTimePosition(s, o = {}) {
409
+ const r = await this.getShipId(s, o), i = await this.getShipInfo(r, o), e = {
410
+ headers: {
411
+ appKey: this.token
412
+ },
413
+ json: {
414
+ shipId: r
415
+ }
416
+ }, t = "https://api3.myships.com/sp/ships/position/latest", a = await I.post(t, e).json();
417
+ g.info("[%s] fetch realtime position from: %s - %j", o.requestId, t, e);
418
+ const n = a.data[0];
419
+ for (const y in n)
420
+ !isNaN(n[y]) && Number(n[y]) !== 1 / 0 && (n[y] = Number(n[y]));
421
+ const { labelCn: u, labelEn: c } = await this.parseStatus(n.aisNavStatus), m = f.unix(n.posTime);
422
+ return {
423
+ ...i,
424
+ mmsi: s,
425
+ lat: Math.round(n.lat / 1e4 / 60 * 1e5) / 1e5,
426
+ lng: Math.round(n.lon / 1e4 / 60 * 1e5) / 1e5,
427
+ sog: Math.round(n.sog / 10 * 100) / 100,
428
+ cog: Math.round(n.cog / 10 * 100) / 100,
429
+ hdg: Math.round(n.heading * 100) / 100,
430
+ rot: Math.round(n.rot * 100) / 100,
431
+ positionTime: n.posTime,
432
+ utc: m.utc().format(),
433
+ status: n.aisNavStatus,
434
+ labelEn: c,
435
+ labelCn: u,
436
+ method: "position",
437
+ vendor: "myship"
438
+ };
439
+ }
440
+ async trajectory(s, o, r, i, e = !0, t = {}) {
441
+ const a = f(o), n = f(r), u = await this.getShipId(s), c = await this.getShipInfo(u), m = [];
442
+ for (; n.diff(a, "day", !0) > 30; )
443
+ await this.trajectoryIn30Day(u, a.unix(), a.add(30, "day").unix(), c, s, i, m);
444
+ return await this.trajectoryIn30Day(u, a.unix(), n.unix(), c, s, i, m), m;
445
+ }
446
+ async trajectoryIn30Day(s, o, r, i, e, t, a, n = {}) {
447
+ var Y;
448
+ const u = {
449
+ headers: {
450
+ appKey: this.token
451
+ },
452
+ json: {
453
+ shipId: s,
454
+ startTime: o,
455
+ endTime: r
456
+ }
457
+ }, c = "https://api3.myships.com/sp/ships/position/history", m = await I.post(c, u).json();
458
+ if (g.info("[%s] fetch trajectory from: %s - %j", n.requestId, c, u), m.code !== "0")
459
+ return g.warn("[%s] invoke myship trajectory failed: %j", n.requestId, m), m;
460
+ const h = m.data;
461
+ for (const p in h)
462
+ !isNaN(h[p]) && Number(h[p]) !== 1 / 0 && (h[p] = Number(h[p]));
463
+ const y = f.unix((Y = h[0]) == null ? void 0 : Y.posTime);
464
+ let k = -1;
465
+ for (const p of h) {
466
+ const b = f.unix(p.posTime), l = {
467
+ imo: i == null ? void 0 : i.imo,
468
+ mmsi: e,
469
+ lat: Math.round(p.lat / 1e4 / 60 * 1e5) / 1e5,
470
+ lng: Math.round(p.lon / 1e4 / 60 * 1e5) / 1e5,
471
+ sog: Math.round(p.sog / 10 * 100) / 100,
472
+ cog: Math.round(p.cog / 10 * 100) / 100,
473
+ hdg: Math.round(p.heading * 100) / 100,
474
+ rot: Math.round(p.rot * 100) / 100,
475
+ positionTime: b.unix(),
476
+ utc: b.utc().format(),
477
+ method: "trajectory",
478
+ vendor: "myship"
479
+ }, M = Math.floor(b.diff(y, "minute", !0) / (t || 1));
480
+ M !== k && (k = M, a.push(l));
288
481
  }
289
- return N;
482
+ return a;
290
483
  }
291
484
  }
292
485
  export {
293
- _ as AISImpl,
294
- V as HifleetImpl,
295
- L as MyVesselImpl
486
+ q as AISImpl,
487
+ K as HifleetImpl,
488
+ z as MyShipImpl,
489
+ L as MyVesselImpl,
490
+ V as ShipxyImpl
296
491
  };
@@ -1 +1 @@
1
- (function(f,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("got"),require("log4js"),require("moment")):typeof define=="function"&&define.amd?define(["exports","got","log4js","moment"],c):(f=typeof globalThis<"u"?globalThis:f||self,c(f["idm-plugin-rabbitmq"]={},f.got,f.log4js,f.moment))})(this,function(f,c,j,l){"use strict";var C=Object.defineProperty;var V=(f,c,j)=>c in f?C(f,c,{enumerable:!0,configurable:!0,writable:!0,value:j}):f[c]=j;var S=(f,c,j)=>(V(f,typeof c!="symbol"?c+"":c,j),j);function $(Y){const M=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(Y){for(const s in Y)if(s!=="default"){const i=Object.getOwnPropertyDescriptor(Y,s);Object.defineProperty(M,s,i.get?i:{enumerable:!0,get:()=>Y[s]})}}return M.default=Y,Object.freeze(M)}const g=$(j).getLogger();class _{parseStatus(M){let s,i;switch(M){case 0:s="在航(主机推动)",i="The engine is in use";break;case 1:s="锚泊",i="Anchored";break;case 2:s="失控",i="Not operated";break;case 3:s="操纵受限",i="Limited airworthiness";break;case 4:s="吃水受限",i="Limited by ship's draft";break;case 5:s="靠泊",i="Mooring";break;case 6:s="搁浅",i="Stranded";break;case 7:s="捕捞作业",i="Engaged in fishing";break;case 8:s="靠帆船提供动力",i="Sailing";break;default:s="未定义",i="Undefined"}return{labelCn:s,labelEn:i}}}class A extends _{constructor(s,i){super();S(this,"clientId");S(this,"clientSecret");S(this,"token");this.clientId=s,this.clientSecret=i}async authToken(s={}){const i="https://svc.data.myvessel.cn/ada/oauth/token",d={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},a=await c.post(i,d).json();g.info("[%s] fetch access token from: %s - %j",s.requestId,i,a),a.error||(this.token={accessToken:a.access_token,tokenType:a.token_type,expiresIn:a.expires_in,scope:a.scope,jti:a.jti,issuedAt:l().utc().format()})}async realTimePosition(s,i={}){var h,p,k;(!this.token||l().diff(l(this.token.issuedAt),"seconds")>((h=this.token)==null?void 0:h.expiresIn)-300)&&await this.authToken(i);const d="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",a={headers:{Authorization:`${(p=this.token)==null?void 0:p.tokenType} ${(k=this.token)==null?void 0:k.accessToken}`},searchParams:{mmsi:s}};g.info("[%s] fetch realtime position from: %s - %j",i.requestId,d,a);const e=await c.get(d,a).json();if(e.code)return g.warn("[%s] fetch realtime position failed: %j",i.requestId,d,{message:e.message,status:e.status,code:e.code}),e;const t=e.data;for(const r in t)!isNaN(t[r])&&Number(t[r])!==1/0&&(t[r]=Number(t[r]));const u=l(`${t.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:t.mmsi,name:t.vesselName,imo:t.imo,callSign:t.callsign,lat:t.lat,lng:t.lon,length:t.length,width:t.width,draught:t.currDraught,sog:t.sog,cog:t.cog,hdg:t.hdg,rot:t.rot,eta:t.eta,destination:t.dest,positionTime:u.unix(),status:t.status,labelCn:t.statusNameCn,labelEn:t.statusNameEn,method:"position",vendor:"myVessel",utc:u.utc().format()}}async trajectory(s,i,d,a,e=!0,t={}){var H,q,T;(!this.token||l().diff(l(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(t);const u=await this.realTimePosition(s,t),m="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track";let h=l(i);const p=l(d);if(e){const o=p.diff(h,"d",!0);(o<0||o>30)&&(h=p.clone().subtract(30,"d"))}const k={headers:{Authorization:`${(H=this.token)==null?void 0:H.tokenType} ${(q=this.token)==null?void 0:q.accessToken}`},json:{mmsi:s,startTime:h.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:p.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};g.info("[%s] fetch trajectory from: %s - %j",t.requestId,m,k);const r=await c.post(m,k).json();if(r.code)return g.warn("[%s] fetch trajectory failed: %j",t.requestId,m,{message:r.message,status:r.status,code:r.code}),r;let w=-1;const y=l(`${(T=r.data[0])==null?void 0:T.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),D=[];return r.data.forEach(o=>{for(const b in o)!isNaN(o[b])&&Number(o[b])!==1/0&&(o[b]=Number(o[b]));const I=l(`${o.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),n=o.eta?l(`${o.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"):void 0,N=o.status,{labelCn:x,labelEn:O}=this.parseStatus(N),P={mmsi:o.mmsi,imo:u==null?void 0:u.imo,lat:o.lat,lng:o.lon,sog:o.sog,cog:o.cog,hdg:o.hdg,draught:o.draught,status:N,eta:n==null?void 0:n.unix(),destination:o.dest,positionTime:I.unix(),labelCn:x,labelEn:O,method:"trajectory",vendor:"myVessel",utc:I.utc().format()},v=Math.floor(I.diff(y,"minute",!0)/(a||1));v!==w&&(w=v,D.push(P))}),D}}class E extends _{constructor(s){super();S(this,"token");this.token=s}async realTimePosition(s,i={}){const d="https://api.hifleet.com/position/position/get/token",a={searchParams:{mmsi:s,usertoken:this.token}},e=await c.post(d,a).json();g.info("[%s] fetch realtime position from: %s - %j",i.requestId,d,a);const t=e==null?void 0:e.list;if(!t)return e;for(const r in t)!isNaN(t[r])&&Number(t[r])!==1/0&&(t[r]=Number(t[r]));t.status=t.sp>3?0:1;const u=t.status,{labelCn:m,labelEn:h}=this.parseStatus(u),p=l(`${t.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:t.m,name:t.n,imo:t.imonumber,callSign:t.callsign,lat:Math.round(t.la/60*1e5)/1e5,lng:Math.round(t.lo/60*1e5)/1e5,length:t.l,width:t.w,draught:t.draught,sog:t.sp,cog:t.co,hdg:t.h,rot:isNaN(t.rot)?0:t.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(t.eta)?l(`${t.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").unix():void 0,destination:t.destination,positionTime:p.unix(),utc:p.utc().format(),status:u,labelCn:m,labelEn:h,method:"position",vendor:"hifleet"}}async search(s,i={}){let d="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const a={searchParams:{keyword:s},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let e=await c.post(d,a).json();g.info("[%s] fetch vessel props from: %s - %j",i.requestId,d,a),e instanceof Array&&(e=e[0]);for(const u in e)!isNaN(e[u])&&Number(e[u])!==1/0&&(e[u]=Number(e[u]));const t={mmsi:e.m,name:e.n,imo:e.i,callSign:e.c,length:e.l,breadth:e.b,draught:e.dr};return d="https://www.hifleet.com/hifleetapi/sameShipSearch.do",e=await c.post(d,a).json(),g.info("[%s] fetch vessel dead weight from: %s - %j",i.requestId,d,a),e instanceof Array&&(e=e[0]),e&&(t.deadweight=Number(e.dwt)),t}async trajectory(s,i,d,a,e=!0,t={}){var T,o,I;const u=await this.realTimePosition(s,t);let m=l(i);const h=l(d),p=l();if(e){let n=h.diff(m,"d",!0);n<0?m=h.clone().subtract(40,"d"):n<30?m.subtract(10,"d"):n<60?m.subtract(5,"d"):m=h.clone().subtract(80,"d"),n=p.diff(h,"d",!0),h.add(n>10?240:n*24,"h")}const k={searchParams:{endtime:h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:m.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:s,usertoken:this.token}},r="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",w=await c.get(r,k).json();g.info("[%s] fetch trajectory from: %s - %j",t.requestId,r,k);let y;w&&(y=((o=(T=w.ships)==null?void 0:T.offors)==null?void 0:o.ship)||[],y.length||g.warn("[%s] got vessel trajectory failed: %j",t.requestId,w));const D=[];let H=-1;const q=l(`${(I=y==null?void 0:y[0])==null?void 0:I.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const n of y){for(const b in n)!isNaN(n[b])&&Number(n[b])!==1/0&&(n[b]=Number(n[b]));const N=l(`${n.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");n.status=n.sp>4?0:1;const{labelEn:x,labelCn:O}=this.parseStatus(n.status),P={mmsi:n.m,name:n.n,imo:u==null?void 0:u.imo,lat:n.la,lng:n.lo,draught:n.draught,sog:n.sp,cog:n.co,hdg:n.hdg,positionTime:N.unix(),utc:N.utc().format(),status:n.status,labelCn:O,labelEn:x,method:"trajectory",vendor:"hifleet"},v=Math.floor(N.diff(q,"minute",!0)/(a||1));v!==H&&(H=v,D.push(P))}return D}}f.AISImpl=_,f.HifleetImpl=E,f.MyVesselImpl=A,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
1
+ (function(y,m){typeof exports=="object"&&typeof module<"u"?m(exports,require("got"),require("log4js"),require("moment")):typeof define=="function"&&define.amd?define(["exports","got","log4js","moment"],m):(y=typeof globalThis<"u"?globalThis:y||self,m(y["idm-plugin-rabbitmq"]={},y.got,y.log4js,y.moment))})(this,function(y,m,T,l){"use strict";var V=Object.defineProperty;var K=(y,m,T)=>m in y?V(y,m,{enumerable:!0,configurable:!0,writable:!0,value:T}):y[m]=T;var x=(y,m,T)=>(K(y,typeof m!="symbol"?m+"":m,T),T);function $(w){const S=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(w){for(const s in w)if(s!=="default"){const i=Object.getOwnPropertyDescriptor(w,s);Object.defineProperty(S,s,i.get?i:{enumerable:!0,get:()=>w[s]})}}return S.default=w,Object.freeze(S)}const j=$(T).getLogger();class q{parseStatus(S){let s,i;switch(S){case 0:s="在航(主机推动)",i="The engine is in use";break;case 1:s="锚泊",i="Anchored";break;case 2:s="失控",i="Not operated";break;case 3:s="操纵受限",i="Limited airworthiness";break;case 4:s="吃水受限",i="Limited by ship's draft";break;case 5:s="靠泊",i="Mooring";break;case 6:s="搁浅",i="Stranded";break;case 7:s="捕捞作业",i="Engaged in fishing";break;case 8:s="靠帆船提供动力",i="Sailing";break;default:s="未定义",i="Undefined"}return{labelCn:s,labelEn:i}}}class E extends q{constructor(s,i){super();x(this,"clientId");x(this,"clientSecret");x(this,"token");this.clientId=s,this.clientSecret=i}async authToken(s={}){const i="https://svc.data.myvessel.cn/ada/oauth/token",r={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},o=await m.post(i,r).json();j.info("[%s] fetch access token from: %s - %j",s.requestId,i,o),o.error||(this.token={accessToken:o.access_token,tokenType:o.token_type,expiresIn:o.expires_in,scope:o.scope,jti:o.jti,issuedAt:l().utc().format()})}async realTimePosition(s,i={}){var h,c,f;(!this.token||l().diff(l(this.token.issuedAt),"seconds")>((h=this.token)==null?void 0:h.expiresIn)-300)&&await this.authToken(i);const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",o={headers:{Authorization:`${(c=this.token)==null?void 0:c.tokenType} ${(f=this.token)==null?void 0:f.accessToken}`},searchParams:{mmsi:s}};j.info("[%s] fetch realtime position from: %s - %j",i.requestId,r,o);const e=await m.get(r,o).json();if(e.code)return j.warn("[%s] fetch realtime position failed: %j",i.requestId,r,{message:e.message,status:e.status,code:e.code}),e;const t=e.data;for(const u in t)!isNaN(t[u])&&Number(t[u])!==1/0&&(t[u]=Number(t[u]));const a=l(`${t.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:t.mmsi,name:t.vesselName,imo:t.imo,callSign:t.callsign,lat:t.lat,lng:t.lon,length:t.length,width:t.width,draught:t.currDraught,sog:t.sog,cog:t.cog,hdg:t.hdg,rot:t.rot,eta:t.eta,destination:t.dest,positionTime:a.unix(),status:t.status,labelCn:t.statusNameCn,labelEn:t.statusNameEn,method:"position",vendor:"myVessel",utc:a.utc().format()}}async trajectory(s,i,r,o,e=!0,t={}){(!this.token||l().diff(l(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(t);const a=await this.realTimePosition(s,t),n=l(i),h=l(r),c=[];for(;h.diff(n,"day",!0)>30;)await this.trajectoryIn30Day(s,n,n.clone().add(30,"day"),a,o,c,t),n.add(30,"day");return await this.trajectoryIn30Day(s,n,h,a,o,c,t),c}async trajectoryIn30Day(s,i,r,o,e,t,a={}){var k,M,Y,g,I;const n="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",h={headers:{Authorization:`${(k=this.token)==null?void 0:k.tokenType} ${(M=this.token)==null?void 0:M.accessToken}`},json:{mmsi:s,startTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:r.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};j.info("[%s] fetch trajectory from: %s - %j",a.requestId,n,h);const c=await m.post(n,h).json();if(c.code)return j.warn("[%s] fetch trajectory failed: %j",a.requestId,n,{message:c.message,status:c.status,code:c.code}),c;let f=-1;const u=l(`${(g=(Y=c.data)==null?void 0:Y[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(I=c.data)==null||I.forEach(p=>{for(const D in p)!isNaN(p[D])&&Number(p[D])!==1/0&&(p[D]=Number(p[D]));const b=l(`${p.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),N=p.eta?l(`${p.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"):void 0,d=p.status,{labelCn:v,labelEn:P}=this.parseStatus(d),O={mmsi:p.mmsi,imo:o==null?void 0:o.imo,lat:p.lat,lng:p.lon,sog:p.sog,cog:p.cog,hdg:p.hdg,draught:p.draught,status:d,eta:N==null?void 0:N.unix(),destination:p.dest,positionTime:b.unix(),labelCn:v,labelEn:P,method:"trajectory",vendor:"myVessel",utc:b.utc().format()},H=Math.floor(b.diff(u,"minute",!0)/(e||1));H!==f&&(f=H,t.push(O))}),t}}class A extends q{constructor(s){super();x(this,"token");this.token=s}async realTimePosition(s,i={}){const r="https://api.hifleet.com/position/position/get/token",o={searchParams:{mmsi:s,usertoken:this.token}},e=await m.post(r,o).json();j.info("[%s] fetch realtime position from: %s - %j",i.requestId,r,o);const t=e==null?void 0:e.list;if(!t)return j.warn("[%s] fetch realtime position failed: %j",i.requestId,r,e),e;for(const u in t)!isNaN(t[u])&&Number(t[u])!==1/0&&(t[u]=Number(t[u]));t.status=t.sp>3?0:1;const a=t.status,{labelCn:n,labelEn:h}=this.parseStatus(a),c=l(`${t.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:t.m,name:t.n,imo:t.imonumber,callSign:t.callsign,lat:Math.round(t.la/60*1e5)/1e5,lng:Math.round(t.lo/60*1e5)/1e5,length:t.l,width:t.w,draught:t.draught,sog:t.sp,cog:t.co,hdg:t.h,rot:isNaN(t.rot)?0:t.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(t.eta)?l(`${t.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").unix():void 0,destination:t.destination,positionTime:c.unix(),utc:c.utc().format(),status:a,labelCn:n,labelEn:h,method:"position",vendor:"hifleet"}}async search(s,i={}){let r="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const o={searchParams:{keyword:s},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let e=await m.post(r,o).json();j.info("[%s] fetch vessel props from: %s - %j",i.requestId,r,o),e instanceof Array&&(e=e[0]);for(const a in e)!isNaN(e[a])&&Number(e[a])!==1/0&&(e[a]=Number(e[a]));const t={mmsi:e.m,name:e.n,imo:e.i,callSign:e.c,length:e.l,breadth:e.b,draught:e.dr};return r="https://www.hifleet.com/hifleetapi/sameShipSearch.do",e=await m.post(r,o).json(),j.info("[%s] fetch vessel dead weight from: %s - %j",i.requestId,r,o),e instanceof Array&&(e=e[0]),e&&(t.deadweight=Number(e.dwt)),t}async trajectory(s,i,r,o,e=!0,t={}){var p,b,N;const a=await this.realTimePosition(s,t);let n=l(i);const h=l(r),c=l();if(e){let d=h.diff(n,"d",!0);d<0?n=h.clone().subtract(40,"d"):d<30?n.subtract(10,"d"):d<60?n.subtract(5,"d"):n=h.clone().subtract(80,"d"),d=c.diff(h,"d",!0),h.add(d>10?240:d*24,"h")}const f={searchParams:{endtime:h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:n.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:s,usertoken:this.token}},u="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",k=await m.get(u,f).json();j.info("[%s] fetch trajectory from: %s - %j",t.requestId,u,f);let M;k&&(M=((b=(p=k.ships)==null?void 0:p.offors)==null?void 0:b.ship)||[],M.length||j.warn("[%s] fetch trajectory failed: %j",t.requestId,k));const Y=[];let g=-1;const I=l(`${(N=M==null?void 0:M[0])==null?void 0:N.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const d of M){for(const _ in d)!isNaN(d[_])&&Number(d[_])!==1/0&&(d[_]=Number(d[_]));const v=l(`${d.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");d.status=d.sp>4?0:1;const{labelEn:P,labelCn:O}=this.parseStatus(d.status),H={mmsi:d.m,name:d.n,imo:a==null?void 0:a.imo,lat:d.la,lng:d.lo,draught:d.draught,sog:d.sp,cog:d.co,hdg:d.hdg,positionTime:v.unix(),utc:v.utc().format(),status:d.status,labelCn:O,labelEn:P,method:"trajectory",vendor:"hifleet"},D=Math.floor(v.diff(I,"minute",!0)/(o||1));D!==g&&(g=D,Y.push(H))}return Y}}class C extends q{constructor(s){super();x(this,"token");this.token=s}async realTimePosition(s,i={}){const r={searchParams:{id:s,k:this.token,enc:1}},o="https://api.shipxy.com/apicall/GetSingleShip",e=await m.get(o,r).json();if(j.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,r),(e==null?void 0:e.status)!==0)return e;const t=e.data[0];for(const f in t)!isNaN(t[f])&&Number(t[f])!==1/0&&(t[f]=Number(t[f]));const{labelCn:a,labelEn:n}=await this.parseStatus(t.navistat),h=l.unix(t.lasttime);return{mmsi:t.ShipID,name:t.name,imo:t.imo,callSign:t.callsign,lat:Math.round(t.lat/1e6*1e5)/1e5,lng:Math.round(t.lon/1e6*1e5)/1e5,length:Math.round(t.length/10*100)/100,width:Math.round(t.width/10*100)/100,draught:Math.round(t.draught/1e3*100)/100,sog:Math.round(t.sog*3600/1e3/1852*100)/100,cog:Math.round(t.cog/100*100)/100,hdg:Math.round(t.hdg/100*100)/100,rot:Math.round(t.rot/100*100)/100,positionTime:t.lasttime,utc:h.utc().format(),status:t.navistat,labelEn:n,labelCn:a,method:"position",vendor:"shipxy"}}async trajectory(s,i,r,o,e=!0,t={}){var I;const a=await this.realTimePosition(s,t),n=l(i),h=l(r),c="https://api.shipxy.com/apicall/GetShipTrack",f={searchParams:{id:s,k:this.token,enc:1,cut:0,btm:n.unix(),etm:h.unix()}},u=await m.get(c,f).json();if(j.info("[%s] fetch trajectory from: %s - %j",t.requestId,c,f),(u==null?void 0:u.status)!==0)return u;const k=u==null?void 0:u.points,M=[],Y=l.unix((I=k[0])==null?void 0:I.utc);let g=-1;for(const p of k){const b=l.unix(p.utc),N={imo:a==null?void 0:a.imo,mmsi:s,sog:Math.round(p.sog*3600/1e3/1852*100)/100,cog:Math.round(p.cog/100*100)/100,lat:Math.round(p.lat/1e6*1e5)/1e5,lng:Math.round(p.lon/1e6*1e5)/1e5,positionTime:b.unix(),utc:b.utc().format(),method:"trajectory",vendor:"shipxy"},d=Math.floor(b.diff(Y,"minute",!0)/(o||1));d!==g&&(g=d,M.push(N))}return M}}class L extends q{constructor(s){super();x(this,"token");this.token=s}async getShipId(s,i={}){const r={headers:{appKey:this.token},json:{mmsiList:s}},o="https://api3.myships.com/sp/ships/getShipIdByMMSI",e=await m.post(o,r).json();return j.info("[%s] fetch ship id from: %s - %j",i.requestId,o,r),e.code!=="0"?e:e.data[0].shipId}async getShipInfo(s,i={}){const r={headers:{appKey:this.token},json:{shipId:s}},o="https://api3.myships.com/sp/ships/aissta",e=await m.post(o,r).json();if(j.info("[%s] fetch ship info from: %s - %j",i.requestId,o,r),e.code!=="0")return e;const t=e.data;let a=t.imo;return s==="407170"&&(a="9198379",j.warn("[%s] ship(%s) imo error: %s, should be %s",i.requestId,s,t.imo,a)),{mmsi:t.mmsi,name:t.shipnameEn,imo:a,callSign:t.callSign,length:t.length,width:t.breadth,draught:(t.draught||100)/10}}async realTimePosition(s,i={}){const r=await this.getShipId(s,i),o=await this.getShipInfo(r,i),e={headers:{appKey:this.token},json:{shipId:r}},t="https://api3.myships.com/sp/ships/position/latest",a=await m.post(t,e).json();j.info("[%s] fetch realtime position from: %s - %j",i.requestId,t,e);const n=a.data[0];for(const k in n)!isNaN(n[k])&&Number(n[k])!==1/0&&(n[k]=Number(n[k]));const{labelCn:h,labelEn:c}=await this.parseStatus(n.aisNavStatus),f=l.unix(n.posTime);return{...o,mmsi:s,lat:Math.round(n.lat/1e4/60*1e5)/1e5,lng:Math.round(n.lon/1e4/60*1e5)/1e5,sog:Math.round(n.sog/10*100)/100,cog:Math.round(n.cog/10*100)/100,hdg:Math.round(n.heading*100)/100,rot:Math.round(n.rot*100)/100,positionTime:n.posTime,utc:f.utc().format(),status:n.aisNavStatus,labelEn:c,labelCn:h,method:"position",vendor:"myship"}}async trajectory(s,i,r,o,e=!0,t={}){const a=l(i),n=l(r),h=await this.getShipId(s),c=await this.getShipInfo(h),f=[];for(;n.diff(a,"day",!0)>30;)await this.trajectoryIn30Day(h,a.unix(),a.add(30,"day").unix(),c,s,o,f);return await this.trajectoryIn30Day(h,a.unix(),n.unix(),c,s,o,f),f}async trajectoryIn30Day(s,i,r,o,e,t,a,n={}){var Y;const h={headers:{appKey:this.token},json:{shipId:s,startTime:i,endTime:r}},c="https://api3.myships.com/sp/ships/position/history",f=await m.post(c,h).json();if(j.info("[%s] fetch trajectory from: %s - %j",n.requestId,c,h),f.code!=="0")return j.warn("[%s] invoke myship trajectory failed: %j",n.requestId,f),f;const u=f.data;for(const g in u)!isNaN(u[g])&&Number(u[g])!==1/0&&(u[g]=Number(u[g]));const k=l.unix((Y=u[0])==null?void 0:Y.posTime);let M=-1;for(const g of u){const I=l.unix(g.posTime),p={imo:o==null?void 0:o.imo,mmsi:e,lat:Math.round(g.lat/1e4/60*1e5)/1e5,lng:Math.round(g.lon/1e4/60*1e5)/1e5,sog:Math.round(g.sog/10*100)/100,cog:Math.round(g.cog/10*100)/100,hdg:Math.round(g.heading*100)/100,rot:Math.round(g.rot*100)/100,positionTime:I.unix(),utc:I.utc().format(),method:"trajectory",vendor:"myship"},b=Math.floor(I.diff(k,"minute",!0)/(t||1));b!==M&&(M=b,a.push(p))}return a}}y.AISImpl=q,y.HifleetImpl=A,y.MyShipImpl=L,y.MyVesselImpl=E,y.ShipxyImpl=C,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idm-plugin/vessel",
3
3
  "private": false,
4
- "version": "1.0.0",
4
+ "version": "1.0.2",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [