@shaxpir/duiduidui-models 1.0.1 → 1.1.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 (224) hide show
  1. package/dist/models/{content/ArrayView.d.ts → ArrayView.d.ts} +1 -1
  2. package/dist/models/{content/ArrayView.js → ArrayView.js} +14 -14
  3. package/dist/models/BayesianScore.d.ts +9 -0
  4. package/dist/models/BayesianScore.js +27 -0
  5. package/dist/models/{markup/ChangeModel.d.ts → ChangeModel.d.ts} +2 -3
  6. package/dist/models/{markup/ChangeModel.js → ChangeModel.js} +20 -10
  7. package/dist/models/{content/Content.d.ts → Content.d.ts} +9 -10
  8. package/dist/models/{content/Content.js → Content.js} +2 -6
  9. package/dist/models/{content/ContentKind.d.ts → ContentKind.d.ts} +3 -0
  10. package/dist/models/{content/ContentKind.js → ContentKind.js} +5 -1
  11. package/dist/models/{content/Device.d.ts → Device.d.ts} +15 -7
  12. package/dist/models/{content/Device.js → Device.js} +14 -18
  13. package/dist/models/Hanzi.d.ts +15 -0
  14. package/dist/models/{content/Manifest.d.ts → Manifest.d.ts} +7 -3
  15. package/dist/models/{content/Manifest.js → Manifest.js} +12 -8
  16. package/dist/models/{content/Media.d.ts → Media.d.ts} +2 -3
  17. package/dist/models/{content/Media.js → Media.js} +4 -5
  18. package/dist/models/{content/Metric.d.ts → Metric.d.ts} +2 -3
  19. package/dist/models/{content/Metric.js → Metric.js} +18 -20
  20. package/dist/models/{content/Model.d.ts → Model.d.ts} +3 -5
  21. package/dist/models/{content/Model.js → Model.js} +5 -6
  22. package/dist/models/{markup/Operation.d.ts → Operation.d.ts} +2 -5
  23. package/dist/models/{markup/Operation.js → Operation.js} +30 -25
  24. package/dist/models/Phrase.d.ts +39 -0
  25. package/dist/models/{content/Profile.d.ts → Profile.d.ts} +1 -2
  26. package/dist/models/{content/Profile.js → Profile.js} +7 -9
  27. package/dist/models/Progress.d.ts +26 -0
  28. package/dist/models/Progress.js +39 -0
  29. package/dist/models/Review.d.ts +14 -0
  30. package/dist/models/{content/Session.d.ts → Session.d.ts} +7 -15
  31. package/dist/models/Session.js +103 -0
  32. package/dist/models/Term.d.ts +36 -0
  33. package/dist/models/Term.js +82 -0
  34. package/dist/models/User.d.ts +32 -0
  35. package/dist/models/User.js +65 -0
  36. package/dist/models/Workspace.d.ts +37 -0
  37. package/dist/models/Workspace.js +94 -0
  38. package/dist/models/index.d.ts +22 -2
  39. package/dist/models/index.js +22 -2
  40. package/dist/repo/PermissiveJson1.d.ts +16 -16
  41. package/dist/repo/PermissiveJson1.js +17 -7
  42. package/dist/repo/ShareSync.d.ts +6 -6
  43. package/dist/repo/ShareSync.js +26 -19
  44. package/dist/repo/index.d.ts +1 -0
  45. package/dist/repo/index.js +1 -0
  46. package/dist/util/index.d.ts +0 -6
  47. package/dist/util/index.js +0 -6
  48. package/lib/models/{content/ArrayView.ts → ArrayView.ts} +2 -2
  49. package/lib/models/BayesianScore.ts +32 -0
  50. package/lib/models/{markup/ChangeModel.ts → ChangeModel.ts} +3 -4
  51. package/lib/models/{content/Content.ts → Content.ts} +15 -18
  52. package/lib/models/{content/ContentKind.ts → ContentKind.ts} +6 -1
  53. package/lib/models/{content/Device.ts → Device.ts} +26 -22
  54. package/lib/models/Hanzi.ts +16 -0
  55. package/lib/models/{content/Manifest.ts → Manifest.ts} +15 -6
  56. package/lib/models/{content/Media.ts → Media.ts} +3 -4
  57. package/lib/models/Metric.ts +233 -0
  58. package/lib/models/{content/Model.ts → Model.ts} +4 -6
  59. package/lib/models/{markup/Operation.ts → Operation.ts} +6 -16
  60. package/lib/models/{content/Permissions.ts → Permissions.ts} +0 -2
  61. package/lib/models/Phrase.ts +53 -0
  62. package/lib/models/{content/Profile.ts → Profile.ts} +4 -6
  63. package/lib/models/Progress.ts +66 -0
  64. package/lib/models/Review.ts +18 -0
  65. package/lib/models/Session.ts +140 -0
  66. package/lib/models/Term.ts +139 -0
  67. package/lib/models/User.ts +97 -0
  68. package/lib/models/Workspace.ts +129 -0
  69. package/lib/models/index.ts +22 -2
  70. package/lib/repo/ShareSync.ts +9 -13
  71. package/lib/repo/index.ts +1 -0
  72. package/lib/util/index.ts +0 -6
  73. package/package.json +4 -15
  74. package/dist/models/OutboundMessage.d.ts +0 -18
  75. package/dist/models/OutboundMessage.js +0 -25
  76. package/dist/models/content/Activity.d.ts +0 -10
  77. package/dist/models/content/Billing.d.ts +0 -144
  78. package/dist/models/content/Billing.js +0 -418
  79. package/dist/models/content/Book.d.ts +0 -77
  80. package/dist/models/content/Book.js +0 -407
  81. package/dist/models/content/Category.d.ts +0 -16
  82. package/dist/models/content/Category.js +0 -20
  83. package/dist/models/content/Checkpointable.d.ts +0 -21
  84. package/dist/models/content/Checkpointable.js +0 -156
  85. package/dist/models/content/Comment.d.ts +0 -19
  86. package/dist/models/content/Comment.js +0 -53
  87. package/dist/models/content/ConceptArt.d.ts +0 -31
  88. package/dist/models/content/ConceptArt.js +0 -84
  89. package/dist/models/content/Context.d.ts +0 -28
  90. package/dist/models/content/Context.js +0 -162
  91. package/dist/models/content/DevEnv.d.ts +0 -5
  92. package/dist/models/content/DevEnv.js +0 -9
  93. package/dist/models/content/Dictionary.d.ts +0 -31
  94. package/dist/models/content/Dictionary.js +0 -5
  95. package/dist/models/content/DictionaryEntry.d.ts +0 -20
  96. package/dist/models/content/DictionaryEntry.js +0 -2
  97. package/dist/models/content/ElasticModel.d.ts +0 -149
  98. package/dist/models/content/ElasticModel.js +0 -179
  99. package/dist/models/content/Environment.d.ts +0 -61
  100. package/dist/models/content/Environment.js +0 -124
  101. package/dist/models/content/ExportOptions.d.ts +0 -64
  102. package/dist/models/content/ExportOptions.js +0 -213
  103. package/dist/models/content/Folder.d.ts +0 -16
  104. package/dist/models/content/Folder.js +0 -33
  105. package/dist/models/content/Fragment.d.ts +0 -54
  106. package/dist/models/content/Fragment.js +0 -181
  107. package/dist/models/content/Hanzi.d.ts +0 -21
  108. package/dist/models/content/HighlightRule.d.ts +0 -9
  109. package/dist/models/content/HighlightRule.js +0 -2
  110. package/dist/models/content/Migration.d.ts +0 -68
  111. package/dist/models/content/Migration.js +0 -155
  112. package/dist/models/content/Phrase.d.ts +0 -8
  113. package/dist/models/content/Placeholder.d.ts +0 -8
  114. package/dist/models/content/Placeholder.js +0 -36
  115. package/dist/models/content/RichText.d.ts +0 -58
  116. package/dist/models/content/RichText.js +0 -79
  117. package/dist/models/content/Session.js +0 -173
  118. package/dist/models/content/Speech.d.ts +0 -67
  119. package/dist/models/content/Speech.js +0 -97
  120. package/dist/models/content/Stub.d.ts +0 -24
  121. package/dist/models/content/Stub.js +0 -179
  122. package/dist/models/content/Time.d.ts +0 -56
  123. package/dist/models/content/Time.js +0 -295
  124. package/dist/models/content/User.d.ts +0 -36
  125. package/dist/models/content/User.js +0 -95
  126. package/dist/models/content/Workspace.d.ts +0 -71
  127. package/dist/models/content/Workspace.js +0 -237
  128. package/dist/models/content/index.d.ts +0 -17
  129. package/dist/models/content/index.js +0 -34
  130. package/dist/models/legacy/LegacyBodyFormat.d.ts +0 -9
  131. package/dist/models/legacy/LegacyBodyFormat.js +0 -2
  132. package/dist/models/legacy/LegacyComment.d.ts +0 -12
  133. package/dist/models/legacy/LegacyComment.js +0 -2
  134. package/dist/models/legacy/LegacyContent.d.ts +0 -53
  135. package/dist/models/legacy/LegacyContent.js +0 -55
  136. package/dist/models/legacy/LegacyConversion.d.ts +0 -55
  137. package/dist/models/legacy/LegacyConversion.js +0 -401
  138. package/dist/models/legacy/LegacyFragment.d.ts +0 -21
  139. package/dist/models/legacy/LegacyFragment.js +0 -2
  140. package/dist/models/legacy/LegacyLocator.d.ts +0 -8
  141. package/dist/models/legacy/LegacyLocator.js +0 -31
  142. package/dist/models/legacy/LegacyOutboundMessage.d.ts +0 -16
  143. package/dist/models/legacy/LegacyOutboundMessage.js +0 -13
  144. package/dist/models/legacy/LegacyPicture.d.ts +0 -14
  145. package/dist/models/legacy/LegacyPicture.js +0 -2
  146. package/dist/models/legacy/LegacyProfile.d.ts +0 -9
  147. package/dist/models/legacy/LegacyProfile.js +0 -2
  148. package/dist/models/legacy/LegacySession.d.ts +0 -41
  149. package/dist/models/legacy/LegacySession.js +0 -35
  150. package/dist/models/legacy/LegacyStory.d.ts +0 -23
  151. package/dist/models/legacy/LegacyStory.js +0 -2
  152. package/dist/models/legacy/LegacyStub.d.ts +0 -15
  153. package/dist/models/legacy/LegacyStub.js +0 -2
  154. package/dist/models/legacy/LegacyTransaction.d.ts +0 -14
  155. package/dist/models/legacy/LegacyTransaction.js +0 -49
  156. package/dist/models/legacy/LegacyUser.d.ts +0 -28
  157. package/dist/models/legacy/LegacyUser.js +0 -32
  158. package/dist/models/legacy/LegacyWorkspace.d.ts +0 -23
  159. package/dist/models/legacy/LegacyWorkspace.js +0 -6
  160. package/dist/models/legacy/index.d.ts +0 -15
  161. package/dist/models/legacy/index.js +0 -32
  162. package/dist/models/markup/BodyFormat.d.ts +0 -14
  163. package/dist/models/markup/BodyFormat.js +0 -190
  164. package/dist/models/markup/DeltaOps.d.ts +0 -5
  165. package/dist/models/markup/DeltaOps.js +0 -74
  166. package/dist/models/markup/HtmlMarkup.d.ts +0 -4
  167. package/dist/models/markup/HtmlMarkup.js +0 -21
  168. package/dist/models/markup/index.d.ts +0 -4
  169. package/dist/models/markup/index.js +0 -21
  170. package/dist/util/Async.d.ts +0 -8
  171. package/dist/util/Async.js +0 -18
  172. package/dist/util/Base62.d.ts +0 -6
  173. package/dist/util/Base62.js +0 -47
  174. package/dist/util/BinarySearch.d.ts +0 -7
  175. package/dist/util/BinarySearch.js +0 -46
  176. package/dist/util/CachingHasher.d.ts +0 -8
  177. package/dist/util/CachingHasher.js +0 -41
  178. package/dist/util/Color.d.ts +0 -32
  179. package/dist/util/Color.js +0 -204
  180. package/dist/util/Dispatch.d.ts +0 -15
  181. package/dist/util/Dispatch.js +0 -79
  182. package/dist/util/EditDistance.d.ts +0 -13
  183. package/dist/util/EditDistance.js +0 -184
  184. package/dist/util/NumberFormat.d.ts +0 -14
  185. package/dist/util/NumberFormat.js +0 -224
  186. package/dist/util/Struct.d.ts +0 -4
  187. package/dist/util/Struct.js +0 -15
  188. package/dist/util/Template.d.ts +0 -16
  189. package/dist/util/Template.js +0 -128
  190. package/dist/util/Text.d.ts +0 -45
  191. package/dist/util/Text.js +0 -243
  192. package/dist/util/Tuples.d.ts +0 -9
  193. package/dist/util/Tuples.js +0 -135
  194. package/dist/util/Validate.d.ts +0 -4
  195. package/dist/util/Validate.js +0 -11
  196. package/dist/util/Vocabulary.d.ts +0 -3
  197. package/dist/util/Vocabulary.js +0 -35
  198. package/lib/models/content/Billing.ts +0 -558
  199. package/lib/models/content/DevEnv.ts +0 -5
  200. package/lib/models/content/DictionaryEntry.ts +0 -22
  201. package/lib/models/content/Hanzi.ts +0 -25
  202. package/lib/models/content/Phrase.ts +0 -10
  203. package/lib/models/content/Time.ts +0 -328
  204. package/lib/models/content/User.ts +0 -130
  205. package/lib/models/content/index.ts +0 -19
  206. package/lib/models/markup/DeltaOps.ts +0 -71
  207. package/lib/models/markup/index.ts +0 -6
  208. package/lib/util/Base62.ts +0 -47
  209. package/lib/util/CachingHasher.ts +0 -38
  210. package/lib/util/Dispatch.ts +0 -92
  211. package/lib/util/NumberFormat.ts +0 -194
  212. package/lib/util/Struct.ts +0 -14
  213. package/lib/util/Tuples.ts +0 -131
  214. /package/dist/models/{content/GeoLocation.d.ts → GeoLocation.d.ts} +0 -0
  215. /package/dist/models/{content/GeoLocation.js → GeoLocation.js} +0 -0
  216. /package/dist/models/{content/Hanzi.js → Hanzi.js} +0 -0
  217. /package/dist/models/{content/Permissions.d.ts → Permissions.d.ts} +0 -0
  218. /package/dist/models/{content/Permissions.js → Permissions.js} +0 -0
  219. /package/dist/models/{content/Phrase.js → Phrase.js} +0 -0
  220. /package/dist/models/{content/Activity.js → Review.js} +0 -0
  221. /package/dist/{models/markup → repo}/TextEditOps.d.ts +0 -0
  222. /package/dist/{models/markup → repo}/TextEditOps.js +0 -0
  223. /package/lib/models/{content/GeoLocation.ts → GeoLocation.ts} +0 -0
  224. /package/lib/{models/markup → repo}/TextEditOps.ts +0 -0
