@idm-plugin/geo 1.0.0

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.
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ ## Geo Plugin
2
+ Geo插件
@@ -0,0 +1,2 @@
1
+ export * from './lngLat/src/';
2
+ export * from './tropicals/src/';
package/dist/index.js ADDED
@@ -0,0 +1,227 @@
1
+ import h from "moment";
2
+ import "moment-timezone";
3
+ import l from "tz-lookup";
4
+ import * as M from "log4js";
5
+ import * as f from "@turf/turf";
6
+ class s {
7
+ /**
8
+ * 基于输入的经度,计算出时区
9
+ * @param lng
10
+ * @param lat
11
+ */
12
+ static guessTimeZoneOffset(e, r) {
13
+ const t = l(r, e), i = h().tz(t).utcOffset();
14
+ return this.roundPrecision(i / 60, 1);
15
+ }
16
+ /**
17
+ * 将时间offset转换为时区,例如:8.5 => +08:30
18
+ * @param offset => 8.5
19
+ * @return timezone => +08:30
20
+ */
21
+ static prettyTimeZoneOffset(e) {
22
+ let r = Math.floor(Math.abs(e)), t = Math.round((Math.abs(e) - r) * 60);
23
+ return t = t > 9 ? t : `0${t}`, r = r > 9 ? r : `0${r}`, e > 0 ? `+${r}:${t}` : `-${r}:${t}`;
24
+ }
25
+ static lng2pretty(e, r = 6, t = "H°M′") {
26
+ e = s.convertToStdLng(e, r);
27
+ let i = "E";
28
+ e < 0 && (i = "W"), e = Math.abs(e), t = t.toUpperCase();
29
+ let o = e * 3600, n, u, c, d, p, a;
30
+ n = o % 3600 % 60, t.indexOf("S") !== -1 && (o = o - n, u = s.padNumber(n, 2, 2)), c = o / 60 % 60, t.indexOf("M") !== -1 && (t.indexOf("S") !== -1 ? d = s.roundPrecision(c, r).toString().padStart(2, "0") : d = s.padNumber(c, 2, 2), o = o - c * 60), p = o / 3600, t.indexOf("M") !== -1 ? a = s.roundPrecision(p, r).toString().padStart(3, "0") : a = s.padNumber(p, 3, 2);
31
+ const m = `${t.replace(/S+/gi, u).replace(/M+/gi, d).replace(/H+/gi, a)}${i}`;
32
+ return {
33
+ direction: i,
34
+ degree: s.roundPrecision(p, r),
35
+ minute: s.roundPrecision(c, r),
36
+ second: s.roundPrecision(n, r),
37
+ pretty: m
38
+ };
39
+ }
40
+ /**
41
+ * 纬度转化为精确数值
42
+ * @param lat 纬度
43
+ * @param precision 精确度
44
+ * @param format 格式化
45
+ */
46
+ static lat2pretty(e, r = 6, t = "H°M′") {
47
+ e = e % 180;
48
+ let i = "N";
49
+ e < 0 && (i = "S"), e = Math.abs(e), t = t.toUpperCase();
50
+ let o = e * 3600, n, u, c, d, p, a;
51
+ n = o % 3600 % 60, t.indexOf("S") !== -1 && (o = o - n, u = s.padNumber(n, 2, 2)), c = o / 60 % 60, t.indexOf("M") !== -1 && (t.indexOf("S") !== -1 ? d = s.roundPrecision(c, r).toString().padStart(2, "0") : d = s.padNumber(c, 2, 2), o = o - c * 60), p = o / 3600, t.indexOf("M") !== -1 ? a = s.roundPrecision(p, r).toString().padStart(2, "0") : a = s.padNumber(p, 2, 2);
52
+ const m = `${t.replace(/S+/gi, u).replace(/M+/gi, d).replace(/H+/gi, a)}${i}`;
53
+ return {
54
+ direction: i,
55
+ degree: s.roundPrecision(p, r),
56
+ minute: s.roundPrecision(c, r),
57
+ second: s.roundPrecision(n, r),
58
+ pretty: m
59
+ };
60
+ }
61
+ static str2Lng(e, r = 6) {
62
+ let t;
63
+ if (isNaN(e)) {
64
+ e = s.strReplace(e, "LNG");
65
+ const i = e[e.length - 1].toUpperCase();
66
+ e = e.substring(0, e.length - 1).trim();
67
+ const o = e.split(" ").filter((c) => c !== "").map((c) => Number(c));
68
+ let [n, u] = o;
69
+ if (n > 360 && !u) {
70
+ const c = this.roundPrecision(n / 100, 0);
71
+ u = n - c * 100, n = c;
72
+ }
73
+ t = n + (u ?? 0) / 60, i === "W" && (t = t * -1);
74
+ } else
75
+ t = Number(e);
76
+ return s.convertToStdLng(t, r);
77
+ }
78
+ static str2Lat(e, r = 6) {
79
+ let t;
80
+ if (isNaN(e)) {
81
+ e = s.strReplace(e, "LAT");
82
+ const i = e[e.length - 1].toUpperCase();
83
+ e = e.substring(0, e.length - 1).trim();
84
+ const o = e.split(" ").filter((c) => c !== "").map((c) => Number(c));
85
+ let [n, u] = o;
86
+ if (n > 90 && !u) {
87
+ const c = this.roundPrecision(n / 100, 0);
88
+ u = n - c * 100, n = c;
89
+ }
90
+ t = n + (u ?? 0) / 60, i === "S" && (t = t * -1);
91
+ } else
92
+ t = Number(e);
93
+ return s.roundPrecision(t, r);
94
+ }
95
+ static str2LngOrLat(e, r = 6, t = "LAT") {
96
+ e = s.strReplace(e, t);
97
+ const i = e[e.length - 1].toUpperCase();
98
+ return ["N", "S"].includes(i) ? {
99
+ lat: s.str2Lat(e, r)
100
+ } : {
101
+ lng: s.str2Lng(e, r)
102
+ };
103
+ }
104
+ static convertToStdLng(e, r = 4) {
105
+ return e > 180 ? (e = e % 360, e = e > 180 ? e - 360 : e) : e < -180 && (e = e % 360, e = e < -180 ? e + 360 : e), s.roundPrecision(e, r);
106
+ }
107
+ static roundPrecision(e, r = 4) {
108
+ if (typeof e == "number") {
109
+ const t = Number("1".padEnd(r + 1, "0"));
110
+ return Math.round(e * t) / t;
111
+ }
112
+ return e;
113
+ }
114
+ /**
115
+ * 转换为按经度单调增/减的坐标数组
116
+ * @param coordinates [[lng, lat]]
117
+ */
118
+ static convertToMonotonicLng2(e) {
119
+ for (let r = 1; r < e.length; r++)
120
+ e[r][0] += Math.round((e[r - 1][0] - e[r][0]) / 360) * 360;
121
+ return e;
122
+ }
123
+ /**
124
+ * 转移为按经度单调增/减的坐标数组
125
+ * @param coordinates [{lng, lat}]
126
+ */
127
+ static convertToMonotonicLng(e) {
128
+ for (let r = 1; r < e.length; r++)
129
+ e[r].lng += Math.round((e[r - 1].lng - e[r].lng) / 360) * 360;
130
+ return e;
131
+ }
132
+ static strReplace(e, r = "LAT") {
133
+ e = e.replace(/([0-9]+)\.([0-9]+\.[0-9]+)/g, "$1 $2").replace(/-/g, " ").replace(/°/, " ").replace(/'/g, " ").replace(/′/g, " ").replace(/"/g, " ").replace(/∼/g, " ").replace(/°/g, " ").replace(/,/g, ".").replace(/^ /g, "").replace(/ $/g, "").trim();
134
+ const t = e[e.length - 1].toUpperCase();
135
+ if (!["N", "S", "E", "W"].includes(t)) {
136
+ const i = e, o = Number(i.split(" ")[0]);
137
+ if (isNaN(o))
138
+ throw new Error(`invalid Lat/Lng: ${e}`);
139
+ o >= 90 ? e = `${i}E` : o <= -90 ? e = `${i}W` : ["LAN", "LNG"].includes(r == null ? void 0 : r.toUpperCase()) ? e = `${i}${o > 0 ? "E" : "W"}` : e = `${i}${o > 0 ? "N" : "S"}`;
140
+ }
141
+ return e;
142
+ }
143
+ /**
144
+ * 数据格式
145
+ * 例如: 10.5003 => 010.50
146
+ * @param num
147
+ * @param intPrecision 整数位数
148
+ * @param dcmPrecision 小数位数
149
+ */
150
+ static padNumber(e, r = 2, t = 2) {
151
+ const i = Math.trunc(e).toString().padStart(r, "0"), o = Math.trunc(s.roundPrecision(e - Math.trunc(e), t) * Math.pow(10, t)).toString().padStart(t, "0");
152
+ return `${i}.${o}`;
153
+ }
154
+ }
155
+ M.getLogger();
156
+ class $ {
157
+ static convert2Geojson(e) {
158
+ const r = f.featureCollection([]);
159
+ for (const t of e) {
160
+ if (t.forecasts)
161
+ for (const i of t.forecasts) {
162
+ const o = [], n = h(i.date).utc(), u = `${t.name}-${i.model}`;
163
+ for (const c in i == null ? void 0 : i.hours) {
164
+ const d = i.hours[c], p = n.clone().add(Number(c), "hour"), a = f.point([d.lng, d.lat], {
165
+ date: p.format(),
166
+ hour: Number(c),
167
+ format: p.format("MMM-DD/HHmm[Z]"),
168
+ pressure: d.pressure > 1e4 ? s.roundPrecision(d.pressure / 100, 0) : s.roundPrecision(d.pressure, 0),
169
+ gusts: d.gusts,
170
+ wind: d.wind || {},
171
+ movement: d.movement,
172
+ category: u,
173
+ type: "forecast"
174
+ });
175
+ r.features.push(a), o.push(a.geometry.coordinates);
176
+ }
177
+ if ((o == null ? void 0 : o.length) > 1) {
178
+ const c = f.lineString(s.convertToMonotonicLng2(o), {
179
+ date: i.date,
180
+ id: t.id || t.name,
181
+ model: i.model,
182
+ name: t.name,
183
+ category: u,
184
+ type: "forecast"
185
+ });
186
+ r.features.push(c);
187
+ }
188
+ }
189
+ if (t.history) {
190
+ const i = [];
191
+ for (const n of t.history) {
192
+ const u = h(n.updated).utc(), c = f.point([n.lng, n.lat], {
193
+ date: u.format(),
194
+ format: u.format("MMM-DD/HHmm[Z]"),
195
+ pressure: n.pressure > 1e4 ? s.roundPrecision(n.pressure / 100, 0) : s.roundPrecision(n.pressure, 0),
196
+ speed: n.speed,
197
+ kts: n.kts,
198
+ source: n.source,
199
+ level: n.type,
200
+ type: "history",
201
+ category: `${t.name}-history`
202
+ });
203
+ r.features.push(c), i.push(c.geometry.coordinates);
204
+ }
205
+ const o = t.history[0];
206
+ if (i.length === 1 && i.push(i[0]), i.length > 1) {
207
+ const n = f.lineString(s.convertToMonotonicLng2(i), {
208
+ name: t.name,
209
+ type: "history",
210
+ updated: o == null ? void 0 : o.updated,
211
+ pressure: (o == null ? void 0 : o.pressure) > 1e4 ? s.roundPrecision((o == null ? void 0 : o.pressure) / 100, 0) : s.roundPrecision(o == null ? void 0 : o.pressure, 0),
212
+ speed: o == null ? void 0 : o.speed,
213
+ kts: o == null ? void 0 : o.kts,
214
+ source: o == null ? void 0 : o.source,
215
+ level: o == null ? void 0 : o.type
216
+ });
217
+ r.features.push(n);
218
+ }
219
+ }
220
+ }
221
+ return r;
222
+ }
223
+ }
224
+ export {
225
+ s as LngLatHelper,
226
+ $ as TropicalHelper
227
+ };
@@ -0,0 +1 @@
1
+ (function(f,m){typeof exports=="object"&&typeof module<"u"?m(exports,require("moment"),require("moment-timezone"),require("tz-lookup"),require("log4js"),require("@turf/turf")):typeof define=="function"&&define.amd?define(["exports","moment","moment-timezone","tz-lookup","log4js","@turf/turf"],m):(f=typeof globalThis<"u"?globalThis:f||self,m(f["idm-plugin-rabbitmq"]={},f.moment,f["moment-timezone"],f["tz-lookup"],f.log4js,f["@turf/turf"]))})(this,function(f,m,$,S,b,N){"use strict";function g(l){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const t in l)if(t!=="default"){const o=Object.getOwnPropertyDescriptor(l,t);Object.defineProperty(e,t,o.get?o:{enumerable:!0,get:()=>l[t]})}}return e.default=l,Object.freeze(e)}const v=g(b),h=g(N);class n{static guessTimeZoneOffset(e,t){const o=S(t,e),i=m().tz(o).utcOffset();return this.roundPrecision(i/60,1)}static prettyTimeZoneOffset(e){let t=Math.floor(Math.abs(e)),o=Math.round((Math.abs(e)-t)*60);return o=o>9?o:`0${o}`,t=t>9?t:`0${t}`,e>0?`+${t}:${o}`:`-${t}:${o}`}static lng2pretty(e,t=6,o="H°M′"){e=n.convertToStdLng(e,t);let i="E";e<0&&(i="W"),e=Math.abs(e),o=o.toUpperCase();let r=e*3600,s,c,u,d,p,a;s=r%3600%60,o.indexOf("S")!==-1&&(r=r-s,c=n.padNumber(s,2,2)),u=r/60%60,o.indexOf("M")!==-1&&(o.indexOf("S")!==-1?d=n.roundPrecision(u,t).toString().padStart(2,"0"):d=n.padNumber(u,2,2),r=r-u*60),p=r/3600,o.indexOf("M")!==-1?a=n.roundPrecision(p,t).toString().padStart(3,"0"):a=n.padNumber(p,3,2);const M=`${o.replace(/S+/gi,c).replace(/M+/gi,d).replace(/H+/gi,a)}${i}`;return{direction:i,degree:n.roundPrecision(p,t),minute:n.roundPrecision(u,t),second:n.roundPrecision(s,t),pretty:M}}static lat2pretty(e,t=6,o="H°M′"){e=e%180;let i="N";e<0&&(i="S"),e=Math.abs(e),o=o.toUpperCase();let r=e*3600,s,c,u,d,p,a;s=r%3600%60,o.indexOf("S")!==-1&&(r=r-s,c=n.padNumber(s,2,2)),u=r/60%60,o.indexOf("M")!==-1&&(o.indexOf("S")!==-1?d=n.roundPrecision(u,t).toString().padStart(2,"0"):d=n.padNumber(u,2,2),r=r-u*60),p=r/3600,o.indexOf("M")!==-1?a=n.roundPrecision(p,t).toString().padStart(2,"0"):a=n.padNumber(p,2,2);const M=`${o.replace(/S+/gi,c).replace(/M+/gi,d).replace(/H+/gi,a)}${i}`;return{direction:i,degree:n.roundPrecision(p,t),minute:n.roundPrecision(u,t),second:n.roundPrecision(s,t),pretty:M}}static str2Lng(e,t=6){let o;if(isNaN(e)){e=n.strReplace(e,"LNG");const i=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const r=e.split(" ").filter(u=>u!=="").map(u=>Number(u));let[s,c]=r;if(s>360&&!c){const u=this.roundPrecision(s/100,0);c=s-u*100,s=u}o=s+(c??0)/60,i==="W"&&(o=o*-1)}else o=Number(e);return n.convertToStdLng(o,t)}static str2Lat(e,t=6){let o;if(isNaN(e)){e=n.strReplace(e,"LAT");const i=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const r=e.split(" ").filter(u=>u!=="").map(u=>Number(u));let[s,c]=r;if(s>90&&!c){const u=this.roundPrecision(s/100,0);c=s-u*100,s=u}o=s+(c??0)/60,i==="S"&&(o=o*-1)}else o=Number(e);return n.roundPrecision(o,t)}static str2LngOrLat(e,t=6,o="LAT"){e=n.strReplace(e,o);const i=e[e.length-1].toUpperCase();return["N","S"].includes(i)?{lat:n.str2Lat(e,t)}:{lng:n.str2Lng(e,t)}}static convertToStdLng(e,t=4){return e>180?(e=e%360,e=e>180?e-360:e):e<-180&&(e=e%360,e=e<-180?e+360:e),n.roundPrecision(e,t)}static roundPrecision(e,t=4){if(typeof e=="number"){const o=Number("1".padEnd(t+1,"0"));return Math.round(e*o)/o}return e}static convertToMonotonicLng2(e){for(let t=1;t<e.length;t++)e[t][0]+=Math.round((e[t-1][0]-e[t][0])/360)*360;return e}static convertToMonotonicLng(e){for(let t=1;t<e.length;t++)e[t].lng+=Math.round((e[t-1].lng-e[t].lng)/360)*360;return e}static strReplace(e,t="LAT"){e=e.replace(/([0-9]+)\.([0-9]+\.[0-9]+)/g,"$1 $2").replace(/-/g," ").replace(/°/," ").replace(/'/g," ").replace(/′/g," ").replace(/"/g," ").replace(/∼/g," ").replace(/°/g," ").replace(/,/g,".").replace(/^ /g,"").replace(/ $/g,"").trim();const o=e[e.length-1].toUpperCase();if(!["N","S","E","W"].includes(o)){const i=e,r=Number(i.split(" ")[0]);if(isNaN(r))throw new Error(`invalid Lat/Lng: ${e}`);r>=90?e=`${i}E`:r<=-90?e=`${i}W`:["LAN","LNG"].includes(t==null?void 0:t.toUpperCase())?e=`${i}${r>0?"E":"W"}`:e=`${i}${r>0?"N":"S"}`}return e}static padNumber(e,t=2,o=2){const i=Math.trunc(e).toString().padStart(t,"0"),r=Math.trunc(n.roundPrecision(e-Math.trunc(e),o)*Math.pow(10,o)).toString().padStart(o,"0");return`${i}.${r}`}}v.getLogger();class y{static convert2Geojson(e){const t=h.featureCollection([]);for(const o of e){if(o.forecasts)for(const i of o.forecasts){const r=[],s=m(i.date).utc(),c=`${o.name}-${i.model}`;for(const u in i==null?void 0:i.hours){const d=i.hours[u],p=s.clone().add(Number(u),"hour"),a=h.point([d.lng,d.lat],{date:p.format(),hour:Number(u),format:p.format("MMM-DD/HHmm[Z]"),pressure:d.pressure>1e4?n.roundPrecision(d.pressure/100,0):n.roundPrecision(d.pressure,0),gusts:d.gusts,wind:d.wind||{},movement:d.movement,category:c,type:"forecast"});t.features.push(a),r.push(a.geometry.coordinates)}if((r==null?void 0:r.length)>1){const u=h.lineString(n.convertToMonotonicLng2(r),{date:i.date,id:o.id||o.name,model:i.model,name:o.name,category:c,type:"forecast"});t.features.push(u)}}if(o.history){const i=[];for(const s of o.history){const c=m(s.updated).utc(),u=h.point([s.lng,s.lat],{date:c.format(),format:c.format("MMM-DD/HHmm[Z]"),pressure:s.pressure>1e4?n.roundPrecision(s.pressure/100,0):n.roundPrecision(s.pressure,0),speed:s.speed,kts:s.kts,source:s.source,level:s.type,type:"history",category:`${o.name}-history`});t.features.push(u),i.push(u.geometry.coordinates)}const r=o.history[0];if(i.length===1&&i.push(i[0]),i.length>1){const s=h.lineString(n.convertToMonotonicLng2(i),{name:o.name,type:"history",updated:r==null?void 0:r.updated,pressure:(r==null?void 0:r.pressure)>1e4?n.roundPrecision((r==null?void 0:r.pressure)/100,0):n.roundPrecision(r==null?void 0:r.pressure,0),speed:r==null?void 0:r.speed,kts:r==null?void 0:r.kts,source:r==null?void 0:r.source,level:r==null?void 0:r.type});t.features.push(s)}}}return t}}f.LngLatHelper=n,f.TropicalHelper=y,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,65 @@
1
+ export interface LngLatPretty {
2
+ direction: string;
3
+ degree: number;
4
+ minute: number;
5
+ second: number;
6
+ pretty: string;
7
+ }
8
+ export declare class LngLatHelper {
9
+ /**
10
+ * 基于输入的经度,计算出时区
11
+ * @param lng
12
+ * @param lat
13
+ */
14
+ static guessTimeZoneOffset(lng: number, lat: number): number;
15
+ /**
16
+ * 将时间offset转换为时区,例如:8.5 => +08:30
17
+ * @param offset => 8.5
18
+ * @return timezone => +08:30
19
+ */
20
+ static prettyTimeZoneOffset(offset: number): string;
21
+ static lng2pretty(lng: number, precision?: number, format?: string): LngLatPretty;
22
+ /**
23
+ * 纬度转化为精确数值
24
+ * @param lat 纬度
25
+ * @param precision 精确度
26
+ * @param format 格式化
27
+ */
28
+ static lat2pretty(lat: number, precision?: number, format?: string): LngLatPretty;
29
+ static str2Lng(str: string, precision?: number): number;
30
+ static str2Lat(str: string, precision?: number): number;
31
+ static str2LngOrLat(str: string, precision?: number, category?: string): {
32
+ lat: number;
33
+ lng?: undefined;
34
+ } | {
35
+ lng: number;
36
+ lat?: undefined;
37
+ };
38
+ static convertToStdLng(lng: number, precision?: number): number;
39
+ static roundPrecision(num: number, precision?: number): number;
40
+ /**
41
+ * 转换为按经度单调增/减的坐标数组
42
+ * @param coordinates [[lng, lat]]
43
+ */
44
+ static convertToMonotonicLng2(coordinates: number[][]): number[][];
45
+ /**
46
+ * 转移为按经度单调增/减的坐标数组
47
+ * @param coordinates [{lng, lat}]
48
+ */
49
+ static convertToMonotonicLng(coordinates: {
50
+ lng: number;
51
+ lat: number;
52
+ }[]): {
53
+ lng: number;
54
+ lat: number;
55
+ }[];
56
+ static strReplace(str: string, category?: string): string;
57
+ /**
58
+ * 数据格式
59
+ * 例如: 10.5003 => 010.50
60
+ * @param num
61
+ * @param intPrecision 整数位数
62
+ * @param dcmPrecision 小数位数
63
+ */
64
+ static padNumber(num: number, intPrecision?: number, dcmPrecision?: number): string;
65
+ }
@@ -0,0 +1,9 @@
1
+ import * as turf from '@turf/turf';
2
+ export declare class TropicalHelper {
3
+ static convert2Geojson(raw: {
4
+ id: string;
5
+ name: string;
6
+ forecasts: any[];
7
+ history: any[];
8
+ }[]): turf.helpers.FeatureCollection<turf.helpers.Geometry, turf.helpers.Properties>;
9
+ }
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@idm-plugin/geo",
3
+ "private": false,
4
+ "version": "1.0.0",
5
+ "description": "idm plugin for geo",
6
+ "type": "module",
7
+ "keywords": [
8
+ "idm",
9
+ "geo"
10
+ ],
11
+ "author": "chenheng@idmwx.com",
12
+ "contributors": [
13
+ "ChenHeng"
14
+ ],
15
+ "license": "GPL-3.0",
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "main": "./dist/index.umd.cjs",
20
+ "module": "./dist/index.js",
21
+ "types": "index.d.ts",
22
+ "scripts": {
23
+ "dev": "vite --config ./build/base.config.ts",
24
+ "build": "vite build --config ./build/lib.config.ts",
25
+ "lint:fix": "eslint --fix --ext .js,.ts,.",
26
+ "prettier": "yarn lint:fix && prettier --write '**/*.{js,ts}'",
27
+ "release": "yarn build && yarn publish --access public"
28
+ },
29
+ "dependencies": {
30
+ "@turf/turf": "^6.5.0",
31
+ "log4js": "^6.9.1",
32
+ "moment": "^2.30.1",
33
+ "moment-timezone": "^0.5.45",
34
+ "tz-lookup": "^6.1.25"
35
+ },
36
+ "devDependencies": {
37
+ "@types/jest": "^25.2.2",
38
+ "@types/node": "^18.14.2",
39
+ "@types/tz-lookup": "^6.1.2",
40
+ "@typescript-eslint/eslint-plugin": "^5.53.0",
41
+ "@typescript-eslint/parser": "^5.53.0",
42
+ "@vitejs/plugin-vue": "^4.2.3",
43
+ "eslint": "^8.35.0",
44
+ "eslint-config-prettier": "^8.6.0",
45
+ "eslint-define-config": "^1.15.0",
46
+ "eslint-plugin-prettier": "^4.2.1",
47
+ "jest": "^26.6.3",
48
+ "lint-staged": "^13.1.2",
49
+ "prettier": "^2.8.4",
50
+ "sass": "^1.58.3",
51
+ "simple-git-hooks": "^2.8.1",
52
+ "stylelint": "^15.2.0",
53
+ "supertest": "^4.0.2",
54
+ "ts-jest": "^26.5.3",
55
+ "ts-node-dev": "^2.0.0-0",
56
+ "tsconfig-paths": "^3.12.0",
57
+ "typescript": "^4.9.3",
58
+ "vite": "^4.1.0",
59
+ "vite-plugin-dts": "^2.0.2",
60
+ "vite-plugin-static-copy": "^0.17.0"
61
+ },
62
+ "lint-staged": {
63
+ "*.{ts,tsx,js}": "eslint --fix",
64
+ "*.{ts,tsx,js,scss}": "prettier --write"
65
+ },
66
+ "simple-git-hooks": {
67
+ "pre-commit": "yarn exec lint-staged"
68
+ }
69
+ }