@real1ty-obsidian-plugins/utils 2.29.0 → 2.30.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 (237) hide show
  1. package/package.json +1 -1
  2. package/dist/async/async.d.ts +0 -69
  3. package/dist/async/async.d.ts.map +0 -1
  4. package/dist/async/async.js +0 -108
  5. package/dist/async/async.js.map +0 -1
  6. package/dist/async/batch-operations.d.ts +0 -21
  7. package/dist/async/batch-operations.d.ts.map +0 -1
  8. package/dist/async/batch-operations.js +0 -60
  9. package/dist/async/batch-operations.js.map +0 -1
  10. package/dist/async/change-notifier.d.ts +0 -13
  11. package/dist/async/change-notifier.d.ts.map +0 -1
  12. package/dist/async/change-notifier.js +0 -26
  13. package/dist/async/change-notifier.js.map +0 -1
  14. package/dist/async/debounced-notifier.d.ts +0 -26
  15. package/dist/async/debounced-notifier.d.ts.map +0 -1
  16. package/dist/async/debounced-notifier.js +0 -50
  17. package/dist/async/debounced-notifier.js.map +0 -1
  18. package/dist/async/index.d.ts +0 -5
  19. package/dist/async/index.d.ts.map +0 -1
  20. package/dist/async/index.js +0 -5
  21. package/dist/async/index.js.map +0 -1
  22. package/dist/components/frontmatter-propagation-modal.d.ts +0 -17
  23. package/dist/components/frontmatter-propagation-modal.d.ts.map +0 -1
  24. package/dist/components/frontmatter-propagation-modal.js +0 -85
  25. package/dist/components/frontmatter-propagation-modal.js.map +0 -1
  26. package/dist/components/index.d.ts +0 -5
  27. package/dist/components/index.d.ts.map +0 -1
  28. package/dist/components/index.js +0 -5
  29. package/dist/components/index.js.map +0 -1
  30. package/dist/components/input-managers/base.d.ts +0 -30
  31. package/dist/components/input-managers/base.d.ts.map +0 -1
  32. package/dist/components/input-managers/base.js +0 -115
  33. package/dist/components/input-managers/base.js.map +0 -1
  34. package/dist/components/input-managers/expression.d.ts +0 -12
  35. package/dist/components/input-managers/expression.d.ts.map +0 -1
  36. package/dist/components/input-managers/expression.js +0 -56
  37. package/dist/components/input-managers/expression.js.map +0 -1
  38. package/dist/components/input-managers/index.d.ts +0 -4
  39. package/dist/components/input-managers/index.d.ts.map +0 -1
  40. package/dist/components/input-managers/index.js +0 -4
  41. package/dist/components/input-managers/index.js.map +0 -1
  42. package/dist/components/input-managers/search.d.ts +0 -6
  43. package/dist/components/input-managers/search.d.ts.map +0 -1
  44. package/dist/components/input-managers/search.js +0 -16
  45. package/dist/components/input-managers/search.js.map +0 -1
  46. package/dist/components/registered-events-component.d.ts +0 -30
  47. package/dist/components/registered-events-component.d.ts.map +0 -1
  48. package/dist/components/registered-events-component.js +0 -43
  49. package/dist/components/registered-events-component.js.map +0 -1
  50. package/dist/components/whats-new-modal.d.ts +0 -64
  51. package/dist/components/whats-new-modal.d.ts.map +0 -1
  52. package/dist/components/whats-new-modal.js +0 -139
  53. package/dist/components/whats-new-modal.js.map +0 -1
  54. package/dist/core/color-utils.d.ts +0 -17
  55. package/dist/core/color-utils.d.ts.map +0 -1
  56. package/dist/core/color-utils.js +0 -29
  57. package/dist/core/color-utils.js.map +0 -1
  58. package/dist/core/css-utils.d.ts +0 -39
  59. package/dist/core/css-utils.d.ts.map +0 -1
  60. package/dist/core/css-utils.js +0 -60
  61. package/dist/core/css-utils.js.map +0 -1
  62. package/dist/core/evaluator/base.d.ts +0 -22
  63. package/dist/core/evaluator/base.d.ts.map +0 -1
  64. package/dist/core/evaluator/base.js +0 -67
  65. package/dist/core/evaluator/base.js.map +0 -1
  66. package/dist/core/evaluator/color.d.ts +0 -19
  67. package/dist/core/evaluator/color.d.ts.map +0 -1
  68. package/dist/core/evaluator/color.js +0 -25
  69. package/dist/core/evaluator/color.js.map +0 -1
  70. package/dist/core/evaluator/excluded.d.ts +0 -32
  71. package/dist/core/evaluator/excluded.d.ts.map +0 -1
  72. package/dist/core/evaluator/excluded.js +0 -41
  73. package/dist/core/evaluator/excluded.js.map +0 -1
  74. package/dist/core/evaluator/filter.d.ts +0 -15
  75. package/dist/core/evaluator/filter.d.ts.map +0 -1
  76. package/dist/core/evaluator/filter.js +0 -27
  77. package/dist/core/evaluator/filter.js.map +0 -1
  78. package/dist/core/evaluator/included.d.ts +0 -36
  79. package/dist/core/evaluator/included.d.ts.map +0 -1
  80. package/dist/core/evaluator/included.js +0 -51
  81. package/dist/core/evaluator/included.js.map +0 -1
  82. package/dist/core/evaluator/index.d.ts +0 -6
  83. package/dist/core/evaluator/index.d.ts.map +0 -1
  84. package/dist/core/evaluator/index.js +0 -6
  85. package/dist/core/evaluator/index.js.map +0 -1
  86. package/dist/core/expression-utils.d.ts +0 -17
  87. package/dist/core/expression-utils.d.ts.map +0 -1
  88. package/dist/core/expression-utils.js +0 -40
  89. package/dist/core/expression-utils.js.map +0 -1
  90. package/dist/core/frontmatter-value.d.ts +0 -157
  91. package/dist/core/frontmatter-value.d.ts.map +0 -1
  92. package/dist/core/frontmatter-value.js +0 -417
  93. package/dist/core/frontmatter-value.js.map +0 -1
  94. package/dist/core/generate.d.ts +0 -7
  95. package/dist/core/generate.d.ts.map +0 -1
  96. package/dist/core/generate.js +0 -13
  97. package/dist/core/generate.js.map +0 -1
  98. package/dist/core/history.d.ts +0 -12
  99. package/dist/core/history.d.ts.map +0 -1
  100. package/dist/core/history.js +0 -39
  101. package/dist/core/history.js.map +0 -1
  102. package/dist/core/index.d.ts +0 -11
  103. package/dist/core/index.d.ts.map +0 -1
  104. package/dist/core/index.js +0 -11
  105. package/dist/core/index.js.map +0 -1
  106. package/dist/core/indexer.d.ts +0 -109
  107. package/dist/core/indexer.d.ts.map +0 -1
  108. package/dist/core/indexer.js +0 -185
  109. package/dist/core/indexer.js.map +0 -1
  110. package/dist/core/property-renderer.d.ts +0 -9
  111. package/dist/core/property-renderer.d.ts.map +0 -1
  112. package/dist/core/property-renderer.js +0 -42
  113. package/dist/core/property-renderer.js.map +0 -1
  114. package/dist/core/validation.d.ts +0 -13
  115. package/dist/core/validation.d.ts.map +0 -1
  116. package/dist/core/validation.js +0 -27
  117. package/dist/core/validation.js.map +0 -1
  118. package/dist/date/date-recurrence.d.ts +0 -30
  119. package/dist/date/date-recurrence.d.ts.map +0 -1
  120. package/dist/date/date-recurrence.js +0 -188
  121. package/dist/date/date-recurrence.js.map +0 -1
  122. package/dist/date/date.d.ts +0 -21
  123. package/dist/date/date.d.ts.map +0 -1
  124. package/dist/date/date.js +0 -105
  125. package/dist/date/date.js.map +0 -1
  126. package/dist/date/index.d.ts +0 -3
  127. package/dist/date/index.d.ts.map +0 -1
  128. package/dist/date/index.js +0 -3
  129. package/dist/date/index.js.map +0 -1
  130. package/dist/file/child-reference.d.ts +0 -9
  131. package/dist/file/child-reference.d.ts.map +0 -1
  132. package/dist/file/child-reference.js +0 -57
  133. package/dist/file/child-reference.js.map +0 -1
  134. package/dist/file/file-operations.d.ts +0 -31
  135. package/dist/file/file-operations.d.ts.map +0 -1
  136. package/dist/file/file-operations.js +0 -160
  137. package/dist/file/file-operations.js.map +0 -1
  138. package/dist/file/file-utils.d.ts +0 -33
  139. package/dist/file/file-utils.d.ts.map +0 -1
  140. package/dist/file/file-utils.js +0 -76
  141. package/dist/file/file-utils.js.map +0 -1
  142. package/dist/file/file.d.ts +0 -332
  143. package/dist/file/file.d.ts.map +0 -1
  144. package/dist/file/file.js +0 -559
  145. package/dist/file/file.js.map +0 -1
  146. package/dist/file/frontmatter-diff.d.ts +0 -38
  147. package/dist/file/frontmatter-diff.d.ts.map +0 -1
  148. package/dist/file/frontmatter-diff.js +0 -162
  149. package/dist/file/frontmatter-diff.js.map +0 -1
  150. package/dist/file/frontmatter-propagation.d.ts +0 -4
  151. package/dist/file/frontmatter-propagation.d.ts.map +0 -1
  152. package/dist/file/frontmatter-propagation.js +0 -28
  153. package/dist/file/frontmatter-propagation.js.map +0 -1
  154. package/dist/file/frontmatter-serialization.d.ts +0 -21
  155. package/dist/file/frontmatter-serialization.d.ts.map +0 -1
  156. package/dist/file/frontmatter-serialization.js +0 -57
  157. package/dist/file/frontmatter-serialization.js.map +0 -1
  158. package/dist/file/frontmatter.d.ts +0 -15
  159. package/dist/file/frontmatter.d.ts.map +0 -1
  160. package/dist/file/frontmatter.js +0 -68
  161. package/dist/file/frontmatter.js.map +0 -1
  162. package/dist/file/index.d.ts +0 -13
  163. package/dist/file/index.d.ts.map +0 -1
  164. package/dist/file/index.js +0 -13
  165. package/dist/file/index.js.map +0 -1
  166. package/dist/file/link-parser.d.ts +0 -63
  167. package/dist/file/link-parser.d.ts.map +0 -1
  168. package/dist/file/link-parser.js +0 -137
  169. package/dist/file/link-parser.js.map +0 -1
  170. package/dist/file/property-utils.d.ts +0 -55
  171. package/dist/file/property-utils.d.ts.map +0 -1
  172. package/dist/file/property-utils.js +0 -90
  173. package/dist/file/property-utils.js.map +0 -1
  174. package/dist/file/templater-service.d.ts +0 -16
  175. package/dist/file/templater-service.d.ts.map +0 -1
  176. package/dist/file/templater-service.js +0 -37
  177. package/dist/file/templater-service.js.map +0 -1
  178. package/dist/file/templater.d.ts +0 -28
  179. package/dist/file/templater.d.ts.map +0 -1
  180. package/dist/file/templater.js +0 -126
  181. package/dist/file/templater.js.map +0 -1
  182. package/dist/index.d.ts +0 -9
  183. package/dist/index.d.ts.map +0 -1
  184. package/dist/index.js +0 -17
  185. package/dist/index.js.map +0 -1
  186. package/dist/inputs/index.d.ts +0 -2
  187. package/dist/inputs/index.d.ts.map +0 -1
  188. package/dist/inputs/index.js +0 -2
  189. package/dist/inputs/index.js.map +0 -1
  190. package/dist/inputs/input-filter-manager.d.ts +0 -72
  191. package/dist/inputs/input-filter-manager.d.ts.map +0 -1
  192. package/dist/inputs/input-filter-manager.js +0 -140
  193. package/dist/inputs/input-filter-manager.js.map +0 -1
  194. package/dist/settings/index.d.ts +0 -3
  195. package/dist/settings/index.d.ts.map +0 -1
  196. package/dist/settings/index.js +0 -3
  197. package/dist/settings/index.js.map +0 -1
  198. package/dist/settings/settings-store.d.ts +0 -20
  199. package/dist/settings/settings-store.d.ts.map +0 -1
  200. package/dist/settings/settings-store.js +0 -82
  201. package/dist/settings/settings-store.js.map +0 -1
  202. package/dist/settings/settings-ui-builder.d.ts +0 -74
  203. package/dist/settings/settings-ui-builder.d.ts.map +0 -1
  204. package/dist/settings/settings-ui-builder.js +0 -436
  205. package/dist/settings/settings-ui-builder.js.map +0 -1
  206. package/dist/string/changelog-parser.d.ts +0 -17
  207. package/dist/string/changelog-parser.d.ts.map +0 -1
  208. package/dist/string/changelog-parser.js +0 -77
  209. package/dist/string/changelog-parser.js.map +0 -1
  210. package/dist/string/filename-utils.d.ts +0 -46
  211. package/dist/string/filename-utils.d.ts.map +0 -1
  212. package/dist/string/filename-utils.js +0 -65
  213. package/dist/string/filename-utils.js.map +0 -1
  214. package/dist/string/index.d.ts +0 -4
  215. package/dist/string/index.d.ts.map +0 -1
  216. package/dist/string/index.js +0 -4
  217. package/dist/string/index.js.map +0 -1
  218. package/dist/string/string.d.ts +0 -5
  219. package/dist/string/string.d.ts.map +0 -1
  220. package/dist/string/string.js +0 -25
  221. package/dist/string/string.js.map +0 -1
  222. package/dist/testing/index.d.ts +0 -5
  223. package/dist/testing/index.d.ts.map +0 -1
  224. package/dist/testing/index.js +0 -6
  225. package/dist/testing/index.js.map +0 -1
  226. package/dist/testing/mocks/obsidian.d.ts +0 -150
  227. package/dist/testing/mocks/obsidian.d.ts.map +0 -1
  228. package/dist/testing/mocks/obsidian.js +0 -226
  229. package/dist/testing/mocks/obsidian.js.map +0 -1
  230. package/dist/testing/mocks/utils.d.ts +0 -14
  231. package/dist/testing/mocks/utils.d.ts.map +0 -1
  232. package/dist/testing/mocks/utils.js +0 -85
  233. package/dist/testing/mocks/utils.js.map +0 -1
  234. package/dist/testing/setup.d.ts +0 -2
  235. package/dist/testing/setup.d.ts.map +0 -1
  236. package/dist/testing/setup.js +0 -18
  237. package/dist/testing/setup.js.map +0 -1