@@ -1,328 +0,0 @@
1
- import dayjs from 'dayjs';
2
- import utc from 'dayjs/plugin/utc';
3
- import timezone from 'dayjs/plugin/timezone';
4
- import dayOfYear from 'dayjs/plugin/dayOfYear';
5
- dayjs.extend(utc);
6
- dayjs.extend(timezone);
7
- dayjs.extend(dayOfYear);
8
-
9
- enum CompactDateTimeBrand {}
10
- enum CompactDateBrand {}
11
-
12
- export type CompactDateTime = string & CompactDateTimeBrand;
13
- export type CompactDate = string & CompactDateBrand;
14
-
15
- export interface SingleTime {
16
- utc_time:CompactDateTime;
17
- }
18
-
19
- export interface MultiTime {
20
- utc_time:CompactDateTime;
21
- local_time:CompactDateTime;
22
- }
23
-
24
- export class MultiClock {
25
-
26
- public static utcNow():MultiTime {
27
- const localtime:CompactDateTime = Time.local();
28
- const utcTime:CompactDateTime = Time.utc(localtime);
29
- return {
30
- local_time: utcTime,
31
- utc_time: utcTime
32
- };
33
- }
34
-
35
- public static now():MultiTime {
36
- const localtime:CompactDateTime = Time.local();
37
- return {
38
- local_time: localtime,
39
- utc_time: Time.utc(localtime)
40
- };
41
- }
42
- }
43
-
44
- export class Time {
45
-
46
- public static readonly DATETIME_FORMAT_LEGACY:string = "YYYY-MM-DDTHH:mm:ss.SSSZ";
47
-
48
- public static readonly DATE_FORMAT:string = "YYYYMMDD";
49
- public static readonly DATETIME_FORMAT_COMPACT:string = "YYYYMMDDHHmmssSSS";
50
-
51
- public static readonly DATE_NO_YEAR:string = "MMMM D";
52
- public static readonly DATE_BEAUTIFIED:string = "MMMM D, YYYY";
53
- public static readonly DATE_FULLY_BEAUTIFIED:string = "dddd, MMMM D, YYYY";
54
-
55
- public static readonly YEAR_ONLY:string = "YYYY";
56
-
57
- public static asCompactDateTime(text:string):CompactDateTime {
58
- // A compact datetime is always 17 digits long and starts with '20'
59
- if (text.startsWith("20") && /^\d{17}$/.test(text)) {
60
- return text as CompactDateTime;
61
- }
62
- return null as CompactDateTime;
63
- }
64
-
65
- public static asCompactDate(text:string):CompactDate|null {
66
- // A compact date is always 8 digits long and starts with '20'
67
- if (text.startsWith("20") && /^\d{8}$/.test(text)) {
68
- return text as CompactDate;
69
- }
70
- return null;
71
- }
72
-
73
- public static isDateBefore(a:CompactDate, b:CompactDate):boolean {
74
- return Time.compareDate(a, b) < 0;
75
- }
76
-
77
- public static isDateAfter(a:CompactDate, b:CompactDate):boolean {
78
- return Time.compareDate(a, b) > 0;
79
- }
80
-
81
- public static compareDate(a:CompactDate, b:CompactDate):number {
82
- if (a == null && b == null) {
83
- return 0;
84
- } else if (a == null) {
85
- return -1;
86
- } else if (b == null) {
87
- return 1;
88
- }
89
- return (a as string).localeCompare(b as string);
90
- }
91
-
92
- public static isDateTimeBefore(a:CompactDateTime, b:CompactDateTime):boolean {
93
- return Time.compareDateTime(a, b) < 0;
94
- }
95
-
96
- public static isDateTimeAfter(a:CompactDateTime, b:CompactDateTime):boolean {
97
- return Time.compareDateTime(a, b) > 0;
98
- }
99
-
100
- public static compareDateTime(a:CompactDateTime, b:CompactDateTime):number {
101
- if (a == null && b == null) {
102
- return 0;
103
- } else if (a == null) {
104
- return -1;
105
- } else if (b == null) {
106
- return 1;
107
- }
108
- return (a as string).localeCompare(b as string);
109
- }
110
-
111
- public static sortByUtcTime(array:MultiTime[]):MultiTime[] {
112
- return array.sort((a, b) => Time.compareDateTime(a.utc_time, b.utc_time));
113
- }
114
-
115
- public static dateFrom(timestamp:CompactDateTime):CompactDate {
116
- const timestampText = timestamp as string;
117
- if (timestampText.length >= 8 && /^\d{8}.*/.test(timestampText)) {
118
- return timestampText.substring(0, 8) as CompactDate;
119
- }
120
- if (typeof(timestamp) === "string") {
121
- throw new Error("can\x27t parse date from malformed timestamp: " + timestamp);
122
- } else {
123
- throw new Error("can\x27t parse date from malformed timestamp: " + JSON.stringify(timestamp));
124
- }
125
- }
126
-
127
- public static datesBetween(minDate:CompactDate, maxDate:CompactDate):CompactDate[] {
128
- const dates:CompactDate[] = new Array<CompactDate>();
129
- let d:string = minDate;
130
- while (d.localeCompare(minDate) >= 0 && d.localeCompare(maxDate) <= 0) {
131
- dates.push(d as CompactDate);
132
- d = dayjs(d, Time.DATE_FORMAT).add(1, 'days').format(Time.DATE_FORMAT) as CompactDate;
133
- }
134
- return dates;
135
- }
136
-
137
- public static plus(timestamp:CompactDateTime, amount:number, units:dayjs.ManipulateType):CompactDateTime {
138
- const time = dayjs(timestamp, Time.DATETIME_FORMAT_COMPACT);
139
- return time.add(amount, units).format(Time.DATETIME_FORMAT_COMPACT) as CompactDateTime;
140
- }
141
-
142
- public static todayLocal():CompactDate {
143
- return Time.dateFrom(Time.local());
144
- }
145
-
146
- public static todayUtc():CompactDate {
147
- return Time.dateFrom(Time.utc());
148
- }
149
-
150
- public static startOfMonth(date:CompactDate):CompactDate {
151
- let text = date as string;
152
- if (text.startsWith("20") && /^\d{8}$/.test(text)) {
153
- text = text.substring(0, 6) + "01;"
154
- }
155
- return text as CompactDate;
156
- }
157
-
158
- public static local(utc?:CompactDateTime):CompactDateTime {
159
- let result;
160
- if (typeof(utc) === "undefined") {
161
- result = dayjs().format(Time.DATETIME_FORMAT_COMPACT);
162
- } else {
163
- const timestamp = dayjs.utc(utc, Time.DATETIME_FORMAT_COMPACT)
164
- .local()
165
- ;
166
- result = timestamp.format(Time.DATETIME_FORMAT_COMPACT);
167
- }
168
- return result as CompactDateTime;
169
- }
170
-
171
- // TODO: Should this actually be called localFromEpochSeconds? Passing zero
172
- // returns timestamp that is local-timezone hours offset from UTC epoch time.
173
- public static utcFromEpochSeconds(seconds:number):CompactDateTime {
174
- return dayjs.unix(seconds).utc().format(Time.DATETIME_FORMAT_COMPACT) as CompactDateTime;
175
- }
176
-
177
- public static utc(local?:CompactDateTime):CompactDateTime {
178
- let result;
179
- if (typeof(local) === "undefined") {
180
- result = dayjs.utc().format(Time.DATETIME_FORMAT_COMPACT);
181
- } else {
182
- const timestamp = dayjs(local, Time.DATETIME_FORMAT_COMPACT)
183
- .utc()
184
- ;
185
- result = timestamp.format(Time.DATETIME_FORMAT_COMPACT);
186
- }
187
- return result as CompactDateTime;
188
- }
189
-
190
- public static format(timestamp:CompactDateTime, pattern:string, isLocal:boolean):CompactDateTime {
191
- let time = null;
192
- if (isLocal) {
193
- time = dayjs(timestamp, Time.DATETIME_FORMAT_COMPACT);
194
- } else {
195
- time = dayjs.utc(timestamp, Time.DATETIME_FORMAT_COMPACT)
196
- .local()
197
- ;
198
- }
199
- return time.format(pattern) as CompactDateTime;
200
- }
201
-
202
- public static formatFromDate(date:Date, pattern:string):string {
203
- const time = dayjs(date);
204
- return time.format(pattern);
205
- }
206
-
207
- public static beautify(
208
- timestamp:CompactDateTime,
209
- isLocal:boolean = false,
210
- amount?:number,
211
- units?:string
212
- ):string {
213
- const now:any = dayjs();
214
- let time:any = null;
215
- if (isLocal) {
216
- time = dayjs(timestamp, Time.DATETIME_FORMAT_COMPACT);
217
- } else {
218
- time = dayjs.utc(timestamp, Time.DATETIME_FORMAT_COMPACT)
219
- .local()
220
- ;
221
- }
222
-
223
- // If the 'num' and 'units' params exist, then use them to manipulate the timestamp
224
- if (typeof(amount) === "number" && typeof(units) === "string") {
225
- time = time.add(amount, units);
226
- }
227
-
228
- let datePart:string = "", timePart:string = "";
229
-
230
- const timeDayOfYear:number = time.dayOfYear();
231
- const nowDayOfYear:number = now.dayOfYear();
232
- const timeYear:number = time.year();
233
- const nowYear:number = now.year();
234
- if (nowDayOfYear === timeDayOfYear && nowYear === timeYear) {
235
- datePart = "Today";
236
- } else if (nowDayOfYear - timeDayOfYear === 1 && nowYear === timeYear) {
237
- datePart = "Yesterday";
238
- } else if (nowDayOfYear === 1 && timeDayOfYear === 365 && timeYear % 4 !== 0 && nowYear - timeYear === 1) {
239
- datePart = "Yesterday";
240
- } else if (nowDayOfYear === 1 && timeDayOfYear === 366 && timeYear % 4 === 0 && nowYear - timeYear === 1) {
241
- datePart = "Yesterday";
242
-
243
- } else if (timeDayOfYear - nowDayOfYear === 1 && timeYear === nowYear) {
244
- datePart = "Tomorrow";
245
- } else if (timeDayOfYear === 1 && nowDayOfYear === 365 && nowYear % 4 !== 0 && timeYear - nowYear === 1) {
246
- datePart = "Tomorrow";
247
- } else if (timeDayOfYear === 1 && nowDayOfYear === 366 && nowYear % 4 === 0 && timeYear - nowYear === 1) {
248
- datePart = "Tomorrow";
249
-
250
- } else if (Math.abs(now.diff(time, "days")) <= 30) {
251
- datePart = time.format(Time.DATE_FULLY_BEAUTIFIED);
252
- } else {
253
- datePart = time.format(Time.DATE_BEAUTIFIED);
254
- }
255
-
256
- if (Math.abs(now.diff(time, "days")) <= 7) {
257
- timePart = time.format("h:mm a");
258
- timePart = timePart.replace(" am", "a");
259
- timePart = timePart.replace(" pm", "p");
260
- }
261
-
262
- if (timePart.length === 0) {
263
- return datePart;
264
- } else {
265
- return datePart + ", " + timePart;
266
- }
267
- }
268
-
269
- public static absDiffMinutes(a:CompactDateTime, b:CompactDateTime):number {
270
- const aMoment = dayjs(a, Time.DATETIME_FORMAT_COMPACT);
271
- const bMoment = dayjs(b, Time.DATETIME_FORMAT_COMPACT);
272
- return Math.abs(aMoment.diff(bMoment, 'minutes', true));
273
- }
274
-
275
- public static elapsed(timestamp:CompactDateTime, isLocal:boolean):string {
276
- let time = null;
277
- if (isLocal) {
278
- time = dayjs(timestamp, Time.DATETIME_FORMAT_COMPACT);
279
- } else {
280
- time = dayjs.utc(timestamp, Time.DATETIME_FORMAT_COMPACT)
281
- .local()
282
- ;
283
- }
284
- const difference = dayjs().diff(time, 'seconds');
285
- if (difference < 60) {
286
- return difference === 1 ? "1 second ago" : difference + " seconds ago";
287
- } else if (difference < 3 * 60) {
288
- const minutes = Math.floor(difference / 60);
289
- const seconds = Math.floor(difference % 60);
290
- const minText = minutes === 1 ? "1 minute" : minutes + " minutes";
291
- const secText = seconds === 1 ? "1 second" : seconds + " seconds";
292
- return minText + ", " + secText + " ago";
293
- } else if (difference < 60 * 60) {
294
- const minutes = Math.round(difference / 60);
295
- return "about " + minutes + " minutes ago";
296
- } else if (difference < 24 * 60 * 60) {
297
- const hours = Math.round(difference / (60 * 60));
298
- return "about " + hours + " hours ago";
299
- } else {
300
- return Time.beautify(timestamp, isLocal);
301
- }
302
- }
303
-
304
- public static timeUntil(utcTime:CompactDateTime, units:dayjs.UnitType):number {
305
- return - Time.timeSince(utcTime, units);
306
- }
307
-
308
- public static timeSince(utcTime:CompactDateTime, units:dayjs.UnitType):number {
309
- const then = dayjs.utc(utcTime, Time.DATETIME_FORMAT_COMPACT);
310
- const now = dayjs().utc();
311
- return now.diff(then, units, true);
312
- }
313
-
314
- public static currentYear():string {
315
- return dayjs().format(Time.YEAR_ONLY);
316
- }
317
-
318
- public static humanizedDatePacific(epochSeconds:number):string {
319
- return dayjs.unix(epochSeconds).tz("America/Los_Angeles").format("MMMM D, YYYY");
320
- }
321
-
322
- // TODO: Should this actually expect seconds instead of milliseconds?
323
- public static humanizedTimePacific(epochSeconds:number):string {
324
- return dayjs(epochSeconds).tz("America/Los_Angeles").format("h:mm:ss a") + " (Pacific)";
325
- }
326
-
327
-
328
- }
@@ -1,130 +0,0 @@
1
- import { Doc } from '@shaxpir/sharedb/lib/client';
2
- import { ShareSync, ShareSyncFactory } from '../../repo/ShareSync';
3
- import { CachingHasher } from '../../util/CachingHasher';
4
- import { BatchOperation } from '../markup/Operation';
5
- import { Content, ContentId, ContentMeta } from "./Content";
6
- import { ContentKind } from './ContentKind';
7
- import { MultiClock, MultiTime } from "./Time";
8
-
9
- export interface UserPayload {
10
- email:string;
11
- phone:string;
12
- force_password_reset:boolean;
13
- pass_md5_salt_md5:string;
14
- salt:string;
15
- }
16
-
17
- export interface ModernUserBody {
18
- meta:ContentMeta;
19
- payload:UserPayload;
20
- }
21
-
22
- export class ModernUser extends Content {
23
-
24
- public static readonly MIN_PASSWORD_LENGTH:number = 8;
25
-
26
- constructor(doc:Doc, shouldAcquire:boolean, shareSync:ShareSync) {
27
- super(doc, shouldAcquire, shareSync);
28
- }
29
-
30
- public get payload():UserPayload {
31
- return this.doc.data.payload as UserPayload;
32
- }
33
-
34
- public static create(
35
- userId:ContentId,
36
- payload:UserPayload,
37
- createdAt?:MultiTime
38
- ):ModernUser {
39
- // User creation always happens in UTC time
40
- const now = MultiClock.utcNow();
41
- // If the createdAt time is not provided, use the current time
42
- createdAt ??= now;
43
- return ShareSyncFactory.get().createContent(
44
- {
45
- meta : {
46
- ref : userId,
47
- is_head : true,
48
- kind : ContentKind.USER,
49
- id : userId,
50
- owner : userId,
51
- created_at : createdAt,
52
- updated_at : now
53
- },
54
- payload : payload
55
- }
56
- ) as ModernUser;
57
- }
58
-
59
- public get email():string {
60
- return this.payload.email;
61
- }
62
- public setEmail(value:string) {
63
- if (this.email != value) {
64
- const batch = new BatchOperation(this);
65
- batch.setPathValue([ 'payload', 'email' ] , value);
66
- batch.commit();
67
- }
68
- }
69
-
70
- public get forcePasswordReset():boolean {
71
- return this.payload.force_password_reset;
72
- }
73
- public setForcePasswordReset(value:boolean) {
74
- if (this.forcePasswordReset != value) {
75
- const batch = new BatchOperation(this);
76
- batch.setPathValue([ 'payload', 'force_password_reset' ] , value);
77
- batch.commit();
78
- }
79
- }
80
-
81
- public get passMd5SaltMd5():string {
82
- return this.payload.pass_md5_salt_md5;
83
- }
84
- public setPassMd5SaltMd5(value:string) {
85
- if (this.passMd5SaltMd5 != value) {
86
- const batch = new BatchOperation(this);
87
- batch.setPathValue([ 'payload', 'pass_md5_salt_md5' ] , value);
88
- batch.commit();
89
- }
90
- }
91
-
92
- public get salt():string {
93
- return this.payload.salt;
94
- }
95
-
96
- public hasValidPassword(password:string):boolean {
97
- const passMd5 = ModernUser.makePassMd5(password);
98
- return this.hasValidPassMd5(passMd5);
99
- }
100
-
101
- public hasValidPassMd5(passMd5:string):boolean {
102
- return ModernUser.isValidPassMd5(passMd5, this.payload);
103
- }
104
-
105
- public static makePassMd5SaltMd5(salt:string, password:string):string {
106
- const passMd5 = ModernUser.makePassMd5(password);
107
- return ModernUser.addSaltToPassMd5(salt, passMd5);
108
- }
109
-
110
- public static addSaltToPassMd5(salt:string, passMd5:string):string {
111
- return CachingHasher.makeMd5Hash(passMd5 + salt);
112
- }
113
-
114
- public static makePassMd5(password:string):string {
115
- return CachingHasher.makeMd5Hash(password);
116
- }
117
-
118
- public static isValidPassMd5(passMd5:string, userPayload:UserPayload):boolean {
119
- const passMd5SaltMd5 = ModernUser.addSaltToPassMd5(userPayload.salt, passMd5);
120
- return passMd5SaltMd5 === userPayload.pass_md5_salt_md5;
121
- }
122
-
123
- public static async findByEmail(email:string):Promise<ModernUser[]> {
124
- const shareSync = ShareSyncFactory.get();
125
- return shareSync.findAndAcquire(
126
- ContentKind.USER, { "payload.email" : email }
127
- ) as Promise<ModernUser[]>;
128
- }
129
-
130
- }
@@ -1,19 +0,0 @@
1
- // created from 'create-ts-index'
2
-
3
- export * from './ArrayView';
4
- export * from './Billing';
5
- export * from './Content';
6
- export * from './ContentKind';
7
- export * from './DevEnv';
8
- export * from './Device';
9
- export * from './DictionaryEntry';
10
- export * from './GeoLocation';
11
- export * from './Hanzi';
12
- export * from './Manifest';
13
- export * from './Media';
14
- export * from './Model';
15
- export * from './Permissions';
16
- export * from './Phrase';
17
- export * from './Profile';
18
- export * from './Time';
19
- export * from './User';
@@ -1,71 +0,0 @@
1
- import { AttributeMap, Op as DeltaOp } from "@shaxpir/quill-delta";
2
- import { Struct } from "../../util/Struct";
3
-
4
- export class DeltaOpsModel {
5
-
6
- private static readonly BLOCK_ATTR_KEYS:any = {
7
- "align" : true,
8
- "blockquote" : true,
9
- "header" : true,
10
- "indent" : true,
11
- "list" : true,
12
- "caption" : true,
13
- };
14
-
15
- public static splitOnNewlines(ops:DeltaOp[]):DeltaOp[] {
16
- let newOps:DeltaOp[] = [];
17
- for (let i:number = 0, iLen:number = ops.length; i < iLen; i++) {
18
- let op:DeltaOp = ops[i];
19
- let text:any = "\n";
20
- let embed:AttributeMap = null;
21
- let blockAttr:AttributeMap = null;
22
- let rangeAttr:AttributeMap = null;
23
- if (typeof(op.insert) === "string") {
24
- text = op.insert;
25
- if (op.hasOwnProperty("attributes")) {
26
- for (let key in op.attributes) {
27
- let val:any = (op.attributes as any)[key];
28
- if (DeltaOpsModel.BLOCK_ATTR_KEYS.hasOwnProperty(key)) {
29
- if (blockAttr == null) {
30
- blockAttr = {};
31
- }
32
- (blockAttr as any)[key] = val;
33
- } else {
34
- if (rangeAttr == null) {
35
- rangeAttr = {};
36
- }
37
- (rangeAttr as any)[key] = val;
38
- }
39
- }
40
-
41
- }
42
- } else if (op.hasOwnProperty("insert")) {
43
- embed = Struct.clone(op.insert);
44
- }
45
- let parts:string[] = text.split(/(\n)/g);
46
- let nonEmptyParts:string[] = [];
47
- for (let j:number = 0, jLen:number = parts.length; j < jLen; j++) {
48
- let part:string = parts[j];
49
- if (part.length > 0) {
50
- nonEmptyParts.push(part);
51
- }
52
- }
53
- parts = nonEmptyParts;
54
- for (let j:number = 0, jLen:number = parts.length, jLast = jLen - 1; j < jLen; j++) {
55
- let part:string = parts[j];
56
- let newOp:DeltaOp = { "insert" : part, "attributes" : {} };
57
- if (embed !== null) {
58
- newOp.insert = embed;
59
- } else if (part === "\n") {
60
- if (j === jLast && blockAttr != null) {
61
- newOp.attributes = blockAttr;
62
- }
63
- } else if (rangeAttr != null) {
64
- newOp.attributes = rangeAttr;
65
- }
66
- newOps.push(newOp);
67
- }
68
- }
69
- return newOps;
70
- }
71
- }
@@ -1,6 +0,0 @@
1
- // created from 'create-ts-index'
2
-
3
- export * from './ChangeModel';
4
- export * from './DeltaOps';
5
- export * from './Operation';
6
- export * from './TextEditOps';
@@ -1,47 +0,0 @@
1
- export class Base62 {
2
-
3
- public static readonly CHARS:string = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
4
-
5
- public static encode(value:number, padToLength:number = 1):string {
6
- if (value < 0) {
7
- throw new Error("number out of range: " + value);
8
- }
9
- let result:string = "";
10
- while (value > 0) {
11
- let index:number = value % 62;
12
- let digit:string = Base62.CHARS.charAt(index);
13
- result = digit + result;
14
- value = Math.floor(value / 62);
15
- }
16
- while (result.length < padToLength) {
17
- result = "0" + result;
18
- }
19
- return result;
20
- }
21
-
22
- public static decode(value:string) {
23
- let result = 0;
24
- for (let i:number = 0, len:number = value.length; i < len; i++) {
25
- let c:string = value.charAt(i);
26
- result *= 62;
27
- result += Base62.CHARS.indexOf(c);
28
- }
29
- return result;
30
- }
31
-
32
- public static fromHexHash(hex:string, length:number):string {
33
- // NOTE: the crazy one-liner below is equivalent to this commented code...
34
- // const b64 = Buffer.from(hex, 'hex').toString('base64');
35
- // ...but it doesn't require Buffer class, which is only available in Node.js, not in browsers.
36
- // This one-liner came from stackoverflow: https://stackoverflow.com/questions/23190056/hex-to-base64-converter-for-javascript
37
- const b64 = btoa(hex.match(/\w{2}/g).map((a) => { return String.fromCharCode(parseInt(a, 16)) }).join(""));
38
- let alphanum = b64.replace(/[^a-zA-Z0-9]/g, "");
39
- if (alphanum.length < length) {
40
- alphanum = alphanum.padEnd(length, "0");
41
- } else if (alphanum.length > length) {
42
- alphanum = alphanum.substring(0, length);
43
- }
44
- return alphanum;
45
- }
46
-
47
- }
@@ -1,38 +0,0 @@
1
- import md5 from 'md5';
2
- import { ContentId } from '../models/content/Content';
3
- import { Base62 } from './Base62';
4
-
5
- export class CachingHasher {
6
-
7
- private static readonly MAX_SIZE:number = 1000;
8
-
9
- private static md5HashLookup:Map<string, string> = new Map<string, string>();
10
- private static contentIdLookup:Map<string, ContentId> = new Map<string, ContentId>();
11
-
12
- public static makeMd5Hash(text:string):string {
13
- if (CachingHasher.md5HashLookup.size > CachingHasher.MAX_SIZE) {
14
- CachingHasher.md5HashLookup.clear();
15
- }
16
- if (CachingHasher.md5HashLookup.has(text)) {
17
- return CachingHasher.md5HashLookup.get(text);
18
- } else {
19
- const rawHash = md5(text);
20
- this.md5HashLookup.set(text, rawHash);
21
- return rawHash;
22
- }
23
- }
24
-
25
- public static makeMd5ContentId(text:string):ContentId {
26
- if (CachingHasher.contentIdLookup.size > CachingHasher.MAX_SIZE) {
27
- CachingHasher.contentIdLookup.clear();
28
- }
29
- if (CachingHasher.contentIdLookup.has(text)) {
30
- return CachingHasher.contentIdLookup.get(text);
31
- } else {
32
- const rawHash = md5(text);
33
- const asBase62 = Base62.fromHexHash(rawHash, 16) as ContentId;
34
- this.contentIdLookup.set(text, asBase62);
35
- return asBase62;
36
- }
37
- }
38
- }