@digitalwalletcorp/utils 0.10.0 → 0.11.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.
Files changed (58) hide show
  1. package/README.md +1 -0
  2. package/lib/date-time.cjs +2 -0
  3. package/lib/date-time.cjs.map +1 -0
  4. package/lib/date-time.d.cts +203 -0
  5. package/lib/date-time.d.ts +203 -0
  6. package/lib/date-time.js +289 -0
  7. package/lib/date-time.js.map +1 -0
  8. package/lib/date-util-ByW86YIS.cjs +2 -0
  9. package/lib/date-util-ByW86YIS.cjs.map +1 -0
  10. package/lib/date-util-C581gVKx.js +140 -0
  11. package/lib/date-util-C581gVKx.js.map +1 -0
  12. package/lib/date-util.cjs +1 -1
  13. package/lib/date-util.d.cts +8 -15
  14. package/lib/date-util.d.ts +8 -15
  15. package/lib/date-util.js +15 -16
  16. package/lib/html-util-BctKzfnH.js +60 -0
  17. package/lib/html-util-BctKzfnH.js.map +1 -0
  18. package/lib/html-util-ELyFVsxl.cjs +2 -0
  19. package/lib/html-util-ELyFVsxl.cjs.map +1 -0
  20. package/lib/html-util.cjs +1 -1
  21. package/lib/html-util.d.cts +5 -4
  22. package/lib/html-util.d.ts +5 -4
  23. package/lib/html-util.js +2 -2
  24. package/lib/index.cjs +1 -1
  25. package/lib/index.d.cts +1 -0
  26. package/lib/index.d.ts +1 -0
  27. package/lib/index.js +16 -14
  28. package/lib/index.js.map +1 -1
  29. package/lib/{json-util-5mq7fsX_.cjs → json-util-CKnsxu1e.cjs} +3 -3
  30. package/lib/json-util-CKnsxu1e.cjs.map +1 -0
  31. package/lib/{json-util-CF-O1b7m.js → json-util-C_Pm1BpJ.js} +6 -5
  32. package/lib/json-util-C_Pm1BpJ.js.map +1 -0
  33. package/lib/json-util.cjs +1 -1
  34. package/lib/json-util.d.cts +10 -1
  35. package/lib/json-util.d.ts +10 -1
  36. package/lib/json-util.js +1 -1
  37. package/lib/{object-util-Cc1SmN-8.cjs → object-util-BHg61ifG.cjs} +2 -2
  38. package/lib/{object-util-Cc1SmN-8.cjs.map → object-util-BHg61ifG.cjs.map} +1 -1
  39. package/lib/{object-util-BGqczDbJ.js → object-util-wOMJtGK3.js} +2 -2
  40. package/lib/{object-util-BGqczDbJ.js.map → object-util-wOMJtGK3.js.map} +1 -1
  41. package/lib/object-util.cjs +1 -1
  42. package/lib/object-util.js +2 -2
  43. package/package.json +1 -1
  44. package/src/date-time.ts +395 -0
  45. package/src/date-util.ts +29 -103
  46. package/src/html-util.ts +22 -12
  47. package/src/index.ts +1 -0
  48. package/src/json-util.ts +8 -5
  49. package/lib/date-util-DrfUsv9b.js +0 -181
  50. package/lib/date-util-DrfUsv9b.js.map +0 -1
  51. package/lib/date-util-b1Lw7Nyu.cjs +0 -2
  52. package/lib/date-util-b1Lw7Nyu.cjs.map +0 -1
  53. package/lib/html-util-CcRJtzod.js +0 -56
  54. package/lib/html-util-CcRJtzod.js.map +0 -1
  55. package/lib/html-util-ClGIpzW1.cjs +0 -2
  56. package/lib/html-util-ClGIpzW1.cjs.map +0 -1
  57. package/lib/json-util-5mq7fsX_.cjs.map +0 -1
  58. package/lib/json-util-CF-O1b7m.js.map +0 -1
package/src/html-util.ts CHANGED
@@ -57,24 +57,33 @@ const toStyleString = (value: HtmlStyleValue): string => {
57
57
  .join('; ');
58
58
  };
59
59
 
60
+ /** diffForWebの既定の文字色 */
61
+ const DIFF_STYLES = {
62
+ added: 'color: var(--dwui-color-text-diff-added, light-dark(#006400, rgb(121, 227, 121)))',
63
+ removed: 'color: var(--dwui-color-text-diff-removed, light-dark(#ff0000, rgb(222, 109, 109)))',
64
+ same: 'color: var(--dwui-color-text-diff-same, light-dark(#838383, #808080))'
65
+ };
66
+
60
67
  /**
61
- * 値をエスケープしたspanタグを返す
68
+ * 値をエスケープしたタグを返す
62
69
  *
70
+ * @param {string} tagName
63
71
  * @param {string} value
64
72
  * @param {HtmlTagOptions} [options]
73
+ * @param {string} [defaultStyle] optionsのstyleより前に出力するstyle
65
74
  * @returns {string}
66
75
  */