@@ -1,27 +0,0 @@
1
- /**
2
- * Checks if a value is not empty.
3
- * Returns false for: undefined, null, empty string, or empty arrays.
4
- * Returns true for all other values.
5
- */
6
- export function isNotEmpty(value) {
7
- if (value === undefined || value === null || value === "") {
8
- return false;
9
- }
10
- if (Array.isArray(value) && value.length === 0) {
11
- return false;
12
- }
13
- return true;
14
- }
15
- /**
16
- * Parses a value to a positive integer.
17
- * Handles both number and string types from frontmatter.
18
- * Returns the parsed integer if valid and positive, otherwise returns the fallback value.
19
- */
20
- export function parsePositiveInt(value, fallback) {
21
- if (value === undefined || value === null) {
22
- return fallback;
23
- }
24
- const parsed = typeof value === "number" ? Math.floor(value) : Number.parseInt(String(value), 10);
25
- return !Number.isNaN(parsed) && parsed > 0 ? parsed : fallback;
26
- }
27
- //# sourceMappingURL=validation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAc;IACxC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QAC3D,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc,EAAE,QAAgB;IAChE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC3C,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAClG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AAChE,CAAC","sourcesContent":["/**\n * Checks if a value is not empty.\n * Returns false for: undefined, null, empty string, or empty arrays.\n * Returns true for all other values.\n */\nexport function isNotEmpty(value: unknown): boolean {\n\tif (value === undefined || value === null || value === \"\") {\n\t\treturn false;\n\t}\n\tif (Array.isArray(value) && value.length === 0) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/**\n * Parses a value to a positive integer.\n * Handles both number and string types from frontmatter.\n * Returns the parsed integer if valid and positive, otherwise returns the fallback value.\n */\nexport function parsePositiveInt(value: unknown, fallback: number): number {\n\tif (value === undefined || value === null) {\n\t\treturn fallback;\n\t}\n\tconst parsed = typeof value === \"number\" ? Math.floor(value) : Number.parseInt(String(value), 10);\n\treturn !Number.isNaN(parsed) && parsed > 0 ? parsed : fallback;\n}\n"]}
@@ -1,30 +0,0 @@
1
- import type { DateTime } from "luxon";
2
- export type RecurrenceType = "daily" | "weekly" | "bi-weekly" | "monthly" | "bi-monthly" | "yearly";
3
- export type Weekday = "sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday";
4
- export declare const WEEKDAY_TO_NUMBER: Record<Weekday, number>;
5
- /**
6
- * Calculates the next occurrence date based on recurrence type and optional weekdays
7
- */
8
- export declare function getNextOccurrence(currentDate: DateTime, recurrenceType: RecurrenceType, weekdays?: Weekday[]): DateTime;
9
- /**
10
- * Checks if a given date matches any of the specified weekdays
11
- */
12
- export declare function isDateOnWeekdays(date: DateTime, weekdays: Weekday[]): boolean;
13
- /**
14
- * Finds the next occurrence on specified weekdays
15
- */
16
- export declare function getNextWeekdayOccurrence(currentDate: DateTime, weekdays: Weekday[]): DateTime;
17
- /**
18
- * Finds the next bi-weekly occurrence on specified weekdays
19
- */
20
- export declare function getNextBiWeeklyOccurrence(currentDate: DateTime, weekdays: Weekday[]): DateTime;
21
- export declare function iterateOccurrencesInRange(startDate: DateTime, rrules: {
22
- type: RecurrenceType;
23
- weekdays?: Weekday[];
24
- }, rangeStart: DateTime, rangeEnd: DateTime): Generator<DateTime, void, unknown>;
25
- /**
26
- * Calculates a DateTime for a specific date with optional time
27
- */
28
- export declare function calculateInstanceDateTime(instanceDate: DateTime, timeString?: string): DateTime;
29
- export declare function calculateRecurringInstanceDateTime(nextInstanceDateTime: DateTime, nodeRecuringEventDateTime: DateTime, recurrenceType: RecurrenceType, allDay?: boolean): DateTime;
30
- //# sourceMappingURL=date-recurrence.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"date-recurrence.d.ts","sourceRoot":"","sources":["../../src/date/date-recurrence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEtC,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,QAAQ,CAAC;AAEpG,MAAM,MAAM,OAAO,GAChB,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,WAAW,GACX,UAAU,GACV,QAAQ,GACR,UAAU,CAAC;AAEd,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAQrD,CAAC;AAEF;;GAEG;AACH,wBAAgB,iBAAiB,CAChC,WAAW,EAAE,QAAQ,EACrB,cAAc,EAAE,cAAc,EAC9B,QAAQ,CAAC,EAAE,OAAO,EAAE,GAClB,QAAQ,CAuBV;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAQ7E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,QAAQ,CAgB7F;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,QAAQ,CAI9F;AAED,wBAAiB,yBAAyB,CACzC,SAAS,EAAE,QAAQ,EACnB,MAAM,EAAE;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;CAAE,EACtD,UAAU,EAAE,QAAQ,EACpB,QAAQ,EAAE,QAAQ,GAChB,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CA+DpC;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,CAO/F;AAED,wBAAgB,kCAAkC,CACjD,oBAAoB,EAAE,QAAQ,EAC9B,yBAAyB,EAAE,QAAQ,EACnC,cAAc,EAAE,cAAc,EAC9B,MAAM,CAAC,EAAE,OAAO,GACd,QAAQ,CA0DV"}
@@ -1,188 +0,0 @@
1
- export const WEEKDAY_TO_NUMBER = {
2
- sunday: 0,
3
- monday: 1,
4
- tuesday: 2,
5
- wednesday: 3,
6
- thursday: 4,
7
- friday: 5,
8
- saturday: 6,
9
- };
10
- /**
11
- * Calculates the next occurrence date based on recurrence type and optional weekdays
12
- */
13
- export function getNextOccurrence(currentDate, recurrenceType, weekdays) {
14
- switch (recurrenceType) {
15
- case "daily":
16
- return currentDate.plus({ days: 1 });
17
- case "weekly":
18
- if (weekdays && weekdays.length > 0) {
19
- return getNextWeekdayOccurrence(currentDate, weekdays);
20
- }
21
- return currentDate.plus({ weeks: 1 });
22
- case "bi-weekly":
23
- if (weekdays && weekdays.length > 0) {
24
- return getNextBiWeeklyOccurrence(currentDate, weekdays);
25
- }
26
- return currentDate.plus({ weeks: 2 });
27
- case "monthly":
28
- return currentDate.plus({ months: 1 });
29
- case "bi-monthly":
30
- return currentDate.plus({ months: 2 });
31
- case "yearly":
32
- return currentDate.plus({ years: 1 });
33
- default:
34
- return currentDate.plus({ days: 1 });
35
- }
36
- }
37
- /**
38
- * Checks if a given date matches any of the specified weekdays
39
- */
40
- export function isDateOnWeekdays(date, weekdays) {
41
- const dateWeekday = date.weekday;
42
- const luxonWeekdays = weekdays.map((day) => {
43
- const dayNumber = WEEKDAY_TO_NUMBER[day];
44
- return dayNumber === 0 ? 7 : dayNumber; // Convert Sunday from 0 to 7 for Luxon
45
- });
46
- return luxonWeekdays.includes(dateWeekday);
47
- }
48
- /**
49
- * Finds the next occurrence on specified weekdays
50
- */
51
- export function getNextWeekdayOccurrence(currentDate, weekdays) {
52
- const currentWeekday = currentDate.weekday;
53
- const luxonWeekdays = weekdays.map((day) => {
54
- const dayNumber = WEEKDAY_TO_NUMBER[day];
55
- return dayNumber === 0 ? 7 : dayNumber; // Convert Sunday from 0 to 7 for Luxon
56
- });
57
- // Find next weekday in the current week (after today)
58
- const nextWeekday = luxonWeekdays.find((day) => day > currentWeekday);
59
- if (nextWeekday) {
60
- return currentDate.set({ weekday: nextWeekday });
61
- }
62
- // No more weekdays this week, go to first weekday of next week
63
- const firstWeekday = Math.min(...luxonWeekdays);
64
- return currentDate.plus({ weeks: 1 }).set({ weekday: firstWeekday });
65
- }
66
- /**
67
- * Finds the next bi-weekly occurrence on specified weekdays
68
- */
69
- export function getNextBiWeeklyOccurrence(currentDate, weekdays) {
70
- const nextWeekly = getNextWeekdayOccurrence(currentDate, weekdays);
71
- // Add one more week to make it bi-weekly
72
- return nextWeekly.plus({ weeks: 1 });
73
- }
74
- export function* iterateOccurrencesInRange(startDate, rrules, rangeStart, rangeEnd) {
75
- // Normalize to start of day for comparison
76
- const normalizedStart = startDate.startOf("day");
77
- const normalizedRangeStart = rangeStart.startOf("day");
78
- const normalizedRangeEnd = rangeEnd.startOf("day");
79
- // Start from the later of startDate or rangeStart
80
- let currentDate = normalizedStart >= normalizedRangeStart ? normalizedStart : normalizedRangeStart;
81
- // For weekly/bi-weekly with weekdays, we need to track which week we're in
82
- if ((rrules.type === "weekly" || rrules.type === "bi-weekly") &&
83
- rrules.weekdays &&
84
- rrules.weekdays.length > 0) {
85
- // Calculate week offset from start date
86
- const weeksFromStart = Math.floor(currentDate.diff(normalizedStart, "weeks").weeks);
87
- // For bi-weekly, we only want even weeks (0, 2, 4...) from the start date
88
- const weekInterval = rrules.type === "bi-weekly" ? 2 : 1;
89
- // Adjust to the correct week if we're in an off-week
90
- const weekOffset = weeksFromStart % weekInterval;
91
- if (weekOffset !== 0) {
92
- currentDate = currentDate.plus({ weeks: weekInterval - weekOffset });
93
- }
94
- // Now iterate through weeks, checking each day
95
- while (currentDate <= normalizedRangeEnd) {
96
- // Check all 7 days of the current week
97
- for (let dayOffset = 0; dayOffset < 7; dayOffset++) {
98
- const checkDate = currentDate.plus({ days: dayOffset });
99
- // Only yield if within range and matches a target weekday
100
- if (checkDate >= normalizedRangeStart &&
101
- checkDate <= normalizedRangeEnd &&
102
- isDateOnWeekdays(checkDate, rrules.weekdays)) {
103
- yield checkDate;
104
- }
105
- }
106
- // Move to next occurrence week (1 week for weekly, 2 weeks for bi-weekly)
107
- currentDate = currentDate.plus({ weeks: weekInterval });
108
- }
109
- }
110
- else {
111
- // For other recurrence types (daily, monthly, yearly, or weekly without weekdays)
112
- while (currentDate <= normalizedRangeEnd) {
113
- if (currentDate >= normalizedRangeStart) {
114
- yield currentDate;
115
- }
116
- const nextDate = getNextOccurrence(currentDate, rrules.type, rrules.weekdays);
117
- if (nextDate <= normalizedRangeEnd) {
118
- currentDate = nextDate;
119
- }
120
- else {
121
- break;
122
- }
123
- }
124
- }
125
- }
126
- /**
127
- * Calculates a DateTime for a specific date with optional time
128
- */
129
- export function calculateInstanceDateTime(instanceDate, timeString) {
130
- if (!timeString) {
131
- return instanceDate.startOf("day");
132
- }
133
- const [hours, minutes] = timeString.split(":").map(Number);
134
- return instanceDate.set({ hour: hours, minute: minutes, second: 0, millisecond: 0 });
135
- }
136
- export function calculateRecurringInstanceDateTime(nextInstanceDateTime, nodeRecuringEventDateTime, recurrenceType, allDay) {
137
- // Convert the original event time to the target timezone once to preserve local time
138
- const originalInTargetZone = nodeRecuringEventDateTime.setZone(nextInstanceDateTime.zone);
139
- switch (recurrenceType) {
140
- case "daily":
141
- case "weekly":
142
- case "bi-weekly": {
143
- if (allDay) {
144
- return nextInstanceDateTime.startOf("day");
145
- }
146
- return nextInstanceDateTime.set({
147
- hour: originalInTargetZone.hour,
148
- minute: originalInTargetZone.minute,
149
- second: 0,
150
- millisecond: 0,
151
- });
152
- }
153
- case "monthly":
154
- case "bi-monthly": {
155
- if (allDay) {
156
- return nextInstanceDateTime.set({ day: originalInTargetZone.day }).startOf("day");
157
- }
158
- return nextInstanceDateTime.set({
159
- day: originalInTargetZone.day,
160
- hour: originalInTargetZone.hour,
161
- minute: originalInTargetZone.minute,
162
- second: 0,
163
- millisecond: 0,
164
- });
165
- }
166
- case "yearly": {
167
- if (allDay) {
168
- return nextInstanceDateTime
169
- .set({
170
- month: originalInTargetZone.month,
171
- day: originalInTargetZone.day,
172
- })
173
- .startOf("day");
174
- }
175
- return nextInstanceDateTime.set({
176
- month: originalInTargetZone.month,
177
- day: originalInTargetZone.day,
178
- hour: originalInTargetZone.hour,
179
- minute: originalInTargetZone.minute,
180
- second: 0,
181
- millisecond: 0,
182
- });
183
- }
184
- default:
185
- return nextInstanceDateTime.startOf("day");
186
- }
187
- }
188
- //# sourceMappingURL=date-recurrence.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"date-recurrence.js","sourceRoot":"","sources":["../../src/date/date-recurrence.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DateTime } from \"luxon\";\n\nexport type RecurrenceType = \"daily\" | \"weekly\" | \"bi-weekly\" | \"monthly\" | \"bi-monthly\" | \"yearly\";\n\nexport type Weekday =\n\t| \"sunday\"\n\t| \"monday\"\n\t| \"tuesday\"\n\t| \"wednesday\"\n\t| \"thursday\"\n\t| \"friday\"\n\t| \"saturday\";\n\nexport const WEEKDAY_TO_NUMBER: Record<Weekday, number> = {\n\tsunday: 0,\n\tmonday: 1,\n\ttuesday: 2,\n\twednesday: 3,\n\tthursday: 4,\n\tfriday: 5,\n\tsaturday: 6,\n};\n\n/**\n * Calculates the next occurrence date based on recurrence type and optional weekdays\n */\nexport function getNextOccurrence(\n\tcurrentDate: DateTime,\n\trecurrenceType: RecurrenceType,\n\tweekdays?: Weekday[]\n): DateTime {\n\tswitch (recurrenceType) {\n\t\tcase \"daily\":\n\t\t\treturn currentDate.plus({ days: 1 });\n\t\tcase \"weekly\":\n\t\t\tif (weekdays && weekdays.length > 0) {\n\t\t\t\treturn getNextWeekdayOccurrence(currentDate, weekdays);\n\t\t\t}\n\t\t\treturn currentDate.plus({ weeks: 1 });\n\t\tcase \"bi-weekly\":\n\t\t\tif (weekdays && weekdays.length > 0) {\n\t\t\t\treturn getNextBiWeeklyOccurrence(currentDate, weekdays);\n\t\t\t}\n\t\t\treturn currentDate.plus({ weeks: 2 });\n\t\tcase \"monthly\":\n\t\t\treturn currentDate.plus({ months: 1 });\n\t\tcase \"bi-monthly\":\n\t\t\treturn currentDate.plus({ months: 2 });\n\t\tcase \"yearly\":\n\t\t\treturn currentDate.plus({ years: 1 });\n\t\tdefault:\n\t\t\treturn currentDate.plus({ days: 1 });\n\t}\n}\n\n/**\n * Checks if a given date matches any of the specified weekdays\n */\nexport function isDateOnWeekdays(date: DateTime, weekdays: Weekday[]): boolean {\n\tconst dateWeekday = date.weekday;\n\tconst luxonWeekdays = weekdays.map((day) => {\n\t\tconst dayNumber = WEEKDAY_TO_NUMBER[day];\n\t\treturn dayNumber === 0 ? 7 : dayNumber; // Convert Sunday from 0 to 7 for Luxon\n\t});\n\n\treturn luxonWeekdays.includes(dateWeekday);\n}\n\n/**\n * Finds the next occurrence on specified weekdays\n */\nexport function getNextWeekdayOccurrence(currentDate: DateTime, weekdays: Weekday[]): DateTime {\n\tconst currentWeekday = currentDate.weekday;\n\tconst luxonWeekdays = weekdays.map((day) => {\n\t\tconst dayNumber = WEEKDAY_TO_NUMBER[day];\n\t\treturn dayNumber === 0 ? 7 : dayNumber; // Convert Sunday from 0 to 7 for Luxon\n\t});\n\n\t// Find next weekday in the current week (after today)\n\tconst nextWeekday = luxonWeekdays.find((day) => day > currentWeekday);\n\tif (nextWeekday) {\n\t\treturn currentDate.set({ weekday: nextWeekday as 1 | 2 | 3 | 4 | 5 | 6 | 7 });\n\t}\n\n\t// No more weekdays this week, go to first weekday of next week\n\tconst firstWeekday = Math.min(...luxonWeekdays);\n\treturn currentDate.plus({ weeks: 1 }).set({ weekday: firstWeekday as 1 | 2 | 3 | 4 | 5 | 6 | 7 });\n}\n\n/**\n * Finds the next bi-weekly occurrence on specified weekdays\n */\nexport function getNextBiWeeklyOccurrence(currentDate: DateTime, weekdays: Weekday[]): DateTime {\n\tconst nextWeekly = getNextWeekdayOccurrence(currentDate, weekdays);\n\t// Add one more week to make it bi-weekly\n\treturn nextWeekly.plus({ weeks: 1 });\n}\n\nexport function* iterateOccurrencesInRange(\n\tstartDate: DateTime,\n\trrules: { type: RecurrenceType; weekdays?: Weekday[] },\n\trangeStart: DateTime,\n\trangeEnd: DateTime\n): Generator<DateTime, void, unknown> {\n\t// Normalize to start of day for comparison\n\tconst normalizedStart = startDate.startOf(\"day\");\n\tconst normalizedRangeStart = rangeStart.startOf(\"day\");\n\tconst normalizedRangeEnd = rangeEnd.startOf(\"day\");\n\n\t// Start from the later of startDate or rangeStart\n\tlet currentDate =\n\t\tnormalizedStart >= normalizedRangeStart ? normalizedStart : normalizedRangeStart;\n\n\t// For weekly/bi-weekly with weekdays, we need to track which week we're in\n\tif (\n\t\t(rrules.type === \"weekly\" || rrules.type === \"bi-weekly\") &&\n\t\trrules.weekdays &&\n\t\trrules.weekdays.length > 0\n\t) {\n\t\t// Calculate week offset from start date\n\t\tconst weeksFromStart = Math.floor(currentDate.diff(normalizedStart, \"weeks\").weeks);\n\n\t\t// For bi-weekly, we only want even weeks (0, 2, 4...) from the start date\n\t\tconst weekInterval = rrules.type === \"bi-weekly\" ? 2 : 1;\n\n\t\t// Adjust to the correct week if we're in an off-week\n\t\tconst weekOffset = weeksFromStart % weekInterval;\n\t\tif (weekOffset !== 0) {\n\t\t\tcurrentDate = currentDate.plus({ weeks: weekInterval - weekOffset });\n\t\t}\n\n\t\t// Now iterate through weeks, checking each day\n\t\twhile (currentDate <= normalizedRangeEnd) {\n\t\t\t// Check all 7 days of the current week\n\t\t\tfor (let dayOffset = 0; dayOffset < 7; dayOffset++) {\n\t\t\t\tconst checkDate = currentDate.plus({ days: dayOffset });\n\n\t\t\t\t// Only yield if within range and matches a target weekday\n\t\t\t\tif (\n\t\t\t\t\tcheckDate >= normalizedRangeStart &&\n\t\t\t\t\tcheckDate <= normalizedRangeEnd &&\n\t\t\t\t\tisDateOnWeekdays(checkDate, rrules.weekdays)\n\t\t\t\t) {\n\t\t\t\t\tyield checkDate;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Move to next occurrence week (1 week for weekly, 2 weeks for bi-weekly)\n\t\t\tcurrentDate = currentDate.plus({ weeks: weekInterval });\n\t\t}\n\t} else {\n\t\t// For other recurrence types (daily, monthly, yearly, or weekly without weekdays)\n\t\twhile (currentDate <= normalizedRangeEnd) {\n\t\t\tif (currentDate >= normalizedRangeStart) {\n\t\t\t\tyield currentDate;\n\t\t\t}\n\n\t\t\tconst nextDate = getNextOccurrence(currentDate, rrules.type, rrules.weekdays);\n\n\t\t\tif (nextDate <= normalizedRangeEnd) {\n\t\t\t\tcurrentDate = nextDate;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Calculates a DateTime for a specific date with optional time\n */\nexport function calculateInstanceDateTime(instanceDate: DateTime, timeString?: string): DateTime {\n\tif (!timeString) {\n\t\treturn instanceDate.startOf(\"day\");\n\t}\n\n\tconst [hours, minutes] = timeString.split(\":\").map(Number);\n\treturn instanceDate.set({ hour: hours, minute: minutes, second: 0, millisecond: 0 });\n}\n\nexport function calculateRecurringInstanceDateTime(\n\tnextInstanceDateTime: DateTime,\n\tnodeRecuringEventDateTime: DateTime,\n\trecurrenceType: RecurrenceType,\n\tallDay?: boolean\n): DateTime {\n\t// Convert the original event time to the target timezone once to preserve local time\n\tconst originalInTargetZone = nodeRecuringEventDateTime.setZone(nextInstanceDateTime.zone);\n\n\tswitch (recurrenceType) {\n\t\tcase \"daily\":\n\t\tcase \"weekly\":\n\t\tcase \"bi-weekly\": {\n\t\t\tif (allDay) {\n\t\t\t\treturn nextInstanceDateTime.startOf(\"day\");\n\t\t\t}\n\n\t\t\treturn nextInstanceDateTime.set({\n\t\t\t\thour: originalInTargetZone.hour,\n\t\t\t\tminute: originalInTargetZone.minute,\n\t\t\t\tsecond: 0,\n\t\t\t\tmillisecond: 0,\n\t\t\t});\n\t\t}\n\n\t\tcase \"monthly\":\n\t\tcase \"bi-monthly\": {\n\t\t\tif (allDay) {\n\t\t\t\treturn nextInstanceDateTime.set({ day: originalInTargetZone.day }).startOf(\"day\");\n\t\t\t}\n\n\t\t\treturn nextInstanceDateTime.set({\n\t\t\t\tday: originalInTargetZone.day,\n\t\t\t\thour: originalInTargetZone.hour,\n\t\t\t\tminute: originalInTargetZone.minute,\n\t\t\t\tsecond: 0,\n\t\t\t\tmillisecond: 0,\n\t\t\t});\n\t\t}\n\n\t\tcase \"yearly\": {\n\t\t\tif (allDay) {\n\t\t\t\treturn nextInstanceDateTime\n\t\t\t\t\t.set({\n\t\t\t\t\t\tmonth: originalInTargetZone.month,\n\t\t\t\t\t\tday: originalInTargetZone.day,\n\t\t\t\t\t})\n\t\t\t\t\t.startOf(\"day\");\n\t\t\t}\n\n\t\t\treturn nextInstanceDateTime.set({\n\t\t\t\tmonth: originalInTargetZone.month,\n\t\t\t\tday: originalInTargetZone.day,\n\t\t\t\thour: originalInTargetZone.hour,\n\t\t\t\tminute: originalInTargetZone.minute,\n\t\t\t\tsecond: 0,\n\t\t\t\tmillisecond: 0,\n\t\t\t});\n\t\t}\n\n\t\tdefault:\n\t\t\treturn nextInstanceDateTime.startOf(\"day\");\n\t}\n}\n"]}
@@ -1,21 +0,0 @@
1
- import { DateTime } from "luxon";
2
- export declare const formatDateTimeForInput: (dateString: string) => string;
3
- export declare const formatDateForInput: (dateString: string) => string;
4
- /**
5
- * Converts input value to ISO string, handling edge cases where
6
- * browser datetime-local inputs behave differently across platforms.
7
- * Returns null for invalid dates to prevent silent failures.
8
- */
9
- export declare const inputValueToISOString: (inputValue: string) => string | null;
10
- export declare const formatDuration: (minutes: number) => string;
11
- /**
12
- * Parse time string from datetime value - returns DateTime object
13
- * Rejects plain HH:mm format, requires full datetime
14
- */
15
- export declare const parseTimeString: (value: string | null) => DateTime | undefined;
16
- /**
17
- * Parse and validate datetime strings for event parsing
18
- * Supports multiple formats including date-only and datetime formats
19
- */
20
- export declare const parseDateTimeString: (value: string | null) => DateTime | undefined;
21
- //# sourceMappingURL=date.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/date/date.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,eAAO,MAAM,sBAAsB,GAAI,YAAY,MAAM,KAAG,MAgB3D,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,YAAY,MAAM,KAAG,MAavD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,YAAY,MAAM,KAAG,MAAM,GAAG,IAMnE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,MAIhD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,GAAG,IAAI,KAAG,QAAQ,GAAG,SAgBjE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,MAAM,GAAG,IAAI,KAAG,QAAQ,GAAG,SA8BrE,CAAC"}
package/dist/date/date.js DELETED
@@ -1,105 +0,0 @@
1
- import { DateTime } from "luxon";
2
- export const formatDateTimeForInput = (dateString) => {
3
- if (!dateString)
4
- return "";
5
- try {
6
- const date = new Date(dateString);
7
- // Format for datetime-local input (YYYY-MM-DDTHH:mm)
8
- const year = date.getFullYear();
9
- const month = String(date.getMonth() + 1).padStart(2, "0");
10
- const day = String(date.getDate()).padStart(2, "0");
11
- const hours = String(date.getHours()).padStart(2, "0");
12
- const minutes = String(date.getMinutes()).padStart(2, "0");
13
- return `${year}-${month}-${day}T${hours}:${minutes}`;
14
- }
15
- catch (_a) {
16
- return "";
17
- }
18
- };
19
- export const formatDateForInput = (dateString) => {
20
- if (!dateString)
21
- return "";
22
- try {
23
- const date = new Date(dateString);
24
- const year = date.getFullYear();
25
- const month = String(date.getMonth() + 1).padStart(2, "0");
26
- const day = String(date.getDate()).padStart(2, "0");
27
- return `${year}-${month}-${day}`;
28
- }
29
- catch (_a) {
30
- return "";
31
- }
32
- };
33
- /**
34
- * Converts input value to ISO string, handling edge cases where
35
- * browser datetime-local inputs behave differently across platforms.
36
- * Returns null for invalid dates to prevent silent failures.
37
- */
38
- export const inputValueToISOString = (inputValue) => {
39
- try {
40
- return new Date(inputValue).toISOString();
41
- }
42
- catch (_a) {
43
- return null;
44
- }
45
- };
46
- export const formatDuration = (minutes) => {
47
- const hours = Math.floor(minutes / 60);
48
- const mins = minutes % 60;
49
- return `${String(hours).padStart(2, "0")}:${String(mins).padStart(2, "0")}:00`;
50
- };
51
- /**
52
- * Parse time string from datetime value - returns DateTime object
53
- * Rejects plain HH:mm format, requires full datetime
54
- */
55
- export const parseTimeString = (value) => {
56
- if (value === null)
57
- return undefined;
58
- const v = value.trim();
59
- // Reject plain HH:mm format - require full datetime
60
- if (/^\d{2}:\d{2}$/.test(v)) {
61
- return undefined; // Reject plain time format
62
- }
63
- // Try ISO format first (most common) - EXACT same logic as recurring events
64
- let dt = DateTime.fromISO(v, { setZone: true }); // ISO: with/without seconds, Z/offset, T
65
- if (!dt.isValid)
66
- dt = DateTime.fromSQL(v, { setZone: true }); // "YYYY-MM-DD HH:mm[:ss]" etc.
67
- if (!dt.isValid)
68
- dt = DateTime.fromFormat(v, "yyyy-MM-dd HH:mm", { setZone: true });
69
- return dt.isValid ? dt : undefined;
70
- };
71
- /**
72
- * Parse and validate datetime strings for event parsing
73
- * Supports multiple formats including date-only and datetime formats
74
- */
75
- export const parseDateTimeString = (value) => {
76
- if (value === null)
77
- return undefined;
78
- const v = value.trim();
79
- if (!v)
80
- return undefined;
81
- // Try multiple datetime formats in order of preference
82
- let dt;
83
- // 1. Try ISO format first (most common)
84
- dt = DateTime.fromISO(v, { setZone: true });
85
- if (dt.isValid)
86
- return dt;
87
- // 2. Try SQL format (YYYY-MM-DD HH:mm:ss)
88
- dt = DateTime.fromSQL(v, { setZone: true });
89
- if (dt.isValid)
90
- return dt;
91
- // 3. Try common format with space (YYYY-MM-DD HH:mm)
92
- dt = DateTime.fromFormat(v, "yyyy-MM-dd HH:mm", { setZone: true });
93
- if (dt.isValid)
94
- return dt;
95
- // 4. Try date-only format (YYYY-MM-DD) - treat as start of day
96
- dt = DateTime.fromFormat(v, "yyyy-MM-dd", { setZone: true });
97
- if (dt.isValid)
98
- return dt;
99
- // 5. Try ISO date format (YYYY-MM-DD)
100
- dt = DateTime.fromISO(v, { setZone: true });
101
- if (dt.isValid)
102
- return dt;
103
- return undefined;
104
- };
105
- //# sourceMappingURL=date.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"date.js","sourceRoot":"","sources":["../../src/date/date.ts"],"names":[],"mappings":"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","sourcesContent":["import { DateTime } from \"luxon\";\n\nexport const formatDateTimeForInput = (dateString: string): string => {\n\tif (!dateString) return \"\";\n\n\ttry {\n\t\tconst date = new Date(dateString);\n\t\t// Format for datetime-local input (YYYY-MM-DDTHH:mm)\n\t\tconst year = date.getFullYear();\n\t\tconst month = String(date.getMonth() + 1).padStart(2, \"0\");\n\t\tconst day = String(date.getDate()).padStart(2, \"0\");\n\t\tconst hours = String(date.getHours()).padStart(2, \"0\");\n\t\tconst minutes = String(date.getMinutes()).padStart(2, \"0\");\n\n\t\treturn `${year}-${month}-${day}T${hours}:${minutes}`;\n\t} catch {\n\t\treturn \"\";\n\t}\n};\n\nexport const formatDateForInput = (dateString: string): string => {\n\tif (!dateString) return \"\";\n\n\ttry {\n\t\tconst date = new Date(dateString);\n\t\tconst year = date.getFullYear();\n\t\tconst month = String(date.getMonth() + 1).padStart(2, \"0\");\n\t\tconst day = String(date.getDate()).padStart(2, \"0\");\n\n\t\treturn `${year}-${month}-${day}`;\n\t} catch {\n\t\treturn \"\";\n\t}\n};\n\n/**\n * Converts input value to ISO string, handling edge cases where\n * browser datetime-local inputs behave differently across platforms.\n * Returns null for invalid dates to prevent silent failures.\n */\nexport const inputValueToISOString = (inputValue: string): string | null => {\n\ttry {\n\t\treturn new Date(inputValue).toISOString();\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nexport const formatDuration = (minutes: number): string => {\n\tconst hours = Math.floor(minutes / 60);\n\tconst mins = minutes % 60;\n\treturn `${String(hours).padStart(2, \"0\")}:${String(mins).padStart(2, \"0\")}:00`;\n};\n\n/**\n * Parse time string from datetime value - returns DateTime object\n * Rejects plain HH:mm format, requires full datetime\n */\nexport const parseTimeString = (value: string | null): DateTime | undefined => {\n\tif (value === null) return undefined;\n\n\tconst v = value.trim();\n\n\t// Reject plain HH:mm format - require full datetime\n\tif (/^\\d{2}:\\d{2}$/.test(v)) {\n\t\treturn undefined; // Reject plain time format\n\t}\n\n\t// Try ISO format first (most common) - EXACT same logic as recurring events\n\tlet dt = DateTime.fromISO(v, { setZone: true }); // ISO: with/without seconds, Z/offset, T\n\tif (!dt.isValid) dt = DateTime.fromSQL(v, { setZone: true }); // \"YYYY-MM-DD HH:mm[:ss]\" etc.\n\tif (!dt.isValid) dt = DateTime.fromFormat(v, \"yyyy-MM-dd HH:mm\", { setZone: true });\n\n\treturn dt.isValid ? dt : undefined;\n};\n\n/**\n * Parse and validate datetime strings for event parsing\n * Supports multiple formats including date-only and datetime formats\n */\nexport const parseDateTimeString = (value: string | null): DateTime | undefined => {\n\tif (value === null) return undefined;\n\n\tconst v = value.trim();\n\tif (!v) return undefined;\n\n\t// Try multiple datetime formats in order of preference\n\tlet dt: DateTime;\n\n\t// 1. Try ISO format first (most common)\n\tdt = DateTime.fromISO(v, { setZone: true });\n\tif (dt.isValid) return dt;\n\n\t// 2. Try SQL format (YYYY-MM-DD HH:mm:ss)\n\tdt = DateTime.fromSQL(v, { setZone: true });\n\tif (dt.isValid) return dt;\n\n\t// 3. Try common format with space (YYYY-MM-DD HH:mm)\n\tdt = DateTime.fromFormat(v, \"yyyy-MM-dd HH:mm\", { setZone: true });\n\tif (dt.isValid) return dt;\n\n\t// 4. Try date-only format (YYYY-MM-DD) - treat as start of day\n\tdt = DateTime.fromFormat(v, \"yyyy-MM-dd\", { setZone: true });\n\tif (dt.isValid) return dt;\n\n\t// 5. Try ISO date format (YYYY-MM-DD)\n\tdt = DateTime.fromISO(v, { setZone: true });\n\tif (dt.isValid) return dt;\n\n\treturn undefined;\n};\n"]}
@@ -1,3 +0,0 @@
1
- export * from "./date";
2
- export * from "./date-recurrence";
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/date/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,mBAAmB,CAAC"}
@@ -1,3 +0,0 @@
1
- export * from "./date";
2
- export * from "./date-recurrence";
3
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/date/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,mBAAmB,CAAC","sourcesContent":["export * from \"./date\";\nexport * from \"./date-recurrence\";\n"]}
@@ -1,9 +0,0 @@
1
- import { TFile } from "obsidian";
2
- export interface VaultAdapter {
3
- getAbstractFileByPath(path: string): TFile | null;
4
- }
5
- export declare function extractDirectoryPath(filePath: string): string;
6
- export declare function isRelativeChildReference(childRef: string): boolean;
7
- export declare function normalizeChildReference(childRef: string, vault: VaultAdapter, currentFileDirectory?: string): string;
8
- export declare function normalizeChildReferences(childRefs: string[], vault: VaultAdapter, currentFileDirectory?: string): string[];
9
- //# sourceMappingURL=child-reference.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"child-reference.d.ts","sourceRoot":"","sources":["../../src/file/child-reference.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAIjC,MAAM,WAAW,YAAY;IAC5B,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC;CAClD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM7D;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMlE;AAED,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,oBAAoB,CAAC,EAAE,MAAM,GAC3B,MAAM,CAqCR;AAED,wBAAgB,wBAAwB,CACvC,SAAS,EAAE,MAAM,EAAE,EACnB,KAAK,EAAE,YAAY,EACnB,oBAAoB,CAAC,EAAE,MAAM,GAC3B,MAAM,EAAE,CAIV"}
@@ -1,57 +0,0 @@
1
- import { TFile } from "obsidian";
2
- import { createFileLink } from "./file-operations";
3
- import { extractFilePathFromLink } from "./link-parser";
4
- export function extractDirectoryPath(filePath) {
5
- const lastSlashIndex = filePath.lastIndexOf("/");
6
- if (lastSlashIndex === -1) {
7
- return "";
8
- }
9
- return filePath.substring(0, lastSlashIndex);
10
- }
11
- export function isRelativeChildReference(childRef) {
12
- const filePath = extractFilePathFromLink(childRef);
13
- if (!filePath) {
14
- return !childRef.includes("/");
15
- }
16
- return !filePath.includes("/");
17
- }
18
- export function normalizeChildReference(childRef, vault, currentFileDirectory) {
19
- const filePath = extractFilePathFromLink(childRef);
20
- // Handle plain text references (not wrapped in [[]])
21
- if (!filePath) {
22
- // If it's not a link format, check if it should be converted to a link
23
- if (!childRef.includes("/") && currentFileDirectory !== undefined) {
24
- // This is a plain text reference that might need to be converted to a link
25
- const potentialPath = currentFileDirectory
26
- ? `${currentFileDirectory}/${childRef.endsWith(".md") ? childRef : `${childRef}.md`}`
27
- : childRef.endsWith(".md")
28
- ? childRef
29
- : `${childRef}.md`;
30
- const file = vault.getAbstractFileByPath(potentialPath);
31
- if (file instanceof TFile) {
32
- return createFileLink(file);
33
- }
34
- }
35
- return childRef;
36
- }
37
- // Handle relative references by making them absolute
38
- if (isRelativeChildReference(childRef) && currentFileDirectory) {
39
- const absolutePath = `${currentFileDirectory}/${filePath}`;
40
- const file = vault.getAbstractFileByPath(absolutePath);
41
- if (file instanceof TFile) {
42
- return createFileLink(file);
43
- }
44
- }
45
- // For absolute references or when no directory context, try to find the file as-is
46
- const file = vault.getAbstractFileByPath(filePath);
47
- if (file instanceof TFile) {
48
- return createFileLink(file);
49
- }
50
- return childRef;
51
- }
52
- export function normalizeChildReferences(childRefs, vault, currentFileDirectory) {
53
- return childRefs.map((childRef) => {
54
- return normalizeChildReference(childRef, vault, currentFileDirectory);
55
- });
56
- }
57
- //# sourceMappingURL=child-reference.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"child-reference.js","sourceRoot":"","sources":["../../src/file/child-reference.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAMxD,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACpD,MAAM,cAAc,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACjD,IAAI,cAAc,KAAK,CAAC,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAC;IACX,CAAC;IACD,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACxD,MAAM,QAAQ,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,uBAAuB,CACtC,QAAgB,EAChB,KAAmB,EACnB,oBAA6B;IAE7B,MAAM,QAAQ,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAEnD,qDAAqD;IACrD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,uEAAuE;QACvE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,oBAAoB,KAAK,SAAS,EAAE,CAAC;YACnE,2EAA2E;YAC3E,MAAM,aAAa,GAAG,oBAAoB;gBACzC,CAAC,CAAC,GAAG,oBAAoB,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,KAAK,EAAE;gBACrF,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;oBACzB,CAAC,CAAC,QAAQ;oBACV,CAAC,CAAC,GAAG,QAAQ,KAAK,CAAC;YACrB,MAAM,IAAI,GAAG,KAAK,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC;YACxD,IAAI,IAAI,YAAY,KAAK,EAAE,CAAC;gBAC3B,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;QACF,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,qDAAqD;IACrD,IAAI,wBAAwB,CAAC,QAAQ,CAAC,IAAI,oBAAoB,EAAE,CAAC;QAChE,MAAM,YAAY,GAAG,GAAG,oBAAoB,IAAI,QAAQ,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAG,KAAK,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC;QACvD,IAAI,IAAI,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;IAED,mFAAmF;IACnF,MAAM,IAAI,GAAG,KAAK,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACnD,IAAI,IAAI,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,wBAAwB,CACvC,SAAmB,EACnB,KAAmB,EACnB,oBAA6B;IAE7B,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QACjC,OAAO,uBAAuB,CAAC,QAAQ,EAAE,KAAK,EAAE,oBAAoB,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { TFile } from \"obsidian\";\nimport { createFileLink } from \"./file-operations\";\nimport { extractFilePathFromLink } from \"./link-parser\";\n\nexport interface VaultAdapter {\n\tgetAbstractFileByPath(path: string): TFile | null;\n}\n\nexport function extractDirectoryPath(filePath: string): string {\n\tconst lastSlashIndex = filePath.lastIndexOf(\"/\");\n\tif (lastSlashIndex === -1) {\n\t\treturn \"\";\n\t}\n\treturn filePath.substring(0, lastSlashIndex);\n}\n\nexport function isRelativeChildReference(childRef: string): boolean {\n\tconst filePath = extractFilePathFromLink(childRef);\n\tif (!filePath) {\n\t\treturn !childRef.includes(\"/\");\n\t}\n\treturn !filePath.includes(\"/\");\n}\n\nexport function normalizeChildReference(\n\tchildRef: string,\n\tvault: VaultAdapter,\n\tcurrentFileDirectory?: string\n): string {\n\tconst filePath = extractFilePathFromLink(childRef);\n\n\t// Handle plain text references (not wrapped in [[]])\n\tif (!filePath) {\n\t\t// If it's not a link format, check if it should be converted to a link\n\t\tif (!childRef.includes(\"/\") && currentFileDirectory !== undefined) {\n\t\t\t// This is a plain text reference that might need to be converted to a link\n\t\t\tconst potentialPath = currentFileDirectory\n\t\t\t\t? `${currentFileDirectory}/${childRef.endsWith(\".md\") ? childRef : `${childRef}.md`}`\n\t\t\t\t: childRef.endsWith(\".md\")\n\t\t\t\t\t? childRef\n\t\t\t\t\t: `${childRef}.md`;\n\t\t\tconst file = vault.getAbstractFileByPath(potentialPath);\n\t\t\tif (file instanceof TFile) {\n\t\t\t\treturn createFileLink(file);\n\t\t\t}\n\t\t}\n\t\treturn childRef;\n\t}\n\n\t// Handle relative references by making them absolute\n\tif (isRelativeChildReference(childRef) && currentFileDirectory) {\n\t\tconst absolutePath = `${currentFileDirectory}/${filePath}`;\n\t\tconst file = vault.getAbstractFileByPath(absolutePath);\n\t\tif (file instanceof TFile) {\n\t\t\treturn createFileLink(file);\n\t\t}\n\t}\n\n\t// For absolute references or when no directory context, try to find the file as-is\n\tconst file = vault.getAbstractFileByPath(filePath);\n\tif (file instanceof TFile) {\n\t\treturn createFileLink(file);\n\t}\n\n\treturn childRef;\n}\n\nexport function normalizeChildReferences(\n\tchildRefs: string[],\n\tvault: VaultAdapter,\n\tcurrentFileDirectory?: string\n): string[] {\n\treturn childRefs.map((childRef) => {\n\t\treturn normalizeChildReference(childRef, vault, currentFileDirectory);\n\t});\n}\n"]}
@@ -1,31 +0,0 @@
1
- import { type App, TFile } from "obsidian";
2
- export declare const fromRoot: (relativePath: string) => string;
3
- export declare const getActiveFileOrThrow: (app: App) => TFile;
4
- export declare const getTemplateContent: (app: App, templatePath: string) => Promise<string>;
5
- export declare const ensureFolderExists: (app: App, folderPath: string) => Promise<void>;
6
- export declare const openFileInNewLeaf: (app: App, file: TFile) => Promise<void>;
7
- export declare const getNoteFilesFromDir: (directoryPath: string) => Promise<string[]>;
8
- export declare const getTargetFileFromLink: (app: App, relationshipLink: string) => TFile | null;
9
- export declare const createFileLink: (file: TFile) => string;
10
- export declare const normalizeArray: (value: string | string[] | undefined) => string[];
11
- export declare const arraysEqual: (a: string[], b: string[]) => boolean;
12
- /**
13
- * Normalizes frontmatter content by converting quoted numeric _ZettelIDs to numbers.
14
- * This handles edge cases where YAML parsers treat numeric strings inconsistently.
15
- */
16
- export declare const normalizeContent: (content: string) => string;
17
- /**
18
- * Safely performs a file operation with error handling and file validation.
19
- * Reduces boilerplate for common file operations.
20
- */
21
- export declare const withFileOperation: <T>(app: App, event: any, operation: (file: TFile) => Promise<T>, errorMessage?: string) => Promise<T | null>;
22
- /**
23
- * Safely performs a file operation by file path with error handling and file validation.
24
- */
25
- export declare const withFile: <T>(app: App, filePath: string, operation: (file: TFile) => Promise<T>, errorMessage?: string) => Promise<T | null>;
26
- /**
27
- * Duplicates a file with a new ZettelID, preserving the original content
28
- * but updating the ZettelID in frontmatter if configured.
29
- */
30
- export declare const duplicateFileWithNewZettelId: (app: App, file: TFile, zettelIdProp?: string) => Promise<TFile>;
31
- //# sourceMappingURL=file-operations.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-operations.d.ts","sourceRoot":"","sources":["../../src/file/file-operations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,GAAG,EAAU,KAAK,EAAE,MAAM,UAAU,CAAC;AAKnD,eAAO,MAAM,QAAQ,GAAI,cAAc,MAAM,KAAG,MAE/C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,KAAK,GAAG,KAAG,KAO/C,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,KAAK,GAAG,EAAE,cAAc,MAAM,KAAG,OAAO,CAAC,MAAM,CAQvF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,KAAK,GAAG,EAAE,YAAY,MAAM,KAAG,OAAO,CAAC,IAAI,CAInF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,KAAK,GAAG,EAAE,MAAM,KAAK,KAAG,OAAO,CAAC,IAAI,CAE3E,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,MAAM,EAAE,CAejF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,KAAK,GAAG,EAAE,kBAAkB,MAAM,KAAG,KAAK,GAAG,IAclF,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,KAAK,KAAG,MAG5C,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,KAAG,MAAM,EAW3E,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,GAAG,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,KAAG,OAEtD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,KAAG,MAelD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAU,CAAC,EACxC,KAAK,GAAG,EACR,OAAO,GAAG,EACV,WAAW,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,eAAc,MAA2B,KACvC,OAAO,CAAC,CAAC,GAAG,IAAI,CAgBlB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAU,CAAC,EAC/B,KAAK,GAAG,EACR,UAAU,MAAM,EAChB,WAAW,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,eAAc,MAA2B,KACvC,OAAO,CAAC,CAAC,GAAG,IAAI,CAelB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,4BAA4B,GACxC,KAAK,GAAG,EACR,MAAM,KAAK,EACX,eAAe,MAAM,KACnB,OAAO,CAAC,KAAK,CAoBf,CAAC"}