67
- const toSpan = (value: string, options?: HtmlTagOptions): string => {
76
+ const toElement = (tagName: string, value: string, options?: HtmlTagOptions, defaultStyle?: string): string => {
68
77
  let attributes = '';
69
78
  const className = options?.class == null ? '' : toClassString(options.class);
70
79
  if (className) {
71
80
  attributes += ` class="${escapeHtml(className)}"`;
72
81
  }
73
- const style = options?.style == null ? '' : toStyleString(options.style);
82
+ const style = [defaultStyle, options?.style == null ? '' : toStyleString(options.style)].filter(Boolean).join('; ');
74
83
  if (style) {
75
84
  attributes += ` style="${escapeHtml(style)}"`;
76
85
  }
77
- return `<span${attributes}>${escapeHtml(value)}</span>`;
86
+ return `<${tagName}${attributes}>${escapeHtml(value)}</${tagName}>`;
78
87
  };
79
88
 
80
89
  /**
@@ -127,16 +136,16 @@ export function formatJsonStringForWeb(value: any, options?: FormatJsonStringOpt
127
136
  }
128
137
 
129
138
  /**
130
- * 文字列の中で一致したワードをspanタグで囲んだHTML文字列を返す
139
+ * 文字列の中で一致したワードをmarkタグで囲んだHTML文字列を返す
131
140
  * オプションのhtmlにより、入力文字列がHTMLなのかプレーンテキストなのかを指定可能
132
141
  *
133
142
  * 例)
134
143
  * HtmlUtil.highlightWord('This is a test message', 'test', { class: 'highlight' });
135
- * → 'This is a <span class="highlight">test</span> message'
144
+ * → 'This is a <mark class="highlight">test</mark> message'
136
145
  *
137
146
  * @param {string | null | undefined} value
138
147
  * @param {string | null | undefined} word
139
- * @param {*} [options] spanタグに付与するclass, styleのほか、以下を指定できる
148
+ * @param {*} [options] markタグに付与するclass, styleのほか、以下を指定できる
140
149
  * ├ class string | string[] | Record<string, boolean>
141
150
  * ├ style string | Record<string, string | number>
142
151
  * ├ caseInsensitive boolean trueを指定した場合、大文字小文字を区別しない
@@ -165,7 +174,7 @@ export function highlightWord(
165
174
  // キャプチャグループで分割すると、奇数番目の要素が一致した部分になる
166
175
  const highlight = (text: string): string => text
167
176
  .split(regex)
168
- .map((part, i) => i % 2 === 0 ? toHtml(part) : toSpan(part, options))
177
+ .map((part, i) => i % 2 === 0 ? toHtml(part) : toElement('mark', part, options))
169
178
  .join('');
170
179
 
171
180
  if (!options?.html) {
@@ -181,7 +190,8 @@ export function highlightWord(
181
190
 
182
191
  /**
183
192
  * 文字列を1文字ずつ比較し、差分をspanタグで囲んだHTML文字列を返す
184
- * 追加・削除・一致の部分ごとに、spanタグに付与するclass, styleを指定できる
193
+ * 追加・削除・一致の部分ごとに既定の文字色を持つ。文字色はCSS変数(--dwui-color-text-diff-added / --dwui-color-text-diff-removed / --dwui-color-text-diff-same)で変更できる
194
+ * 追加・削除・一致の部分ごとに、spanタグに付与するclass, styleを指定できる。styleは既定の文字色より後に出力する
185
195
  * 入力文字列はプレーンなテキストであるとみなす
186
196
  * 出力される文字列は、diffで埋め込まれるHTMLタグ以外はHTMLエスケープされ、HTMLセーフな文字列となる
187
197
  *
@@ -204,11 +214,11 @@ export function diffForWeb(text1: string | null | undefined, text2: string | nul
204
214
  let html = '';
205
215
  for (const change of changes) {
206
216
  if (change.added) {
207
- html += toSpan(change.value, options?.added);
217
+ html += toElement('span', change.value, options?.added, DIFF_STYLES.added);
208
218
  } else if (change.removed) {
209
- html += toSpan(change.value, options?.removed);
219
+ html += toElement('span', change.value, options?.removed, DIFF_STYLES.removed);
210
220
  } else {
211
- html += toSpan(change.value, options?.same);
221
+ html += toElement('span', change.value, options?.same, DIFF_STYLES.same);
212
222
  }
213
223
  }
214
224
  return html;
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * as CryptoUtil from './crypto-util';
2
+ export { DateTime } from './date-time';
2
3
  export * as DateUtil from './date-util';
3
4
  export { Decimal } from './decimal';
4
5
  export * as FileUtil from './file-util';
package/src/json-util.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * JSON.parseのreviverが第3引数で受け取る情報
3
3
  */
4
- interface JsonReviverContext {
4
+ export interface JsonReviverContext {
5
5
  /** プリミティブ値のJSON上の表記 */
6
6
  source?: string;
7
7
  }
@@ -12,17 +12,20 @@ const INTEGER_LITERAL = /^-?\d+$/;
12
12
  * JSON文字列をパースする
13
13
  * Number.MIN_SAFE_INTEGER〜Number.MAX_SAFE_INTEGERの範囲外の整数はnumberに変換すると桁落ちするため、JSON上の表記のまま文字列で返す
14
14
  * そのため、同じ項目でも値の大きさによってnumberとstringが混在する
15
+ * reviverには、範囲外の整数を文字列にした後の値を渡す
15
16
  *
16
17
  * @param {string} source
18
+ * @param {(this: any, key: string, value: any, context?: JsonReviverContext) => any} [reviver]
17
19
  * @returns {T}
18
20
  */
19
- export function parse<T = any>(source: string): T {
20
- return JSON.parse(source, (_key: string, value: any, context?: JsonReviverContext) => {
21
+ export function parse<T = any>(source: string, reviver?: (this: any, key: string, value: any, context?: JsonReviverContext) => any): T {
22
+ return JSON.parse(source, function(this: any, key: string, value: any, context?: JsonReviverContext) {
21
23
  const literal = context?.source;
24
+ let result = value;
22
25
  if (typeof value === 'number' && !Number.isSafeInteger(value) && literal && INTEGER_LITERAL.test(literal)) {
23
- return literal;
26
+ result = literal;
24
27
  }
25
- return value;
28
+ return reviver ? reviver.call(this, key, result, context) : result;
26
29
  }) as T;
27
30
  }
28
31
 
@@ -1,181 +0,0 @@
1
- import { Duration as S, DateTime as s } from "luxon";
2
- const l = "UTC", m = "yyyy-MM-dd'T'HH:mm:ss.SSSZZ", E = 25569, A = 1440 * 60 * 1e3, D = 3600 * 1e3, g = /GMT[+-]\d{1,2}(:\d{2})?/g, y = {
3
- UTC: { standard: "UTC" },
4
- "Asia/Tokyo": { standard: "JST" },
5
- "Asia/Seoul": { standard: "KST" },
6
- "Asia/Shanghai": { standard: "CST" },
7
- "Asia/Hong_Kong": { standard: "HKT" },
8
- "Asia/Taipei": { standard: "CST" },
9
- "Asia/Singapore": { standard: "SGT" },
10
- "Asia/Manila": { standard: "PHT" },
11
- "Asia/Bangkok": { standard: "ICT" },
12
- "Asia/Ho_Chi_Minh": { standard: "ICT" },
13
- "Asia/Jakarta": { standard: "WIB" },
14
- "Asia/Kolkata": { standard: "IST" },
15
- "Asia/Dubai": { standard: "GST" },
16
- "Australia/Sydney": { standard: "AEST", daylight: "AEDT" },
17
- "Pacific/Auckland": { standard: "NZST", daylight: "NZDT" },
18
- "Europe/London": { standard: "GMT", daylight: "BST" },
19
- "Europe/Paris": { standard: "CET", daylight: "CEST" },
20
- "Europe/Berlin": { standard: "CET", daylight: "CEST" },
21
- "Europe/Madrid": { standard: "CET", daylight: "CEST" },
22
- "Europe/Rome": { standard: "CET", daylight: "CEST" },
23
- "Europe/Amsterdam": { standard: "CET", daylight: "CEST" },
24
- "America/New_York": { standard: "EST", daylight: "EDT" },
25
- "America/Toronto": { standard: "EST", daylight: "EDT" },
26
- "America/Chicago": { standard: "CST", daylight: "CDT" },
27
- "America/Denver": { standard: "MST", daylight: "MDT" },
28
- "America/Phoenix": { standard: "MST" },
29
- "America/Los_Angeles": { standard: "PST", daylight: "PDT" },
30
- "America/Vancouver": { standard: "PST", daylight: "PDT" },
31
- "America/Mexico_City": { standard: "CST" },
32
- "America/Sao_Paulo": { standard: "BRT" }
33
- }, f = (t) => {
34
- if (!t.isValid && t.invalidReason === "unsupported zone")
35
- throw new RangeError(t.invalidExplanation ?? t.invalidReason);
36
- }, i = (t, a) => {
37
- if (t == null || t === "")
38
- return null;
39
- const n = a?.inputTimezone ?? l;
40
- let r = null;
41
- if (t instanceof Date)
42
- r = s.fromJSDate(t, { zone: n });
43
- else if (typeof t == "number")
44
- r = Number.isFinite(t) ? s.fromMillis(t, { zone: n }) : null;
45
- else {
46
- const e = a?.inputFormat ? [a.inputFormat].flat() : [];
47
- for (const d of e) {
48
- const o = s.fromFormat(t, d, { zone: n });
49
- if (f(o), o.isValid) {
50
- r = o;
51
- break;
52
- }
53
- }
54
- r == null && (r = s.fromISO(t, { zone: n }));
55
- }
56
- return r == null || (f(r), !r.isValid) ? null : (a?.duration && (r = r.plus(a.duration)), a?.startOf && (r = r.startOf(a.startOf)), a?.endOf && (r = r.endOf(a.endOf)), r);
57
- }, u = (t, a, n, r) => {
58
- const e = i(t, n), d = i(a, n);
59
- return !e || !d ? !1 : r(e.valueOf(), d.valueOf());
60
- };
61
- function O(t, a) {
62
- return i(t, a)?.toJSDate() ?? null;
63
- }
64
- function T(t, a) {
65
- if (typeof t == "object" && t !== null && !(t instanceof Date))
66
- return T(/* @__PURE__ */ new Date(), t);
67
- if (t == null || t === "")
68
- return "";
69
- const n = i(t, a);
70
- if (!n)
71
- return a?.invalidText ?? "Invalid Date";
72
- const r = n.setZone(a?.outputTimezone ?? l);
73
- return f(r), a?.outputFormat ? r.toFormat(a.outputFormat) : r.toISO();
74
- }
75
- function C(t, a) {
76
- return i(t, a) != null;
77
- }
78
- function h(t, a, n) {
79
- return u(t, a, n, (r, e) => r === e);
80
- }
81
- function _(t, a, n) {
82
- return u(t, a, n, (r, e) => r < e);
83
- }
84
- function M(t, a, n) {
85
- return u(t, a, n, (r, e) => r <= e);
86
- }
87
- function I(t, a, n) {
88
- return u(t, a, n, (r, e) => e < r);
89
- }
90
- function b(t, a, n) {
91
- return u(t, a, n, (r, e) => e <= r);
92
- }
93
- function p(t, a) {
94
- const n = i(t, a)?.startOf("day");
95
- if (!n)
96
- return !1;
97
- const r = s.now().setZone(a?.inputTimezone ?? l).startOf("day");
98
- return n.valueOf() < r.valueOf();
99
- }
100
- function P(t, a) {
101
- const n = i(t, a);
102
- return n != null && n.valueOf() < Date.now();
103
- }
104
- function F(t, a, n, r) {
105
- const e = i(t, r), d = i(a, r);
106
- if (!e || !d)
107
- return NaN;
108
- const o = n.slice(0, -1);
109
- return e.startOf(o).diff(d.startOf(o), n).get(n);
110
- }
111
- function Z(t = l) {
112
- const a = s.now().setZone(t);
113
- return f(a), a.toFormat(m);
114
- }
115
- function N(t, a) {
116
- let n = (t - E) * A;
117
- return a?.offset && (n -= a.offset * D), n;
118
- }
119
- function R(t, a, n) {
120
- return S.fromObject({ [a]: t }).as(n);
121
- }
122
- function L(t, a) {
123
- const n = a === void 0 ? s.now().setZone(t) : i(a)?.setZone(t);
124
- return n == null ? !1 : (f(n), n.isInDST);
125
- }
126
- function c(t, a) {
127
- const n = { ...y, ...a?.abbreviations }[t];
128
- if (!n)
129
- return null;
130
- if (n.daylight) {
131
- const r = s.fromJSDate(a?.at ?? /* @__PURE__ */ new Date(), { zone: t });
132
- if (f(r), r.isInDST)
133
- return n.daylight;
134
- }
135
- return n.standard;
136
- }
137
- function U(t, a, n) {
138
- const r = c(a, n);
139
- return r == null ? t : t.replace(g, r);
140
- }
141
- const w = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
142
- __proto__: null,
143
- applyTimezoneAbbr: U,
144
- convertExcelDateSerialToUnixTimeSerial: N,
145
- convertTimeUnit: R,
146
- currentTimestamp: Z,
147
- diff: F,
148
- formatDate: T,
149
- getTimezoneAbbr: c,
150
- isAfter: I,
151
- isBefore: _,
152
- isInDST: L,
153
- isPastDate: p,
154
- isPastDateTime: P,
155
- isSame: h,
156
- isSameOrAfter: b,
157
- isSameOrBefore: M,
158
- isValid: C,
159
- parseDate: O
160
- }, Symbol.toStringTag, { value: "Module" }));
161
- export {
162
- U as a,
163
- R as b,
164
- N as c,
165
- w as d,
166
- Z as e,
167
- F as f,
168
- T as g,
169
- c as h,
170
- I as i,
171
- _ as j,
172
- L as k,
173
- p as l,
174
- P as m,
175
- h as n,
176
- b as o,
177
- M as p,
178
- C as q,
179
- O as r
180
- };
181
- //# sourceMappingURL=date-util-DrfUsv9b.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"date-util-DrfUsv9b.js","sources":["../src/date-util.ts"],"sourcesContent":["import { DateTime, Duration as LuxonDuration } from 'luxon';\nimport type { DateTimeUnit } from 'luxon';\n\n/** 日時として解釈する値。string はISO形式または inputFormat の書式、number は epoch ミリ秒 */\nexport type DateInput = string | Date | number | null | undefined;\n\n/** 日時の切り捨て(startOf / endOf)に使う単位 */\nexport type DateUnit = 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond';\n\n/** 期間の単位 */\nexport type TimeUnit = 'milliseconds' | 'seconds' | 'minutes' | 'hours' | 'days' | 'months' | 'years';\n\n/** 日時の加算・減算に使う期間。負の値で減算になる */\nexport interface Duration {\n years?: number;\n quarters?: number;\n months?: number;\n weeks?: number;\n days?: number;\n hours?: number;\n minutes?: number;\n seconds?: number;\n milliseconds?: number;\n}\n\n/**\n * 日時を解釈するときのオプション\n */\nexport interface ParseDateOptions {\n /** 入力の書式。配列の場合は先頭から順に試す。いずれにも一致しない場合はISO形式として解釈する */\n inputFormat?: string | string[];\n /** ゾーン情報を含まない入力をどのタイムゾーンの日時とみなすか(IANA名)。既定は 'UTC' */\n inputTimezone?: string;\n /** 解釈した日時に加算する期間。startOf / endOf より先に適用する */\n duration?: Duration;\n /** 指定した単位の最初の時点に切り捨てる(month なら月初の00:00:00.000) */\n startOf?: DateUnit;\n /** 指定した単位の最後の時点に切り上げる(month なら月末の23:59:59.999) */\n endOf?: DateUnit;\n}\n\n/**\n * 日時を文字列にするときのオプション\n */\nexport interface FormatDateOptions extends ParseDateOptions {\n /** 出力の書式。省略時はISO形式 */\n outputFormat?: string;\n /** 出力に使うタイムゾーン(IANA名)。既定は 'UTC' */\n outputTimezone?: string;\n /** 日時として解釈できない値に対する出力。既定は 'Invalid Date' */\n invalidText?: string;\n}\n\n/** タイムゾーンの略称。夏時間のないタイムゾーンでは daylight を持たない */\nexport interface TimezoneAbbreviation {\n standard: string;\n daylight?: string;\n}\n\n/** IANA名をキーにしたタイムゾーンの略称の表 */\nexport type TimezoneAbbreviations = Record<string, TimezoneAbbreviation>;\n\n/**\n * タイムゾーンの略称を解決するときのオプション\n */\nexport interface TimezoneAbbrOptions {\n /** 夏時間かどうかを判定する時点。既定は現在時刻 */\n at?: Date;\n /** 既定の表に追加・上書きする略称 */\n abbreviations?: TimezoneAbbreviations;\n}\n\nconst DEFAULT_TIMEZONE = 'UTC';\n\nconst TIMESTAMP_FORMAT = `yyyy-MM-dd'T'HH:mm:ss.SSSZZ`;\n\n/** 1970-01-01 を表すExcelの日付シリアル値 */\nconst EXCEL_EPOCH_SERIAL = 25569;\n\nconst MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;\n\nconst MILLISECONDS_PER_HOUR = 60 * 60 * 1000;\n\nconst GMT_OFFSET = /GMT[+-]\\d{1,2}(:\\d{2})?/g;\n\n/**\n * 略称の既定の表。略称は世界で一意ではないため(CST は米国中部・中国などで使われる)、このライブラリが採用する表記である\n */\nconst DEFAULT_TIMEZONE_ABBREVIATIONS: TimezoneAbbreviations = {\n 'UTC': { standard: 'UTC' },\n 'Asia/Tokyo': { standard: 'JST' },\n 'Asia/Seoul': { standard: 'KST' },\n 'Asia/Shanghai': { standard: 'CST' },\n 'Asia/Hong_Kong': { standard: 'HKT' },\n 'Asia/Taipei': { standard: 'CST' },\n 'Asia/Singapore': { standard: 'SGT' },\n 'Asia/Manila': { standard: 'PHT' },\n 'Asia/Bangkok': { standard: 'ICT' },\n 'Asia/Ho_Chi_Minh': { standard: 'ICT' },\n 'Asia/Jakarta': { standard: 'WIB' },\n 'Asia/Kolkata': { standard: 'IST' },\n 'Asia/Dubai': { standard: 'GST' },\n 'Australia/Sydney': { standard: 'AEST', daylight: 'AEDT' },\n 'Pacific/Auckland': { standard: 'NZST', daylight: 'NZDT' },\n 'Europe/London': { standard: 'GMT', daylight: 'BST' },\n 'Europe/Paris': { standard: 'CET', daylight: 'CEST' },\n 'Europe/Berlin': { standard: 'CET', daylight: 'CEST' },\n 'Europe/Madrid': { standard: 'CET', daylight: 'CEST' },\n 'Europe/Rome': { standard: 'CET', daylight: 'CEST' },\n 'Europe/Amsterdam': { standard: 'CET', daylight: 'CEST' },\n 'America/New_York': { standard: 'EST', daylight: 'EDT' },\n 'America/Toronto': { standard: 'EST', daylight: 'EDT' },\n 'America/Chicago': { standard: 'CST', daylight: 'CDT' },\n 'America/Denver': { standard: 'MST', daylight: 'MDT' },\n 'America/Phoenix': { standard: 'MST' },\n 'America/Los_Angeles': { standard: 'PST', daylight: 'PDT' },\n 'America/Vancouver': { standard: 'PST', daylight: 'PDT' },\n 'America/Mexico_City': { standard: 'CST' },\n 'America/Sao_Paulo': { standard: 'BRT' }\n};\n\n/**\n * タイムゾーンの指定が不正な場合は、日時の不正とは区別して例外にする\n */\nconst assertZone = (d: DateTime): void => {\n if (!d.isValid && d.invalidReason === 'unsupported zone') {\n throw new RangeError(d.invalidExplanation ?? d.invalidReason);\n }\n};\n\nconst toDateTime = (value: DateInput, options?: ParseDateOptions): DateTime | null => {\n if (value == null || value === '') {\n return null;\n }\n const zone = options?.inputTimezone ?? DEFAULT_TIMEZONE;\n let d: DateTime | null = null;\n if (value instanceof Date) {\n d = DateTime.fromJSDate(value, { zone: zone });\n } else if (typeof value === 'number') {\n d = Number.isFinite(value) ? DateTime.fromMillis(value, { zone: zone }) : null;\n } else {\n const formats = options?.inputFormat ? [options.inputFormat].flat() : [];\n for (const format of formats) {\n const parsed = DateTime.fromFormat(value, format, { zone: zone });\n assertZone(parsed);\n if (parsed.isValid) {\n d = parsed;\n break;\n }\n }\n if (d == null) {\n d = DateTime.fromISO(value, { zone: zone });\n }\n }\n if (d == null) {\n return null;\n }\n assertZone(d);\n if (!d.isValid) {\n return null;\n }\n if (options?.duration) {\n d = d.plus(options.duration);\n }\n if (options?.startOf) {\n d = d.startOf(options.startOf);\n }\n if (options?.endOf) {\n d = d.endOf(options.endOf);\n }\n return d;\n};\n\nconst compare = (date1: DateInput, date2: DateInput, options: ParseDateOptions | undefined, predicate: (v1: number, v2: number) => boolean): boolean => {\n const d1 = toDateTime(date1, options);\n const d2 = toDateTime(date2, options);\n if (!d1 || !d2) {\n return false;\n }\n return predicate(d1.valueOf(), d2.valueOf());\n};\n\n/**\n * 値を日時として解釈し、Date を返す\n * duration / startOf / endOf は inputTimezone のゾーンで計算する\n * 解釈できない値、null / undefined / 空文字は null を返す。タイムゾーンの指定が不正な場合は RangeError をスローする\n *\n * @param {DateInput} value\n * @param {ParseDateOptions} [options]\n * @returns {Date | null}\n */\nexport function parseDate(value: DateInput, options?: ParseDateOptions): Date | null {\n return toDateTime(value, options)?.toJSDate() ?? null;\n}\n\n/**\n * 値を日時として解釈し、outputTimezone での文字列にする\n * value を省略して options だけを渡した場合は現在時刻を整形する\n * null / undefined / 空文字は空文字を返す。解釈できない値は 'Invalid Date' を返す\n * タイムゾーンの指定が不正な場合は RangeError をスローする\n *\n * @param {DateInput} value\n * @param {FormatDateOptions} [options]\n * @returns {string}\n */\nexport function formatDate(options: FormatDateOptions): string;\nexport function formatDate(value: DateInput, options?: FormatDateOptions): string;\nexport function formatDate(value: DateInput | FormatDateOptions, options?: FormatDateOptions): string {\n if (typeof value === 'object' && value !== null && !(value instanceof Date)) {\n return formatDate(new Date(), value);\n }\n if (value == null || value === '') {\n return '';\n }\n const d = toDateTime(value, options);\n if (!d) {\n return options?.invalidText ?? 'Invalid Date';\n }\n const output = d.setZone(options?.outputTimezone ?? DEFAULT_TIMEZONE);\n assertZone(output);\n return options?.outputFormat ? output.toFormat(options.outputFormat) : output.toISO() as string;\n}\n\n/**\n * 値が日時として解釈できるか判定する\n *\n * @param {DateInput} value\n * @param {ParseDateOptions} [options]\n * @returns {boolean}\n */\nexport function isValid(value: DateInput, options?: ParseDateOptions): boolean {\n return toDateTime(value, options) != null;\n}\n\n/**\n * date1 と date2 が同じ時刻か判定する。どちらかが解釈できない場合は false\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {boolean}\n */\nexport function isSame(date1: DateInput, date2: DateInput, options?: ParseDateOptions): boolean {\n return compare(date1, date2, options, (v1, v2) => v1 === v2);\n}\n\n/**\n * date1 が date2 より前の時刻か判定する。どちらかが解釈できない場合は false\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {boolean}\n */\nexport function isBefore(date1: DateInput, date2: DateInput, options?: ParseDateOptions): boolean {\n return compare(date1, date2, options, (v1, v2) => v1 < v2);\n}\n\n/**\n * date1 が date2 と同じか、より前の時刻か判定する。どちらかが解釈できない場合は false\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {boolean}\n */\nexport function isSameOrBefore(date1: DateInput, date2: DateInput, options?: ParseDateOptions): boolean {\n return compare(date1, date2, options, (v1, v2) => v1 <= v2);\n}\n\n/**\n * date1 が date2 より後の時刻か判定する。どちらかが解釈できない場合は false\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {boolean}\n */\nexport function isAfter(date1: DateInput, date2: DateInput, options?: ParseDateOptions): boolean {\n return compare(date1, date2, options, (v1, v2) => v2 < v1);\n}\n\n/**\n * date1 が date2 と同じか、より後の時刻か判定する。どちらかが解釈できない場合は false\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {boolean}\n */\nexport function isSameOrAfter(date1: DateInput, date2: DateInput, options?: ParseDateOptions): boolean {\n return compare(date1, date2, options, (v1, v2) => v2 <= v1);\n}\n\n/**\n * 値が inputTimezone での今日より前の日付か判定する。解釈できない場合は false\n *\n * @param {DateInput} value\n * @param {ParseDateOptions} [options]\n * @returns {boolean}\n */\nexport function isPastDate(value: DateInput, options?: ParseDateOptions): boolean {\n const target = toDateTime(value, options)?.startOf('day');\n if (!target) {\n return false;\n }\n const today = DateTime.now().setZone(options?.inputTimezone ?? DEFAULT_TIMEZONE).startOf('day');\n return target.valueOf() < today.valueOf();\n}\n\n/**\n * 値が現在時刻より前か判定する。解釈できない場合は false\n *\n * @param {DateInput} value\n * @param {ParseDateOptions} [options]\n * @returns {boolean}\n */\nexport function isPastDateTime(value: DateInput, options?: ParseDateOptions): boolean {\n const target = toDateTime(value, options);\n return target != null && target.valueOf() < Date.now();\n}\n\n/**\n * date1 − date2 を unit の単位で返す\n * 両方を inputTimezone で unit の始まりに切り捨ててから差を取るため、暦の上での差になる(23:00 と翌 01:00 の days は 1)\n * どちらかが解釈できない場合は NaN を返す\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {TimeUnit} unit\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {number}\n */\nexport function diff(date1: DateInput, date2: DateInput, unit: TimeUnit, options?: ParseDateOptions): number {\n const d1 = toDateTime(date1, options);\n const d2 = toDateTime(date2, options);\n if (!d1 || !d2) {\n return NaN;\n }\n // 'days' → 'day' のように切り捨ての単位にする\n const dateUnit = unit.slice(0, -1) as DateTimeUnit;\n return d1.startOf(dateUnit).diff(d2.startOf(dateUnit), unit).get(unit);\n}\n\n/**\n * 現在時刻を timezone での 'yyyy-MM-ddTHH:mm:ss.SSS+HH:mm' 形式の文字列で返す\n *\n * @param {string} [timezone] IANA名。既定は 'UTC'\n * @returns {string}\n */\nexport function currentTimestamp(timezone: string = DEFAULT_TIMEZONE): string {\n const d = DateTime.now().setZone(timezone);\n assertZone(d);\n return d.toFormat(TIMESTAMP_FORMAT);\n}\n\n/**\n * Excelの日付シリアル値を epoch ミリ秒に変換する\n * Excelの日付シリアル値はゾーンの概念を持たないため、そのままではUTCの日時として変換される\n * シリアル値がどのゾーンの日時かが分かっている場合は offset に時間差を指定する\n *\n * @example\n * convertExcelDateSerialToUnixTimeSerial(45200); // 1696118400000 (2023-10-01T00:00:00Z)\n * convertExcelDateSerialToUnixTimeSerial(45200, { offset: 9 }); // 1696086000000 (2023-10-01T00:00:00+09:00)\n *\n * @param {number} excelDateSerial\n * @param {*} [options]\n * └ offset シリアル値のゾーンのUTCからの時間差(時)\n * @returns {number}\n */\nexport function convertExcelDateSerialToUnixTimeSerial(excelDateSerial: number, options?: {\n offset: number;\n}): number {\n let timeserial = (excelDateSerial - EXCEL_EPOCH_SERIAL) * MILLISECONDS_PER_DAY;\n if (options?.offset) {\n timeserial -= options.offset * MILLISECONDS_PER_HOUR;\n }\n return timeserial;\n}\n\n/**\n * 期間の値を別の単位に換算する\n * 月と年は固定長(1か月 = 30日、1年 = 365日)として換算する\n *\n * @example\n * convertTimeUnit(1, 'hours', 'milliseconds'); // 3600000\n *\n * @param {number} value\n * @param {TimeUnit} inputUnit\n * @param {TimeUnit} outputUnit\n * @returns {number}\n */\nexport function convertTimeUnit(value: number, inputUnit: TimeUnit, outputUnit: TimeUnit): number {\n return LuxonDuration.fromObject({ [inputUnit]: value }).as(outputUnit);\n}\n\n/**\n * timezone が at の時点で夏時間かどうかを返す\n * at を省略した場合は現在時刻で判定する。at が解釈できない場合は false を返す\n * タイムゾーンの指定が不正な場合は RangeError をスローする\n *\n * @param {string} timezone IANA名\n * @param {DateInput} [at] 判定する時点\n * @returns {boolean}\n */\nexport function isInDST(timezone: string, at?: DateInput): boolean {\n const d = at === undefined ? DateTime.now().setZone(timezone) : toDateTime(at)?.setZone(timezone);\n if (d == null) {\n return false;\n }\n assertZone(d);\n return d.isInDST;\n}\n\n/**\n * タイムゾーンの略称を返す。夏時間の期間中は夏時間の略称を返す\n * 既定の表にない場合は null を返す。表は options.abbreviations で追加・上書きできる\n *\n * @param {string} timezone IANA名\n * @param {TimezoneAbbrOptions} [options]\n * @returns {string | null}\n */\nexport function getTimezoneAbbr(timezone: string, options?: TimezoneAbbrOptions): string | null {\n const definition = { ...DEFAULT_TIMEZONE_ABBREVIATIONS, ...options?.abbreviations }[timezone];\n if (!definition) {\n return null;\n }\n if (definition.daylight) {\n const d = DateTime.fromJSDate(options?.at ?? new Date(), { zone: timezone });\n assertZone(d);\n if (d.isInDST) {\n return definition.daylight;\n }\n }\n return definition.standard;\n}\n\n/**\n * 文字列中の 'GMT+9' のようなオフセット表記を、timezone の略称に置き換える\n * 略称が解決できない場合は文字列をそのまま返す\n *\n * @param {string} text\n * @param {string} timezone IANA名\n * @param {TimezoneAbbrOptions} [options]\n * @returns {string}\n */\nexport function applyTimezoneAbbr(text: string, timezone: string, options?: TimezoneAbbrOptions): string {\n const abbr = getTimezoneAbbr(timezone, options);\n return abbr == null ? text : text.replace(GMT_OFFSET, abbr);\n}\n"],"names":["DEFAULT_TIMEZONE","TIMESTAMP_FORMAT","EXCEL_EPOCH_SERIAL","MILLISECONDS_PER_DAY","MILLISECONDS_PER_HOUR","GMT_OFFSET","DEFAULT_TIMEZONE_ABBREVIATIONS","assertZone","d","toDateTime","value","options","zone","DateTime","formats","format","parsed","compare","date1","date2","predicate","d1","d2","parseDate","formatDate","output","isValid","isSame","v1","v2","isBefore","isSameOrBefore","isAfter","isSameOrAfter","isPastDate","target","today","isPastDateTime","diff","unit","dateUnit","currentTimestamp","timezone","convertExcelDateSerialToUnixTimeSerial","excelDateSerial","timeserial","convertTimeUnit","inputUnit","outputUnit","LuxonDuration","isInDST","at","getTimezoneAbbr","definition","applyTimezoneAbbr","text","abbr"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";const s=require("luxon"),T="UTC",P="yyyy-MM-dd'T'HH:mm:ss.SSSZZ",F=25569,U=1440*60*1e3,Z=3600*1e3,B=/GMT[+-]\d{1,2}(:\d{2})?/g,N={UTC:{standard:"UTC"},"Asia/Tokyo":{standard:"JST"},"Asia/Seoul":{standard:"KST"},"Asia/Shanghai":{standard:"CST"},"Asia/Hong_Kong":{standard:"HKT"},"Asia/Taipei":{standard:"CST"},"Asia/Singapore":{standard:"SGT"},"Asia/Manila":{standard:"PHT"},"Asia/Bangkok":{standard:"ICT"},"Asia/Ho_Chi_Minh":{standard:"ICT"},"Asia/Jakarta":{standard:"WIB"},"Asia/Kolkata":{standard:"IST"},"Asia/Dubai":{standard:"GST"},"Australia/Sydney":{standard:"AEST",daylight:"AEDT"},"Pacific/Auckland":{standard:"NZST",daylight:"NZDT"},"Europe/London":{standard:"GMT",daylight:"BST"},"Europe/Paris":{standard:"CET",daylight:"CEST"},"Europe/Berlin":{standard:"CET",daylight:"CEST"},"Europe/Madrid":{standard:"CET",daylight:"CEST"},"Europe/Rome":{standard:"CET",daylight:"CEST"},"Europe/Amsterdam":{standard:"CET",daylight:"CEST"},"America/New_York":{standard:"EST",daylight:"EDT"},"America/Toronto":{standard:"EST",daylight:"EDT"},"America/Chicago":{standard:"CST",daylight:"CDT"},"America/Denver":{standard:"MST",daylight:"MDT"},"America/Phoenix":{standard:"MST"},"America/Los_Angeles":{standard:"PST",daylight:"PDT"},"America/Vancouver":{standard:"PST",daylight:"PDT"},"America/Mexico_City":{standard:"CST"},"America/Sao_Paulo":{standard:"BRT"}},f=t=>{if(!t.isValid&&t.invalidReason==="unsupported zone")throw new RangeError(t.invalidExplanation??t.invalidReason)},i=(t,a)=>{if(t==null||t==="")return null;const e=a?.inputTimezone??T;let n=null;if(t instanceof Date)n=s.DateTime.fromJSDate(t,{zone:e});else if(typeof t=="number")n=Number.isFinite(t)?s.DateTime.fromMillis(t,{zone:e}):null;else{const r=a?.inputFormat?[a.inputFormat].flat():[];for(const o of r){const d=s.DateTime.fromFormat(t,o,{zone:e});if(f(d),d.isValid){n=d;break}}n==null&&(n=s.DateTime.fromISO(t,{zone:e}))}return n==null||(f(n),!n.isValid)?null:(a?.duration&&(n=n.plus(a.duration)),a?.startOf&&(n=n.startOf(a.startOf)),a?.endOf&&(n=n.endOf(a.endOf)),n)},u=(t,a,e,n)=>{const r=i(t,e),o=i(a,e);return!r||!o?!1:n(r.valueOf(),o.valueOf())};function m(t,a){return i(t,a)?.toJSDate()??null}function l(t,a){if(typeof t=="object"&&t!==null&&!(t instanceof Date))return l(new Date,t);if(t==null||t==="")return"";const e=i(t,a);if(!e)return a?.invalidText??"Invalid Date";const n=e.setZone(a?.outputTimezone??T);return f(n),a?.outputFormat?n.toFormat(a.outputFormat):n.toISO()}function S(t,a){return i(t,a)!=null}function D(t,a,e){return u(t,a,e,(n,r)=>n===r)}function A(t,a,e){return u(t,a,e,(n,r)=>n<r)}function E(t,a,e){return u(t,a,e,(n,r)=>n<=r)}function y(t,a,e){return u(t,a,e,(n,r)=>r<n)}function O(t,a,e){return u(t,a,e,(n,r)=>r<=n)}function g(t,a){const e=i(t,a)?.startOf("day");if(!e)return!1;const n=s.DateTime.now().setZone(a?.inputTimezone??T).startOf("day");return e.valueOf()<n.valueOf()}function C(t,a){const e=i(t,a);return e!=null&&e.valueOf()<Date.now()}function h(t,a,e,n){const r=i(t,n),o=i(a,n);if(!r||!o)return NaN;const d=e.slice(0,-1);return r.startOf(d).diff(o.startOf(d),e).get(e)}function _(t=T){const a=s.DateTime.now().setZone(t);return f(a),a.toFormat(P)}function b(t,a){let e=(t-F)*U;return a?.offset&&(e-=a.offset*Z),e}function I(t,a,e){return s.Duration.fromObject({[a]:t}).as(e)}function M(t,a){const e=a===void 0?s.DateTime.now().setZone(t):i(a)?.setZone(t);return e==null?!1:(f(e),e.isInDST)}function c(t,a){const e={...N,...a?.abbreviations}[t];if(!e)return null;if(e.daylight){const n=s.DateTime.fromJSDate(a?.at??new Date,{zone:t});if(f(n),n.isInDST)return e.daylight}return e.standard}function p(t,a,e){const n=c(a,e);return n==null?t:t.replace(B,n)}const R=Object.freeze(Object.defineProperty({__proto__:null,applyTimezoneAbbr:p,convertExcelDateSerialToUnixTimeSerial:b,convertTimeUnit:I,currentTimestamp:_,diff:h,formatDate:l,getTimezoneAbbr:c,isAfter:y,isBefore:A,isInDST:M,isPastDate:g,isPastDateTime:C,isSame:D,isSameOrAfter:O,isSameOrBefore:E,isValid:S,parseDate:m},Symbol.toStringTag,{value:"Module"}));exports.applyTimezoneAbbr=p;exports.convertExcelDateSerialToUnixTimeSerial=b;exports.convertTimeUnit=I;exports.currentTimestamp=_;exports.dateUtil=R;exports.diff=h;exports.formatDate=l;exports.getTimezoneAbbr=c;exports.isAfter=y;exports.isBefore=A;exports.isInDST=M;exports.isPastDate=g;exports.isPastDateTime=C;exports.isSame=D;exports.isSameOrAfter=O;exports.isSameOrBefore=E;exports.isValid=S;exports.parseDate=m;
2
- //# sourceMappingURL=date-util-b1Lw7Nyu.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"date-util-b1Lw7Nyu.cjs","sources":["../src/date-util.ts"],"sourcesContent":["import { DateTime, Duration as LuxonDuration } from 'luxon';\nimport type { DateTimeUnit } from 'luxon';\n\n/** 日時として解釈する値。string はISO形式または inputFormat の書式、number は epoch ミリ秒 */\nexport type DateInput = string | Date | number | null | undefined;\n\n/** 日時の切り捨て(startOf / endOf)に使う単位 */\nexport type DateUnit = 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond';\n\n/** 期間の単位 */\nexport type TimeUnit = 'milliseconds' | 'seconds' | 'minutes' | 'hours' | 'days' | 'months' | 'years';\n\n/** 日時の加算・減算に使う期間。負の値で減算になる */\nexport interface Duration {\n years?: number;\n quarters?: number;\n months?: number;\n weeks?: number;\n days?: number;\n hours?: number;\n minutes?: number;\n seconds?: number;\n milliseconds?: number;\n}\n\n/**\n * 日時を解釈するときのオプション\n */\nexport interface ParseDateOptions {\n /** 入力の書式。配列の場合は先頭から順に試す。いずれにも一致しない場合はISO形式として解釈する */\n inputFormat?: string | string[];\n /** ゾーン情報を含まない入力をどのタイムゾーンの日時とみなすか(IANA名)。既定は 'UTC' */\n inputTimezone?: string;\n /** 解釈した日時に加算する期間。startOf / endOf より先に適用する */\n duration?: Duration;\n /** 指定した単位の最初の時点に切り捨てる(month なら月初の00:00:00.000) */\n startOf?: DateUnit;\n /** 指定した単位の最後の時点に切り上げる(month なら月末の23:59:59.999) */\n endOf?: DateUnit;\n}\n\n/**\n * 日時を文字列にするときのオプション\n */\nexport interface FormatDateOptions extends ParseDateOptions {\n /** 出力の書式。省略時はISO形式 */\n outputFormat?: string;\n /** 出力に使うタイムゾーン(IANA名)。既定は 'UTC' */\n outputTimezone?: string;\n /** 日時として解釈できない値に対する出力。既定は 'Invalid Date' */\n invalidText?: string;\n}\n\n/** タイムゾーンの略称。夏時間のないタイムゾーンでは daylight を持たない */\nexport interface TimezoneAbbreviation {\n standard: string;\n daylight?: string;\n}\n\n/** IANA名をキーにしたタイムゾーンの略称の表 */\nexport type TimezoneAbbreviations = Record<string, TimezoneAbbreviation>;\n\n/**\n * タイムゾーンの略称を解決するときのオプション\n */\nexport interface TimezoneAbbrOptions {\n /** 夏時間かどうかを判定する時点。既定は現在時刻 */\n at?: Date;\n /** 既定の表に追加・上書きする略称 */\n abbreviations?: TimezoneAbbreviations;\n}\n\nconst DEFAULT_TIMEZONE = 'UTC';\n\nconst TIMESTAMP_FORMAT = `yyyy-MM-dd'T'HH:mm:ss.SSSZZ`;\n\n/** 1970-01-01 を表すExcelの日付シリアル値 */\nconst EXCEL_EPOCH_SERIAL = 25569;\n\nconst MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;\n\nconst MILLISECONDS_PER_HOUR = 60 * 60 * 1000;\n\nconst GMT_OFFSET = /GMT[+-]\\d{1,2}(:\\d{2})?/g;\n\n/**\n * 略称の既定の表。略称は世界で一意ではないため(CST は米国中部・中国などで使われる)、このライブラリが採用する表記である\n */\nconst DEFAULT_TIMEZONE_ABBREVIATIONS: TimezoneAbbreviations = {\n 'UTC': { standard: 'UTC' },\n 'Asia/Tokyo': { standard: 'JST' },\n 'Asia/Seoul': { standard: 'KST' },\n 'Asia/Shanghai': { standard: 'CST' },\n 'Asia/Hong_Kong': { standard: 'HKT' },\n 'Asia/Taipei': { standard: 'CST' },\n 'Asia/Singapore': { standard: 'SGT' },\n 'Asia/Manila': { standard: 'PHT' },\n 'Asia/Bangkok': { standard: 'ICT' },\n 'Asia/Ho_Chi_Minh': { standard: 'ICT' },\n 'Asia/Jakarta': { standard: 'WIB' },\n 'Asia/Kolkata': { standard: 'IST' },\n 'Asia/Dubai': { standard: 'GST' },\n 'Australia/Sydney': { standard: 'AEST', daylight: 'AEDT' },\n 'Pacific/Auckland': { standard: 'NZST', daylight: 'NZDT' },\n 'Europe/London': { standard: 'GMT', daylight: 'BST' },\n 'Europe/Paris': { standard: 'CET', daylight: 'CEST' },\n 'Europe/Berlin': { standard: 'CET', daylight: 'CEST' },\n 'Europe/Madrid': { standard: 'CET', daylight: 'CEST' },\n 'Europe/Rome': { standard: 'CET', daylight: 'CEST' },\n 'Europe/Amsterdam': { standard: 'CET', daylight: 'CEST' },\n 'America/New_York': { standard: 'EST', daylight: 'EDT' },\n 'America/Toronto': { standard: 'EST', daylight: 'EDT' },\n 'America/Chicago': { standard: 'CST', daylight: 'CDT' },\n 'America/Denver': { standard: 'MST', daylight: 'MDT' },\n 'America/Phoenix': { standard: 'MST' },\n 'America/Los_Angeles': { standard: 'PST', daylight: 'PDT' },\n 'America/Vancouver': { standard: 'PST', daylight: 'PDT' },\n 'America/Mexico_City': { standard: 'CST' },\n 'America/Sao_Paulo': { standard: 'BRT' }\n};\n\n/**\n * タイムゾーンの指定が不正な場合は、日時の不正とは区別して例外にする\n */\nconst assertZone = (d: DateTime): void => {\n if (!d.isValid && d.invalidReason === 'unsupported zone') {\n throw new RangeError(d.invalidExplanation ?? d.invalidReason);\n }\n};\n\nconst toDateTime = (value: DateInput, options?: ParseDateOptions): DateTime | null => {\n if (value == null || value === '') {\n return null;\n }\n const zone = options?.inputTimezone ?? DEFAULT_TIMEZONE;\n let d: DateTime | null = null;\n if (value instanceof Date) {\n d = DateTime.fromJSDate(value, { zone: zone });\n } else if (typeof value === 'number') {\n d = Number.isFinite(value) ? DateTime.fromMillis(value, { zone: zone }) : null;\n } else {\n const formats = options?.inputFormat ? [options.inputFormat].flat() : [];\n for (const format of formats) {\n const parsed = DateTime.fromFormat(value, format, { zone: zone });\n assertZone(parsed);\n if (parsed.isValid) {\n d = parsed;\n break;\n }\n }\n if (d == null) {\n d = DateTime.fromISO(value, { zone: zone });\n }\n }\n if (d == null) {\n return null;\n }\n assertZone(d);\n if (!d.isValid) {\n return null;\n }\n if (options?.duration) {\n d = d.plus(options.duration);\n }\n if (options?.startOf) {\n d = d.startOf(options.startOf);\n }\n if (options?.endOf) {\n d = d.endOf(options.endOf);\n }\n return d;\n};\n\nconst compare = (date1: DateInput, date2: DateInput, options: ParseDateOptions | undefined, predicate: (v1: number, v2: number) => boolean): boolean => {\n const d1 = toDateTime(date1, options);\n const d2 = toDateTime(date2, options);\n if (!d1 || !d2) {\n return false;\n }\n return predicate(d1.valueOf(), d2.valueOf());\n};\n\n/**\n * 値を日時として解釈し、Date を返す\n * duration / startOf / endOf は inputTimezone のゾーンで計算する\n * 解釈できない値、null / undefined / 空文字は null を返す。タイムゾーンの指定が不正な場合は RangeError をスローする\n *\n * @param {DateInput} value\n * @param {ParseDateOptions} [options]\n * @returns {Date | null}\n */\nexport function parseDate(value: DateInput, options?: ParseDateOptions): Date | null {\n return toDateTime(value, options)?.toJSDate() ?? null;\n}\n\n/**\n * 値を日時として解釈し、outputTimezone での文字列にする\n * value を省略して options だけを渡した場合は現在時刻を整形する\n * null / undefined / 空文字は空文字を返す。解釈できない値は 'Invalid Date' を返す\n * タイムゾーンの指定が不正な場合は RangeError をスローする\n *\n * @param {DateInput} value\n * @param {FormatDateOptions} [options]\n * @returns {string}\n */\nexport function formatDate(options: FormatDateOptions): string;\nexport function formatDate(value: DateInput, options?: FormatDateOptions): string;\nexport function formatDate(value: DateInput | FormatDateOptions, options?: FormatDateOptions): string {\n if (typeof value === 'object' && value !== null && !(value instanceof Date)) {\n return formatDate(new Date(), value);\n }\n if (value == null || value === '') {\n return '';\n }\n const d = toDateTime(value, options);\n if (!d) {\n return options?.invalidText ?? 'Invalid Date';\n }\n const output = d.setZone(options?.outputTimezone ?? DEFAULT_TIMEZONE);\n assertZone(output);\n return options?.outputFormat ? output.toFormat(options.outputFormat) : output.toISO() as string;\n}\n\n/**\n * 値が日時として解釈できるか判定する\n *\n * @param {DateInput} value\n * @param {ParseDateOptions} [options]\n * @returns {boolean}\n */\nexport function isValid(value: DateInput, options?: ParseDateOptions): boolean {\n return toDateTime(value, options) != null;\n}\n\n/**\n * date1 と date2 が同じ時刻か判定する。どちらかが解釈できない場合は false\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {boolean}\n */\nexport function isSame(date1: DateInput, date2: DateInput, options?: ParseDateOptions): boolean {\n return compare(date1, date2, options, (v1, v2) => v1 === v2);\n}\n\n/**\n * date1 が date2 より前の時刻か判定する。どちらかが解釈できない場合は false\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {boolean}\n */\nexport function isBefore(date1: DateInput, date2: DateInput, options?: ParseDateOptions): boolean {\n return compare(date1, date2, options, (v1, v2) => v1 < v2);\n}\n\n/**\n * date1 が date2 と同じか、より前の時刻か判定する。どちらかが解釈できない場合は false\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {boolean}\n */\nexport function isSameOrBefore(date1: DateInput, date2: DateInput, options?: ParseDateOptions): boolean {\n return compare(date1, date2, options, (v1, v2) => v1 <= v2);\n}\n\n/**\n * date1 が date2 より後の時刻か判定する。どちらかが解釈できない場合は false\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {boolean}\n */\nexport function isAfter(date1: DateInput, date2: DateInput, options?: ParseDateOptions): boolean {\n return compare(date1, date2, options, (v1, v2) => v2 < v1);\n}\n\n/**\n * date1 が date2 と同じか、より後の時刻か判定する。どちらかが解釈できない場合は false\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {boolean}\n */\nexport function isSameOrAfter(date1: DateInput, date2: DateInput, options?: ParseDateOptions): boolean {\n return compare(date1, date2, options, (v1, v2) => v2 <= v1);\n}\n\n/**\n * 値が inputTimezone での今日より前の日付か判定する。解釈できない場合は false\n *\n * @param {DateInput} value\n * @param {ParseDateOptions} [options]\n * @returns {boolean}\n */\nexport function isPastDate(value: DateInput, options?: ParseDateOptions): boolean {\n const target = toDateTime(value, options)?.startOf('day');\n if (!target) {\n return false;\n }\n const today = DateTime.now().setZone(options?.inputTimezone ?? DEFAULT_TIMEZONE).startOf('day');\n return target.valueOf() < today.valueOf();\n}\n\n/**\n * 値が現在時刻より前か判定する。解釈できない場合は false\n *\n * @param {DateInput} value\n * @param {ParseDateOptions} [options]\n * @returns {boolean}\n */\nexport function isPastDateTime(value: DateInput, options?: ParseDateOptions): boolean {\n const target = toDateTime(value, options);\n return target != null && target.valueOf() < Date.now();\n}\n\n/**\n * date1 − date2 を unit の単位で返す\n * 両方を inputTimezone で unit の始まりに切り捨ててから差を取るため、暦の上での差になる(23:00 と翌 01:00 の days は 1)\n * どちらかが解釈できない場合は NaN を返す\n *\n * @param {DateInput} date1\n * @param {DateInput} date2\n * @param {TimeUnit} unit\n * @param {ParseDateOptions} [options] 両方の値に適用する\n * @returns {number}\n */\nexport function diff(date1: DateInput, date2: DateInput, unit: TimeUnit, options?: ParseDateOptions): number {\n const d1 = toDateTime(date1, options);\n const d2 = toDateTime(date2, options);\n if (!d1 || !d2) {\n return NaN;\n }\n // 'days' → 'day' のように切り捨ての単位にする\n const dateUnit = unit.slice(0, -1) as DateTimeUnit;\n return d1.startOf(dateUnit).diff(d2.startOf(dateUnit), unit).get(unit);\n}\n\n/**\n * 現在時刻を timezone での 'yyyy-MM-ddTHH:mm:ss.SSS+HH:mm' 形式の文字列で返す\n *\n * @param {string} [timezone] IANA名。既定は 'UTC'\n * @returns {string}\n */\nexport function currentTimestamp(timezone: string = DEFAULT_TIMEZONE): string {\n const d = DateTime.now().setZone(timezone);\n assertZone(d);\n return d.toFormat(TIMESTAMP_FORMAT);\n}\n\n/**\n * Excelの日付シリアル値を epoch ミリ秒に変換する\n * Excelの日付シリアル値はゾーンの概念を持たないため、そのままではUTCの日時として変換される\n * シリアル値がどのゾーンの日時かが分かっている場合は offset に時間差を指定する\n *\n * @example\n * convertExcelDateSerialToUnixTimeSerial(45200); // 1696118400000 (2023-10-01T00:00:00Z)\n * convertExcelDateSerialToUnixTimeSerial(45200, { offset: 9 }); // 1696086000000 (2023-10-01T00:00:00+09:00)\n *\n * @param {number} excelDateSerial\n * @param {*} [options]\n * └ offset シリアル値のゾーンのUTCからの時間差(時)\n * @returns {number}\n */\nexport function convertExcelDateSerialToUnixTimeSerial(excelDateSerial: number, options?: {\n offset: number;\n}): number {\n let timeserial = (excelDateSerial - EXCEL_EPOCH_SERIAL) * MILLISECONDS_PER_DAY;\n if (options?.offset) {\n timeserial -= options.offset * MILLISECONDS_PER_HOUR;\n }\n return timeserial;\n}\n\n/**\n * 期間の値を別の単位に換算する\n * 月と年は固定長(1か月 = 30日、1年 = 365日)として換算する\n *\n * @example\n * convertTimeUnit(1, 'hours', 'milliseconds'); // 3600000\n *\n * @param {number} value\n * @param {TimeUnit} inputUnit\n * @param {TimeUnit} outputUnit\n * @returns {number}\n */\nexport function convertTimeUnit(value: number, inputUnit: TimeUnit, outputUnit: TimeUnit): number {\n return LuxonDuration.fromObject({ [inputUnit]: value }).as(outputUnit);\n}\n\n/**\n * timezone が at の時点で夏時間かどうかを返す\n * at を省略した場合は現在時刻で判定する。at が解釈できない場合は false を返す\n * タイムゾーンの指定が不正な場合は RangeError をスローする\n *\n * @param {string} timezone IANA名\n * @param {DateInput} [at] 判定する時点\n * @returns {boolean}\n */\nexport function isInDST(timezone: string, at?: DateInput): boolean {\n const d = at === undefined ? DateTime.now().setZone(timezone) : toDateTime(at)?.setZone(timezone);\n if (d == null) {\n return false;\n }\n assertZone(d);\n return d.isInDST;\n}\n\n/**\n * タイムゾーンの略称を返す。夏時間の期間中は夏時間の略称を返す\n * 既定の表にない場合は null を返す。表は options.abbreviations で追加・上書きできる\n *\n * @param {string} timezone IANA名\n * @param {TimezoneAbbrOptions} [options]\n * @returns {string | null}\n */\nexport function getTimezoneAbbr(timezone: string, options?: TimezoneAbbrOptions): string | null {\n const definition = { ...DEFAULT_TIMEZONE_ABBREVIATIONS, ...options?.abbreviations }[timezone];\n if (!definition) {\n return null;\n }\n if (definition.daylight) {\n const d = DateTime.fromJSDate(options?.at ?? new Date(), { zone: timezone });\n assertZone(d);\n if (d.isInDST) {\n return definition.daylight;\n }\n }\n return definition.standard;\n}\n\n/**\n * 文字列中の 'GMT+9' のようなオフセット表記を、timezone の略称に置き換える\n * 略称が解決できない場合は文字列をそのまま返す\n *\n * @param {string} text\n * @param {string} timezone IANA名\n * @param {TimezoneAbbrOptions} [options]\n * @returns {string}\n */\nexport function applyTimezoneAbbr(text: string, timezone: string, options?: TimezoneAbbrOptions): string {\n const abbr = getTimezoneAbbr(timezone, options);\n return abbr == null ? text : text.replace(GMT_OFFSET, abbr);\n}\n"],"names":["DEFAULT_TIMEZONE","TIMESTAMP_FORMAT","EXCEL_EPOCH_SERIAL","MILLISECONDS_PER_DAY","MILLISECONDS_PER_HOUR","GMT_OFFSET","DEFAULT_TIMEZONE_ABBREVIATIONS","assertZone","d","toDateTime","value","options","zone","DateTime","formats","format","parsed","compare","date1","date2","predicate","d1","d2","parseDate","formatDate","output","isValid","isSame","v1","v2","isBefore","isSameOrBefore","isAfter","isSameOrAfter","isPastDate","target","today","isPastDateTime","diff","unit","dateUnit","currentTimestamp","timezone","convertExcelDateSerialToUnixTimeSerial","excelDateSerial","timeserial","convertTimeUnit","inputUnit","outputUnit","LuxonDuration","isInDST","at","getTimezoneAbbr","definition","applyTimezoneAbbr","text","abbr"],"mappings":"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"}
@@ -1,56 +0,0 @@
1
- import { diffChars as u } from "diff";
2
- import { f as h } from "./json-util-CF-O1b7m.js";
3
- const g = /(<!--[\s\S]*?-->|<[^>]*>|&(?:#\d+|#x[\da-f]+|\w+);)/i, d = {
4
- '"': "&quot;",
5
- "&": "&amp;",
6
- "'": "&#39;",
7
- "<": "&lt;",
8
- ">": "&gt;"
9
- }, a = (t) => t.replace(/["&'<>]/g, (r) => d[r]), b = (t) => typeof t == "string" ? t : Array.isArray(t) ? t.filter(Boolean).join(" ") : Object.keys(t).filter((r) => t[r]).join(" "), S = (t) => typeof t == "string" ? t : Object.entries(t).map(([r, e]) => `${r.startsWith("--") ? r : r.replace(/[A-Z]/g, (n) => `-${n.toLowerCase()}`)}: ${e}`).join("; "), c = (t, r) => {
10
- let e = "";
11
- const s = r?.class == null ? "" : b(r.class);
12
- s && (e += ` class="${a(s)}"`);
13
- const n = r?.style == null ? "" : S(r.style);
14
- return n && (e += ` style="${a(n)}"`), `<span${e}>${a(t)}</span>`;
15
- };
16
- function p(t, r) {
17
- if (!t)
18
- return "";
19
- const e = (s) => s.replace(/\r\n|\r|\n/g, "<br>").replace(/\t/g, "&nbsp;&nbsp;").replace(/ /g, "&nbsp;");
20
- return r?.html ? t.split(g).map((s, n) => n % 2 === 1 ? s : e(s)).join("") : e(a(t));
21
- }
22
- function y(t, r) {
23
- const { html: e, ...s } = r ?? {}, n = h(t, s);
24
- return n == null ? "" : p(String(n), { html: e });
25
- }
26
- function j(t, r, e) {
27
- if (!t)
28
- return "";
29
- const s = (i) => e?.html ? i : a(i);
30
- if (!r)
31
- return s(t);
32
- const n = r.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d"), o = new RegExp(`(${n})`, e?.caseInsensitive ? "i" : ""), f = (i) => i.split(o).map((l, m) => m % 2 === 0 ? s(l) : c(l, e)).join("");
33
- return e?.html ? t.split(g).map((i, l) => l % 2 === 1 ? i : f(i)).join("") : f(t);
34
- }
35
- function $(t, r, e) {
36
- const s = u(t ?? "", r ?? "", { ignoreCase: e?.ignoreCase });
37
- let n = "";
38
- for (const o of s)
39
- o.added ? n += c(o.value, e?.added) : o.removed ? n += c(o.value, e?.removed) : n += c(o.value, e?.same);
40
- return n;
41
- }
42
- const O = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
43
- __proto__: null,
44
- diffForWeb: $,
45
- formatJsonStringForWeb: y,
46
- formatStringForWeb: p,
47
- highlightWord: j
48
- }, Symbol.toStringTag, { value: "Module" }));
49
- export {
50
- p as a,
51
- j as b,
52
- $ as d,
53
- y as f,
54
- O as h
55
- };
56
- //# sourceMappingURL=html-util-CcRJtzod.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"html-util-CcRJtzod.js","sources":["../src/html-util.ts"],"sourcesContent":["import { diffChars } from 'diff';\nimport { formatJsonString } from './json-util';\nimport type { FormatJsonStringOptions } from './json-util';\n\n/**\n * class属性に指定する値\n * 配列は要素を空白区切りで連結し、Recordは値がtrueのキーだけを連結する\n */\nexport type HtmlClassValue = string | string[] | Record<string, boolean>;\n\n/**\n * style属性に指定する値\n * Recordのキーはキャメルケースをケバブケースに変換する。数値には単位を付けない\n */\nexport type HtmlStyleValue = string | Record<string, string | number>;\n\n/**\n * 生成するタグに付与する属性\n */\nexport interface HtmlTagOptions {\n class?: HtmlClassValue;\n style?: HtmlStyleValue;\n}\n\nconst HTML_TOKEN = /(<!--[\\s\\S]*?-->|<[^>]*>|&(?:#\\d+|#x[\\da-f]+|\\w+);)/i;\n\nconst HTML_ESCAPE_CHARS: Record<string, string> = {\n '\"': '&quot;',\n '&': '&amp;',\n '\\'': '&#39;',\n '<': '&lt;',\n '>': '&gt;'\n};\n\nconst escapeHtml = (str: string): string => str.replace(/[\"&'<>]/g, (c) => HTML_ESCAPE_CHARS[c]);\n\nconst toClassString = (value: HtmlClassValue): string => {\n if (typeof value === 'string') {\n return value;\n }\n if (Array.isArray(value)) {\n return value.filter(Boolean).join(' ');\n }\n return Object.keys(value).filter(key => value[key]).join(' ');\n};\n\nconst toStyleString = (value: HtmlStyleValue): string => {\n if (typeof value === 'string') {\n return value;\n }\n return Object.entries(value)\n .map(([key, v]) => {\n // カスタムプロパティ(--xxx)は大文字小文字を区別するため変換しない\n const property = key.startsWith('--') ? key : key.replace(/[A-Z]/g, c => `-${c.toLowerCase()}`);\n return `${property}: ${v}`;\n })\n .join('; ');\n};\n\n/**\n * 値をエスケープしたspanタグを返す\n *\n * @param {string} value\n * @param {HtmlTagOptions} [options]\n * @returns {string}\n */\nconst toSpan = (value: string, options?: HtmlTagOptions): string => {\n let attributes = '';\n const className = options?.class == null ? '' : toClassString(options.class);\n if (className) {\n attributes += ` class=\"${escapeHtml(className)}\"`;\n }\n const style = options?.style == null ? '' : toStyleString(options.style);\n if (style) {\n attributes += ` style=\"${escapeHtml(style)}\"`;\n }\n return `<span${attributes}>${escapeHtml(value)}</span>`;\n};\n\n/**\n * 文字列をWEB表示用にフォーマットする\n * オプションのhtmlにより、入力文字列がHTMLなのかプレーンテキストなのかを指定可能\n *\n * @param {string | null | undefined} str\n * @param {*} [options]\n * ├ html boolean trueを指定した場合、入力された文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function formatStringForWeb(str: string | null | undefined, options?: {\n html?: boolean;\n}): string {\n if (!str) {\n return '';\n }\n\n const formatText = (text: string): string => text\n .replace(/\\r\\n|\\r|\\n/g, '<br>')\n .replace(/\\t/g, '&nbsp;&nbsp;')\n .replace(/ /g, '&nbsp;');\n\n if (options?.html) {\n // 奇数番目がタグ・コメント・文字参照。偶数番目のテキスト部分だけをフォーマットする\n return str\n .split(HTML_TOKEN)\n .map((segment, i) => i % 2 === 1 ? segment : formatText(segment))\n .join('');\n }\n\n return formatText(escapeHtml(str));\n}\n\n/**\n * 値を整形したJSON文字列にしてWEB表示用にフォーマットする\n * formatJsonStringで整形した文字列をformatStringForWebで変換する\n *\n * @param {any} value\n * @param {*} [options] formatJsonStringのオプションに以下を加えたもの\n * ├ html boolean trueを指定した場合、文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function formatJsonStringForWeb(value: any, options?: FormatJsonStringOptions & {\n html?: boolean;\n}): string {\n const { html, ...formatOptions } = options ?? {};\n const json = formatJsonString(value, formatOptions);\n return json == null ? '' : formatStringForWeb(String(json), { html });\n}\n\n/**\n * 文字列の中で一致したワードをspanタグで囲んだHTML文字列を返す\n * オプションのhtmlにより、入力文字列がHTMLなのかプレーンテキストなのかを指定可能\n *\n * 例)\n * HtmlUtil.highlightWord('This is a test message', 'test', { class: 'highlight' });\n * → 'This is a <span class=\"highlight\">test</span> message'\n *\n * @param {string | null | undefined} value\n * @param {string | null | undefined} word\n * @param {*} [options] spanタグに付与するclass, styleのほか、以下を指定できる\n * ├ class string | string[] | Record<string, boolean>\n * ├ style string | Record<string, string | number>\n * ├ caseInsensitive boolean trueを指定した場合、大文字小文字を区別しない\n * ├ html boolean trueを指定した場合、入力された文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function highlightWord(\n value: string | null | undefined,\n word: string | null | undefined,\n options?: HtmlTagOptions & {\n caseInsensitive?: boolean;\n html?: boolean;\n }\n): string {\n if (!value) {\n return '';\n }\n\n const toHtml = (text: string): string => options?.html ? text : escapeHtml(text);\n if (!word) {\n return toHtml(value);\n }\n\n const pattern = word.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&').replace(/-/g, '\\\\x2d');\n const regex = new RegExp(`(${pattern})`, options?.caseInsensitive ? 'i' : '');\n // キャプチャグループで分割すると、奇数番目の要素が一致した部分になる\n const highlight = (text: string): string => text\n .split(regex)\n .map((part, i) => i % 2 === 0 ? toHtml(part) : toSpan(part, options))\n .join('');\n\n if (!options?.html) {\n return highlight(value);\n }\n\n // 奇数番目がタグ・コメント・文字参照。偶数番目のテキスト部分だけをハイライトする\n return value\n .split(HTML_TOKEN)\n .map((segment, i) => i % 2 === 1 ? segment : highlight(segment))\n .join('');\n}\n\n/**\n * 文字列を1文字ずつ比較し、差分をspanタグで囲んだHTML文字列を返す\n * 追加・削除・一致の部分ごとに、spanタグに付与するclass, styleを指定できる\n * 入力文字列はプレーンなテキストであるとみなす\n * 出力される文字列は、diffで埋め込まれるHTMLタグ以外はHTMLエスケープされ、HTMLセーフな文字列となる\n *\n * @param {string | null | undefined} text1 比較元の文字列\n * @param {string | null | undefined} text2 比較される文字列(通常、入力値はこちらに渡す)\n * @param {*} [options]\n * ├ ignoreCase boolean trueを指定した場合、大文字小文字を区別しない\n * ├ added HtmlTagOptions text2で追加された部分のspanタグに付与する属性\n * ├ removed HtmlTagOptions text2で削除された部分のspanタグに付与する属性\n * ├ same HtmlTagOptions 一致した部分のspanタグに付与する属性\n * @returns {string}\n */\nexport function diffForWeb(text1: string | null | undefined, text2: string | null | undefined, options?: {\n ignoreCase?: boolean;\n added?: HtmlTagOptions;\n removed?: HtmlTagOptions;\n same?: HtmlTagOptions;\n}): string {\n const changes = diffChars(text1 ?? '', text2 ?? '', { ignoreCase: options?.ignoreCase });\n let html = '';\n for (const change of changes) {\n if (change.added) {\n html += toSpan(change.value, options?.added);\n } else if (change.removed) {\n html += toSpan(change.value, options?.removed);\n } else {\n html += toSpan(change.value, options?.same);\n }\n }\n return html;\n}\n"],"names":["HTML_TOKEN","HTML_ESCAPE_CHARS","escapeHtml","str","c","toClassString","value","key","toStyleString","v","toSpan","options","attributes","className","style","formatStringForWeb","formatText","text","segment","i","formatJsonStringForWeb","html","formatOptions","json","formatJsonString","highlightWord","word","toHtml","pattern","regex","highlight","part","diffForWeb","text1","text2","changes","diffChars","change"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";const b=require("diff"),S=require("./json-util-5mq7fsX_.cjs"),m=/(<!--[\s\S]*?-->|<[^>]*>|&(?:#\d+|#x[\da-f]+|\w+);)/i,j={'"':"&quot;","&":"&amp;","'":"&#39;","<":"&lt;",">":"&gt;"},l=t=>t.replace(/["&'<>]/g,r=>j[r]),y=t=>typeof t=="string"?t:Array.isArray(t)?t.filter(Boolean).join(" "):Object.keys(t).filter(r=>t[r]).join(" "),$=t=>typeof t=="string"?t:Object.entries(t).map(([r,e])=>`${r.startsWith("--")?r:r.replace(/[A-Z]/g,n=>`-${n.toLowerCase()}`)}: ${e}`).join("; "),a=(t,r)=>{let e="";const s=r?.class==null?"":y(r.class);s&&(e+=` class="${l(s)}"`);const n=r?.style==null?"":$(r.style);return n&&(e+=` style="${l(n)}"`),`<span${e}>${l(t)}</span>`};function f(t,r){if(!t)return"";const e=s=>s.replace(/\r\n|\r|\n/g,"<br>").replace(/\t/g,"&nbsp;&nbsp;").replace(/ /g,"&nbsp;");return r?.html?t.split(m).map((s,n)=>n%2===1?s:e(s)).join(""):e(l(t))}function u(t,r){const{html:e,...s}=r??{},n=S.formatJsonString(t,s);return n==null?"":f(String(n),{html:e})}function p(t,r,e){if(!t)return"";const s=i=>e?.html?i:l(i);if(!r)return s(t);const n=r.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d"),o=new RegExp(`(${n})`,e?.caseInsensitive?"i":""),g=i=>i.split(o).map((c,d)=>d%2===0?s(c):a(c,e)).join("");return e?.html?t.split(m).map((i,c)=>c%2===1?i:g(i)).join(""):g(t)}function h(t,r,e){const s=b.diffChars(t??"",r??"",{ignoreCase:e?.ignoreCase});let n="";for(const o of s)o.added?n+=a(o.value,e?.added):o.removed?n+=a(o.value,e?.removed):n+=a(o.value,e?.same);return n}const W=Object.freeze(Object.defineProperty({__proto__:null,diffForWeb:h,formatJsonStringForWeb:u,formatStringForWeb:f,highlightWord:p},Symbol.toStringTag,{value:"Module"}));exports.diffForWeb=h;exports.formatJsonStringForWeb=u;exports.formatStringForWeb=f;exports.highlightWord=p;exports.htmlUtil=W;
2
- //# sourceMappingURL=html-util-ClGIpzW1.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"html-util-ClGIpzW1.cjs","sources":["../src/html-util.ts"],"sourcesContent":["import { diffChars } from 'diff';\nimport { formatJsonString } from './json-util';\nimport type { FormatJsonStringOptions } from './json-util';\n\n/**\n * class属性に指定する値\n * 配列は要素を空白区切りで連結し、Recordは値がtrueのキーだけを連結する\n */\nexport type HtmlClassValue = string | string[] | Record<string, boolean>;\n\n/**\n * style属性に指定する値\n * Recordのキーはキャメルケースをケバブケースに変換する。数値には単位を付けない\n */\nexport type HtmlStyleValue = string | Record<string, string | number>;\n\n/**\n * 生成するタグに付与する属性\n */\nexport interface HtmlTagOptions {\n class?: HtmlClassValue;\n style?: HtmlStyleValue;\n}\n\nconst HTML_TOKEN = /(<!--[\\s\\S]*?-->|<[^>]*>|&(?:#\\d+|#x[\\da-f]+|\\w+);)/i;\n\nconst HTML_ESCAPE_CHARS: Record<string, string> = {\n '\"': '&quot;',\n '&': '&amp;',\n '\\'': '&#39;',\n '<': '&lt;',\n '>': '&gt;'\n};\n\nconst escapeHtml = (str: string): string => str.replace(/[\"&'<>]/g, (c) => HTML_ESCAPE_CHARS[c]);\n\nconst toClassString = (value: HtmlClassValue): string => {\n if (typeof value === 'string') {\n return value;\n }\n if (Array.isArray(value)) {\n return value.filter(Boolean).join(' ');\n }\n return Object.keys(value).filter(key => value[key]).join(' ');\n};\n\nconst toStyleString = (value: HtmlStyleValue): string => {\n if (typeof value === 'string') {\n return value;\n }\n return Object.entries(value)\n .map(([key, v]) => {\n // カスタムプロパティ(--xxx)は大文字小文字を区別するため変換しない\n const property = key.startsWith('--') ? key : key.replace(/[A-Z]/g, c => `-${c.toLowerCase()}`);\n return `${property}: ${v}`;\n })\n .join('; ');\n};\n\n/**\n * 値をエスケープしたspanタグを返す\n *\n * @param {string} value\n * @param {HtmlTagOptions} [options]\n * @returns {string}\n */\nconst toSpan = (value: string, options?: HtmlTagOptions): string => {\n let attributes = '';\n const className = options?.class == null ? '' : toClassString(options.class);\n if (className) {\n attributes += ` class=\"${escapeHtml(className)}\"`;\n }\n const style = options?.style == null ? '' : toStyleString(options.style);\n if (style) {\n attributes += ` style=\"${escapeHtml(style)}\"`;\n }\n return `<span${attributes}>${escapeHtml(value)}</span>`;\n};\n\n/**\n * 文字列をWEB表示用にフォーマットする\n * オプションのhtmlにより、入力文字列がHTMLなのかプレーンテキストなのかを指定可能\n *\n * @param {string | null | undefined} str\n * @param {*} [options]\n * ├ html boolean trueを指定した場合、入力された文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function formatStringForWeb(str: string | null | undefined, options?: {\n html?: boolean;\n}): string {\n if (!str) {\n return '';\n }\n\n const formatText = (text: string): string => text\n .replace(/\\r\\n|\\r|\\n/g, '<br>')\n .replace(/\\t/g, '&nbsp;&nbsp;')\n .replace(/ /g, '&nbsp;');\n\n if (options?.html) {\n // 奇数番目がタグ・コメント・文字参照。偶数番目のテキスト部分だけをフォーマットする\n return str\n .split(HTML_TOKEN)\n .map((segment, i) => i % 2 === 1 ? segment : formatText(segment))\n .join('');\n }\n\n return formatText(escapeHtml(str));\n}\n\n/**\n * 値を整形したJSON文字列にしてWEB表示用にフォーマットする\n * formatJsonStringで整形した文字列をformatStringForWebで変換する\n *\n * @param {any} value\n * @param {*} [options] formatJsonStringのオプションに以下を加えたもの\n * ├ html boolean trueを指定した場合、文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function formatJsonStringForWeb(value: any, options?: FormatJsonStringOptions & {\n html?: boolean;\n}): string {\n const { html, ...formatOptions } = options ?? {};\n const json = formatJsonString(value, formatOptions);\n return json == null ? '' : formatStringForWeb(String(json), { html });\n}\n\n/**\n * 文字列の中で一致したワードをspanタグで囲んだHTML文字列を返す\n * オプションのhtmlにより、入力文字列がHTMLなのかプレーンテキストなのかを指定可能\n *\n * 例)\n * HtmlUtil.highlightWord('This is a test message', 'test', { class: 'highlight' });\n * → 'This is a <span class=\"highlight\">test</span> message'\n *\n * @param {string | null | undefined} value\n * @param {string | null | undefined} word\n * @param {*} [options] spanタグに付与するclass, styleのほか、以下を指定できる\n * ├ class string | string[] | Record<string, boolean>\n * ├ style string | Record<string, string | number>\n * ├ caseInsensitive boolean trueを指定した場合、大文字小文字を区別しない\n * ├ html boolean trueを指定した場合、入力された文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function highlightWord(\n value: string | null | undefined,\n word: string | null | undefined,\n options?: HtmlTagOptions & {\n caseInsensitive?: boolean;\n html?: boolean;\n }\n): string {\n if (!value) {\n return '';\n }\n\n const toHtml = (text: string): string => options?.html ? text : escapeHtml(text);\n if (!word) {\n return toHtml(value);\n }\n\n const pattern = word.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&').replace(/-/g, '\\\\x2d');\n const regex = new RegExp(`(${pattern})`, options?.caseInsensitive ? 'i' : '');\n // キャプチャグループで分割すると、奇数番目の要素が一致した部分になる\n const highlight = (text: string): string => text\n .split(regex)\n .map((part, i) => i % 2 === 0 ? toHtml(part) : toSpan(part, options))\n .join('');\n\n if (!options?.html) {\n return highlight(value);\n }\n\n // 奇数番目がタグ・コメント・文字参照。偶数番目のテキスト部分だけをハイライトする\n return value\n .split(HTML_TOKEN)\n .map((segment, i) => i % 2 === 1 ? segment : highlight(segment))\n .join('');\n}\n\n/**\n * 文字列を1文字ずつ比較し、差分をspanタグで囲んだHTML文字列を返す\n * 追加・削除・一致の部分ごとに、spanタグに付与するclass, styleを指定できる\n * 入力文字列はプレーンなテキストであるとみなす\n * 出力される文字列は、diffで埋め込まれるHTMLタグ以外はHTMLエスケープされ、HTMLセーフな文字列となる\n *\n * @param {string | null | undefined} text1 比較元の文字列\n * @param {string | null | undefined} text2 比較される文字列(通常、入力値はこちらに渡す)\n * @param {*} [options]\n * ├ ignoreCase boolean trueを指定した場合、大文字小文字を区別しない\n * ├ added HtmlTagOptions text2で追加された部分のspanタグに付与する属性\n * ├ removed HtmlTagOptions text2で削除された部分のspanタグに付与する属性\n * ├ same HtmlTagOptions 一致した部分のspanタグに付与する属性\n * @returns {string}\n */\nexport function diffForWeb(text1: string | null | undefined, text2: string | null | undefined, options?: {\n ignoreCase?: boolean;\n added?: HtmlTagOptions;\n removed?: HtmlTagOptions;\n same?: HtmlTagOptions;\n}): string {\n const changes = diffChars(text1 ?? '', text2 ?? '', { ignoreCase: options?.ignoreCase });\n let html = '';\n for (const change of changes) {\n if (change.added) {\n html += toSpan(change.value, options?.added);\n } else if (change.removed) {\n html += toSpan(change.value, options?.removed);\n } else {\n html += toSpan(change.value, options?.same);\n }\n }\n return html;\n}\n"],"names":["HTML_TOKEN","HTML_ESCAPE_CHARS","escapeHtml","str","c","toClassString","value","key","toStyleString","v","toSpan","options","attributes","className","style","formatStringForWeb","formatText","text","segment","i","formatJsonStringForWeb","html","formatOptions","json","formatJsonString","highlightWord","word","toHtml","pattern","regex","highlight","part","diffForWeb","text1","text2","changes","diffChars","change"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"json-util-5mq7fsX_.cjs","sources":["../src/json-util.ts"],"sourcesContent":["/**\n * JSON.parseのreviverが第3引数で受け取る情報\n */\ninterface JsonReviverContext {\n /** プリミティブ値のJSON上の表記 */\n source?: string;\n}\n\nconst INTEGER_LITERAL = /^-?\\d+$/;\n\n/**\n * JSON文字列をパースする\n * Number.MIN_SAFE_INTEGER〜Number.MAX_SAFE_INTEGERの範囲外の整数はnumberに変換すると桁落ちするため、JSON上の表記のまま文字列で返す\n * そのため、同じ項目でも値の大きさによってnumberとstringが混在する\n *\n * @param {string} source\n * @returns {T}\n */\nexport function parse<T = any>(source: string): T {\n return JSON.parse(source, (_key: string, value: any, context?: JsonReviverContext) => {\n const literal = context?.source;\n if (typeof value === 'number' && !Number.isSafeInteger(value) && literal && INTEGER_LITERAL.test(literal)) {\n return literal;\n }\n return value;\n }) as T;\n}\n\n/**\n * 値をJSON文字列に変換する\n * bigintは文字列として出力する\n *\n * @param {any} value\n * @param {(this: any, key: string, value: any) => any} [replacer]\n * @param {string | number} [space]\n * @param {*} [options]\n * ├ circular 'replace' 循環参照を'[Circular]'に置き換える。未指定の場合、循環参照があればTypeErrorをスローする\n * @returns {string}\n */\nexport function stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number, options?: {\n circular?: 'replace';\n}): string {\n // 祖先の「元の値」と「replacerを適用した後の値」の組。JSON.stringifyが走査するのは後者だが、循環参照の判定は前者で行う。\n // replacerが新しいオブジェクトを返す場合でも、元の値が同じなら循環参照として検出できるようにするため\n const ancestors: { original: any; replaced: object; }[] = [];\n return JSON.stringify(value, function(this: any, key: string, current: any) {\n let result = replacer ? replacer.call(this, key, current) : current;\n if (typeof result === 'bigint') {\n result = result.toString();\n }\n if (options?.circular !== 'replace' || typeof result !== 'object' || result === null) {\n return result;\n }\n // thisは処理中の値を持つ親オブジェクトである。親より後に積まれた要素は、走査を終えた兄弟の子孫なので取り除く。\n // 残った要素は処理中の値の祖先だけになる。祖先に含まれる値だけを循環参照とみなすため、複数箇所から参照されているだけのオブジェクトは置き換えない。\n while (ancestors.length && ancestors[ancestors.length - 1].replaced !== this) {\n ancestors.pop();\n }\n if (ancestors.some(ancestor => ancestor.original === current || ancestor.replaced === result)) {\n return '[Circular]';\n }\n ancestors.push({ original: current, replaced: result });\n return result;\n }, space);\n}\n\n/**\n * formatJsonStringのオプション\n */\nexport interface FormatJsonStringOptions {\n /** インデントのスペース数。0を指定すると改行・インデントなしの1行にする デフォルト 2 */\n spaces?: number;\n /** 改行コード デフォルト '\\n' */\n newline?: string;\n /** 展開するネストの深さ。ルートを0とし、これを超える深さのオブジェクト・配列は \"[Object]\" / \"[Array]\" に置き換える。未指定の場合は制限なし */\n maxDepth?: number;\n /** 文字列値1項目あたりの最大文字数。超える部分を切り捨てて末尾に '...' を付ける。未指定の場合は制限なし */\n maxStringLength?: number;\n /** trueの場合、オブジェクトのキーをコード単位の昇順に並べる デフォルト false */\n sort?: boolean;\n}\n\ninterface FormatContext {\n spaces: number;\n newline: string;\n maxDepth: number;\n maxStringLength: number;\n sort: boolean;\n /** 処理中の値の祖先。循環参照の判定に使う */\n ancestors: object[];\n}\n\nconst JSON_LIKE_PATTERN = /^(\\{|\\[)/;\n\n/**\n * オブジェクトまたは配列を表すJSON文字列をパースする\n * それ以外の文字列、パースできない文字列はundefinedを返す\n *\n * @param {string} value\n * @returns {object | undefined}\n */\nfunction parseJsonLike(value: string): object | undefined {\n if (!JSON_LIKE_PATTERN.test(value)) {\n return undefined;\n }\n try {\n const parsed = parse(value);\n return typeof parsed === 'object' && parsed !== null ? parsed : undefined;\n } catch (error) {\n return undefined;\n }\n}\n\n/**\n * 文字列をmaxStringLengthに収まるよう切り詰める\n * サロゲートペアを分断しないようコードポイント単位で数える\n *\n * @param {string} value\n * @param {FormatContext} context\n * @returns {string}\n */\nfunction truncate(value: string, context: FormatContext): string {\n if (value.length <= context.maxStringLength) {\n return value;\n }\n const chars = Array.from(value);\n return chars.length <= context.maxStringLength ? value : `${chars.slice(0, context.maxStringLength).join('')}...`;\n}\n\n/**\n * 文字列をJSONの文字列リテラルにする\n * 改行と二重引用符は、表示したときに読めるようエスケープしない\n *\n * @param {string} value\n * @returns {string}\n */\nfunction quoteString(value: string): string {\n return JSON.stringify(value).replace(/\\\\(.)/g, (escaped, char) => {\n switch (char) {\n case 'n':\n return '\\n';\n case '\"':\n return '\"';\n default:\n return escaped;\n }\n });\n}\n\n/**\n * valueをJSON文字列に変換する\n * JSON.stringifyが出力しない値(undefined・関数・symbol)はundefinedを返す\n *\n * @param {any} value\n * @param {number} depth ルートを0とするネストの深さ\n * @param {string} key 親オブジェクトでのキー。toJSONに渡す\n * @param {FormatContext} context\n * @returns {string | undefined}\n */\nfunction formatValue(value: any, depth: number, key: string, context: FormatContext): string | undefined {\n switch (typeof value) {\n case 'string': {\n const parsed = parseJsonLike(value);\n return parsed === undefined ? quoteString(truncate(value, context)) : formatValue(parsed, depth, key, context);\n }\n case 'number':\n case 'boolean':\n return JSON.stringify(value);\n case 'bigint':\n return JSON.stringify(value.toString());\n case 'object': {\n if (value === null) {\n return 'null';\n }\n if (typeof value.toFixed === 'function') {\n return JSON.stringify(value.toFixed());\n }\n if (typeof value.toJSON === 'function') {\n return formatValue(value.toJSON(key), depth, key, context);\n }\n if (context.ancestors.includes(value)) {\n return '\"[Circular]\"';\n }\n const isArray = Array.isArray(value);\n if (context.maxDepth < depth) {\n return isArray ? '\"[Array]\"' : '\"[Object]\"';\n }\n context.ancestors.push(value);\n try {\n return formatContainer(value, isArray, depth, context);\n } finally {\n context.ancestors.pop();\n }\n }\n default:\n return undefined;\n }\n}\n\n/**\n * オブジェクトまたは配列の要素を整形して括弧で囲む\n *\n * @param {any} value\n * @param {boolean} isArray\n * @param {number} depth\n * @param {FormatContext} context\n * @returns {string}\n */\nfunction formatContainer(value: any, isArray: boolean, depth: number, context: FormatContext): string {\n const separator = context.spaces === 0 ? ':' : ': ';\n const entries: string[] = [];\n if (isArray) {\n for (let i = 0; i < value.length; i++) {\n entries.push(formatValue(value[i], depth + 1, String(i), context) ?? 'null');\n }\n } else {\n const keys = Object.keys(value);\n if (context.sort) {\n keys.sort();\n }\n for (const key of keys) {\n const formatted = formatValue(value[key], depth + 1, key, context);\n if (formatted !== undefined) {\n entries.push(`${JSON.stringify(key)}${separator}${formatted}`);\n }\n }\n }\n const [open, close] = isArray ? ['[', ']'] : ['{', '}'];\n if (entries.length === 0) {\n return `${open}${close}`;\n }\n if (context.spaces === 0) {\n return `${open}${entries.join(',')}${close}`;\n }\n const indent = ' '.repeat(context.spaces * (depth + 1));\n const closeIndent = ' '.repeat(context.spaces * depth);\n return `${open}${context.newline}${indent}${entries.join(`,${context.newline}${indent}`)}${context.newline}${closeIndent}${close}`;\n}\n\n/**\n * 値を整形したJSON文字列に変換する\n * JSON文字列を値に持つ項目は、その文字列もオブジェクトとして展開して整形する\n * 循環参照は \"[Circular]\" に置き換える\n * オブジェクト・配列・それらを表すJSON文字列以外の値はそのまま返す\n *\n * @param {any} value\n * @param {FormatJsonStringOptions} [options]\n * @returns {string}\n * @see FormatJsonStringOptions\n */\nexport function formatJsonString(value: any, options?: FormatJsonStringOptions): string {\n if (value == null) {\n return value;\n }\n const context: FormatContext = {\n spaces: options?.spaces ?? 2,\n newline: options?.newline ?? '\\n',\n maxDepth: options?.maxDepth ?? Number.POSITIVE_INFINITY,\n maxStringLength: options?.maxStringLength ?? Number.POSITIVE_INFINITY,\n sort: options?.sort ?? false,\n ancestors: []\n };\n switch (typeof value) {\n case 'string': {\n const parsed = parseJsonLike(value);\n return parsed === undefined ? value : formatValue(parsed, 0, '', context) as string;\n }\n case 'object':\n return formatValue(value, 0, '', context) ?? value;\n default:\n return value;\n }\n}\n\n/**\n * 値がJSON文字列か判定する\n * オブジェクトまたは配列を表すJSON文字列の場合だけtrueを返す\n *\n * @param {any} value\n * @returns {boolean}\n */\nexport function isJsonString(value: any): boolean {\n if (!value || typeof value !== 'string' || !JSON_LIKE_PATTERN.test(value)) {\n return false;\n }\n try {\n return typeof parse(value) === 'object';\n } catch (error) {\n return false;\n }\n}\n"],"names":["INTEGER_LITERAL","parse","source","_key","value","context","literal","stringify","replacer","space","options","ancestors","key","current","result","ancestor","JSON_LIKE_PATTERN","parseJsonLike","parsed","truncate","chars","quoteString","escaped","char","formatValue","depth","isArray","formatContainer","separator","entries","i","keys","formatted","open","close","indent","closeIndent","formatJsonString","isJsonString"],"mappings":"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"}