@mrtdown/core 2.0.0-alpha.5 → 2.0.0-alpha.6

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 (250) hide show
  1. package/dist/index.d.ts +0 -7
  2. package/dist/index.js +0 -7
  3. package/dist/index.js.map +1 -1
  4. package/dist/schema/Landmark.js.map +1 -1
  5. package/dist/schema/Line.js.map +1 -1
  6. package/dist/schema/Operator.js.map +1 -1
  7. package/dist/schema/Service.js.map +1 -1
  8. package/dist/schema/Station.js.map +1 -1
  9. package/dist/schema/Town.js.map +1 -1
  10. package/dist/schema/common.js.map +1 -1
  11. package/dist/schema/issue/bundle.js.map +1 -1
  12. package/dist/schema/issue/cause.js.map +1 -1
  13. package/dist/schema/issue/claim.js.map +1 -1
  14. package/dist/schema/issue/entity.js.map +1 -1
  15. package/dist/schema/issue/evidence.js.map +1 -1
  16. package/dist/schema/issue/facilityEffect.js.map +1 -1
  17. package/dist/schema/issue/id.js.map +1 -1
  18. package/dist/schema/issue/impactEvent.js.map +1 -1
  19. package/dist/schema/issue/issue.js.map +1 -1
  20. package/dist/schema/issue/issueType.js.map +1 -1
  21. package/dist/schema/issue/period.js.map +1 -1
  22. package/dist/schema/issue/serviceEffect.js.map +1 -1
  23. package/dist/schema/issue/serviceScope.js.map +1 -1
  24. package/package.json +19 -44
  25. package/README.md +0 -107
  26. package/dist/cli/commands/create.d.ts +0 -30
  27. package/dist/cli/commands/create.js +0 -189
  28. package/dist/cli/commands/create.js.map +0 -1
  29. package/dist/cli/commands/list.d.ts +0 -6
  30. package/dist/cli/commands/list.js +0 -106
  31. package/dist/cli/commands/list.js.map +0 -1
  32. package/dist/cli/commands/show.d.ts +0 -6
  33. package/dist/cli/commands/show.js +0 -156
  34. package/dist/cli/commands/show.js.map +0 -1
  35. package/dist/cli/commands/validate.d.ts +0 -6
  36. package/dist/cli/commands/validate.js +0 -19
  37. package/dist/cli/commands/validate.js.map +0 -1
  38. package/dist/cli/index.d.ts +0 -2
  39. package/dist/cli/index.js +0 -162
  40. package/dist/cli/index.js.map +0 -1
  41. package/dist/constants.d.ts +0 -10
  42. package/dist/constants.js +0 -11
  43. package/dist/constants.js.map +0 -1
  44. package/dist/helpers/calculateDurationWithinServiceHours.d.ts +0 -2
  45. package/dist/helpers/calculateDurationWithinServiceHours.js +0 -13
  46. package/dist/helpers/calculateDurationWithinServiceHours.js.map +0 -1
  47. package/dist/helpers/calculateDurationWithinServiceHours.test.d.ts +0 -1
  48. package/dist/helpers/calculateDurationWithinServiceHours.test.js +0 -83
  49. package/dist/helpers/calculateDurationWithinServiceHours.test.js.map +0 -1
  50. package/dist/helpers/computeImpactFromEvidenceClaims.d.ts +0 -21
  51. package/dist/helpers/computeImpactFromEvidenceClaims.js +0 -293
  52. package/dist/helpers/computeImpactFromEvidenceClaims.js.map +0 -1
  53. package/dist/helpers/computeImpactFromEvidenceClaims.test.d.ts +0 -1
  54. package/dist/helpers/computeImpactFromEvidenceClaims.test.js +0 -544
  55. package/dist/helpers/computeImpactFromEvidenceClaims.test.js.map +0 -1
  56. package/dist/helpers/computeStartOfDaysWithinInterval.d.ts +0 -2
  57. package/dist/helpers/computeStartOfDaysWithinInterval.js +0 -15
  58. package/dist/helpers/computeStartOfDaysWithinInterval.js.map +0 -1
  59. package/dist/helpers/computeStartOfDaysWithinInterval.test.d.ts +0 -1
  60. package/dist/helpers/computeStartOfDaysWithinInterval.test.js +0 -126
  61. package/dist/helpers/computeStartOfDaysWithinInterval.test.js.map +0 -1
  62. package/dist/helpers/estimateOpenAICost.d.ts +0 -40
  63. package/dist/helpers/estimateOpenAICost.js +0 -55
  64. package/dist/helpers/estimateOpenAICost.js.map +0 -1
  65. package/dist/helpers/keyForAffectedEntity.d.ts +0 -7
  66. package/dist/helpers/keyForAffectedEntity.js +0 -14
  67. package/dist/helpers/keyForAffectedEntity.js.map +0 -1
  68. package/dist/helpers/normalizeRecurringPeriod.d.ts +0 -7
  69. package/dist/helpers/normalizeRecurringPeriod.js +0 -118
  70. package/dist/helpers/normalizeRecurringPeriod.js.map +0 -1
  71. package/dist/helpers/normalizeRecurringPeriod.test.d.ts +0 -1
  72. package/dist/helpers/normalizeRecurringPeriod.test.js +0 -93
  73. package/dist/helpers/normalizeRecurringPeriod.test.js.map +0 -1
  74. package/dist/helpers/resolvePeriods.d.ts +0 -224
  75. package/dist/helpers/resolvePeriods.js +0 -207
  76. package/dist/helpers/resolvePeriods.js.map +0 -1
  77. package/dist/helpers/resolvePeriods.test.d.ts +0 -1
  78. package/dist/helpers/resolvePeriods.test.js +0 -239
  79. package/dist/helpers/resolvePeriods.test.js.map +0 -1
  80. package/dist/helpers/splitIntervalByServiceHours.d.ts +0 -2
  81. package/dist/helpers/splitIntervalByServiceHours.js +0 -30
  82. package/dist/helpers/splitIntervalByServiceHours.js.map +0 -1
  83. package/dist/helpers/splitIntervalByServiceHours.test.d.ts +0 -1
  84. package/dist/helpers/splitIntervalByServiceHours.test.js +0 -152
  85. package/dist/helpers/splitIntervalByServiceHours.test.js.map +0 -1
  86. package/dist/helpers/sumIntervalDuration.d.ts +0 -2
  87. package/dist/helpers/sumIntervalDuration.js +0 -9
  88. package/dist/helpers/sumIntervalDuration.js.map +0 -1
  89. package/dist/llm/client.d.ts +0 -2
  90. package/dist/llm/client.js +0 -5
  91. package/dist/llm/client.js.map +0 -1
  92. package/dist/llm/common/MemoryStore.d.ts +0 -21
  93. package/dist/llm/common/MemoryStore.js +0 -100
  94. package/dist/llm/common/MemoryStore.js.map +0 -1
  95. package/dist/llm/common/MemoryStore.test.d.ts +0 -1
  96. package/dist/llm/common/MemoryStore.test.js +0 -225
  97. package/dist/llm/common/MemoryStore.test.js.map +0 -1
  98. package/dist/llm/common/formatCurrentState.d.ts +0 -10
  99. package/dist/llm/common/formatCurrentState.js +0 -342
  100. package/dist/llm/common/formatCurrentState.js.map +0 -1
  101. package/dist/llm/common/tool.d.ts +0 -32
  102. package/dist/llm/common/tool.js +0 -6
  103. package/dist/llm/common/tool.js.map +0 -1
  104. package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.d.ts +0 -1
  105. package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.js +0 -433
  106. package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.js.map +0 -1
  107. package/dist/llm/functions/extractClaimsFromNewEvidence/index.d.ts +0 -18
  108. package/dist/llm/functions/extractClaimsFromNewEvidence/index.js +0 -153
  109. package/dist/llm/functions/extractClaimsFromNewEvidence/index.js.map +0 -1
  110. package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.d.ts +0 -1
  111. package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.js +0 -168
  112. package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.js.map +0 -1
  113. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.d.ts +0 -19
  114. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.js +0 -65
  115. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.js.map +0 -1
  116. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.d.ts +0 -21
  117. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.js +0 -115
  118. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.js.map +0 -1
  119. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.d.ts +0 -24
  120. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.js +0 -110
  121. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.js.map +0 -1
  122. package/dist/llm/functions/generateIssueTitleAndSlug/index.d.ts +0 -14
  123. package/dist/llm/functions/generateIssueTitleAndSlug/index.js +0 -38
  124. package/dist/llm/functions/generateIssueTitleAndSlug/index.js.map +0 -1
  125. package/dist/llm/functions/generateIssueTitleAndSlug/prompt.d.ts +0 -1
  126. package/dist/llm/functions/generateIssueTitleAndSlug/prompt.js +0 -23
  127. package/dist/llm/functions/generateIssueTitleAndSlug/prompt.js.map +0 -1
  128. package/dist/llm/functions/translate/index.d.ts +0 -1
  129. package/dist/llm/functions/translate/index.js +0 -59
  130. package/dist/llm/functions/translate/index.js.map +0 -1
  131. package/dist/llm/functions/triageNewEvidence/eval.test.d.ts +0 -1
  132. package/dist/llm/functions/triageNewEvidence/eval.test.js +0 -139
  133. package/dist/llm/functions/triageNewEvidence/eval.test.js.map +0 -1
  134. package/dist/llm/functions/triageNewEvidence/index.d.ts +0 -37
  135. package/dist/llm/functions/triageNewEvidence/index.js +0 -121
  136. package/dist/llm/functions/triageNewEvidence/index.js.map +0 -1
  137. package/dist/llm/functions/triageNewEvidence/prompt.d.ts +0 -1
  138. package/dist/llm/functions/triageNewEvidence/prompt.js +0 -60
  139. package/dist/llm/functions/triageNewEvidence/prompt.js.map +0 -1
  140. package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.d.ts +0 -19
  141. package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.js +0 -65
  142. package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.js.map +0 -1
  143. package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.d.ts +0 -19
  144. package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.js +0 -37
  145. package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.js.map +0 -1
  146. package/dist/repo/MRTDownRepository.d.ts +0 -23
  147. package/dist/repo/MRTDownRepository.js +0 -28
  148. package/dist/repo/MRTDownRepository.js.map +0 -1
  149. package/dist/repo/common/FileStore.d.ts +0 -12
  150. package/dist/repo/common/FileStore.js +0 -27
  151. package/dist/repo/common/FileStore.js.map +0 -1
  152. package/dist/repo/common/StandardRepository.d.ts +0 -32
  153. package/dist/repo/common/StandardRepository.js +0 -58
  154. package/dist/repo/common/StandardRepository.js.map +0 -1
  155. package/dist/repo/common/store.d.ts +0 -29
  156. package/dist/repo/common/store.js +0 -2
  157. package/dist/repo/common/store.js.map +0 -1
  158. package/dist/repo/issue/IssueRepository.d.ts +0 -36
  159. package/dist/repo/issue/IssueRepository.js +0 -177
  160. package/dist/repo/issue/IssueRepository.js.map +0 -1
  161. package/dist/repo/issue/helpers/deriveCurrentState.d.ts +0 -51
  162. package/dist/repo/issue/helpers/deriveCurrentState.js +0 -113
  163. package/dist/repo/issue/helpers/deriveCurrentState.js.map +0 -1
  164. package/dist/repo/issue/helpers/deriveCurrentState.test.d.ts +0 -1
  165. package/dist/repo/issue/helpers/deriveCurrentState.test.js +0 -477
  166. package/dist/repo/issue/helpers/deriveCurrentState.test.js.map +0 -1
  167. package/dist/repo/landmark/LandmarkRepository.d.ts +0 -7
  168. package/dist/repo/landmark/LandmarkRepository.js +0 -12
  169. package/dist/repo/landmark/LandmarkRepository.js.map +0 -1
  170. package/dist/repo/line/LineRepository.d.ts +0 -13
  171. package/dist/repo/line/LineRepository.js +0 -32
  172. package/dist/repo/line/LineRepository.js.map +0 -1
  173. package/dist/repo/operator/OperatorRepository.d.ts +0 -7
  174. package/dist/repo/operator/OperatorRepository.js +0 -12
  175. package/dist/repo/operator/OperatorRepository.js.map +0 -1
  176. package/dist/repo/service/ServiceRepository.d.ts +0 -19
  177. package/dist/repo/service/ServiceRepository.js +0 -39
  178. package/dist/repo/service/ServiceRepository.js.map +0 -1
  179. package/dist/repo/station/StationRepository.d.ts +0 -13
  180. package/dist/repo/station/StationRepository.js +0 -30
  181. package/dist/repo/station/StationRepository.js.map +0 -1
  182. package/dist/repo/town/TownRepository.d.ts +0 -7
  183. package/dist/repo/town/TownRepository.js +0 -12
  184. package/dist/repo/town/TownRepository.js.map +0 -1
  185. package/dist/scripts/ingestViaWebhook.d.ts +0 -1
  186. package/dist/scripts/ingestViaWebhook.js +0 -9
  187. package/dist/scripts/ingestViaWebhook.js.map +0 -1
  188. package/dist/util/assert.d.ts +0 -1
  189. package/dist/util/assert.js +0 -6
  190. package/dist/util/assert.js.map +0 -1
  191. package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.d.ts +0 -7
  192. package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.js +0 -24
  193. package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.js.map +0 -1
  194. package/dist/util/ingestContent/index.d.ts +0 -12
  195. package/dist/util/ingestContent/index.js +0 -171
  196. package/dist/util/ingestContent/index.js.map +0 -1
  197. package/dist/util/ingestContent/types.d.ts +0 -32
  198. package/dist/util/ingestContent/types.js +0 -2
  199. package/dist/util/ingestContent/types.js.map +0 -1
  200. package/dist/validators/buildContext.d.ts +0 -7
  201. package/dist/validators/buildContext.js +0 -164
  202. package/dist/validators/buildContext.js.map +0 -1
  203. package/dist/validators/index.d.ts +0 -17
  204. package/dist/validators/index.js +0 -58
  205. package/dist/validators/index.js.map +0 -1
  206. package/dist/validators/issue.d.ts +0 -13
  207. package/dist/validators/issue.js +0 -220
  208. package/dist/validators/issue.js.map +0 -1
  209. package/dist/validators/landmark.d.ts +0 -7
  210. package/dist/validators/landmark.js +0 -43
  211. package/dist/validators/landmark.js.map +0 -1
  212. package/dist/validators/line.d.ts +0 -8
  213. package/dist/validators/line.js +0 -87
  214. package/dist/validators/line.js.map +0 -1
  215. package/dist/validators/operator.d.ts +0 -7
  216. package/dist/validators/operator.js +0 -43
  217. package/dist/validators/operator.js.map +0 -1
  218. package/dist/validators/service.d.ts +0 -8
  219. package/dist/validators/service.js +0 -87
  220. package/dist/validators/service.js.map +0 -1
  221. package/dist/validators/station.d.ts +0 -8
  222. package/dist/validators/station.js +0 -93
  223. package/dist/validators/station.js.map +0 -1
  224. package/dist/validators/town.d.ts +0 -7
  225. package/dist/validators/town.js +0 -43
  226. package/dist/validators/town.js.map +0 -1
  227. package/dist/validators/types.d.ts +0 -19
  228. package/dist/validators/types.js +0 -2
  229. package/dist/validators/types.js.map +0 -1
  230. package/dist/validators/utils.d.ts +0 -2
  231. package/dist/validators/utils.js +0 -9
  232. package/dist/validators/utils.js.map +0 -1
  233. package/dist/write/MRTDownWriter.d.ts +0 -27
  234. package/dist/write/MRTDownWriter.js +0 -27
  235. package/dist/write/MRTDownWriter.js.map +0 -1
  236. package/dist/write/common/FileWriteStore.d.ts +0 -13
  237. package/dist/write/common/FileWriteStore.js +0 -31
  238. package/dist/write/common/FileWriteStore.js.map +0 -1
  239. package/dist/write/common/StandardWriter.d.ts +0 -14
  240. package/dist/write/common/StandardWriter.js +0 -17
  241. package/dist/write/common/StandardWriter.js.map +0 -1
  242. package/dist/write/common/store.d.ts +0 -32
  243. package/dist/write/common/store.js +0 -2
  244. package/dist/write/common/store.js.map +0 -1
  245. package/dist/write/id/IdGenerator.d.ts +0 -18
  246. package/dist/write/id/IdGenerator.js +0 -23
  247. package/dist/write/id/IdGenerator.js.map +0 -1
  248. package/dist/write/issue/IssueWriter.d.ts +0 -12
  249. package/dist/write/issue/IssueWriter.js +0 -33
  250. package/dist/write/issue/IssueWriter.js.map +0 -1
package/dist/cli/index.js DELETED
@@ -1,162 +0,0 @@
1
- #!/usr/bin/env node
2
- import { join } from 'node:path';
3
- import { Command } from 'commander';
4
- import { runCreateIssue, runCreateLandmark, runCreateLine, runCreateOperator, runCreateService, runCreateStation, runCreateTown, } from './commands/create.js';
5
- import { runList } from './commands/list.js';
6
- import { runShowIssue } from './commands/show.js';
7
- import { runValidate } from './commands/validate.js';
8
- const program = new Command();
9
- program
10
- .name('mrtdown-cli')
11
- .description('CLI for mrtdown-data: create entities and validate data')
12
- .option('-d, --data-dir <path>', 'Data directory', join(process.cwd(), 'data'));
13
- program
14
- .command('validate')
15
- .description('Validate all data files against schemas')
16
- .option('--scope <scope>', 'Only validate these entity types (repeatable): town, landmark, operator, station, line, service, issue', (val, prev) => (prev ?? []).concat(val))
17
- .action((opts) => {
18
- const dataDir = program.opts().dataDir;
19
- const scope = opts.scope;
20
- const code = runValidate({
21
- dataDir,
22
- scope: scope?.length
23
- ? scope
24
- : undefined,
25
- });
26
- process.exit(code);
27
- });
28
- program
29
- .command('show')
30
- .description('Display the current state of an issue')
31
- .argument('<issue-id>', 'Issue ID (e.g. 2011-09-20-faulty-cable-led-to-circle-line-disruption)')
32
- .option('--json', 'Output as JSON')
33
- .action((issueId, opts) => {
34
- const dataDir = program.opts().dataDir;
35
- const code = runShowIssue({
36
- dataDir,
37
- issueId,
38
- json: opts.json,
39
- });
40
- process.exit(code);
41
- });
42
- const list = program.command('list').description('List entities');
43
- const listEntities = [
44
- 'issue',
45
- 'town',
46
- 'landmark',
47
- 'operator',
48
- 'station',
49
- 'line',
50
- 'service',
51
- ];
52
- for (const entity of listEntities) {
53
- list
54
- .command(entity)
55
- .description(`List ${entity}s`)
56
- .option('--json', 'Output as JSON')
57
- .action((opts) => {
58
- const dataDir = program.opts().dataDir;
59
- const code = runList({
60
- dataDir,
61
- entity,
62
- json: opts.json,
63
- });
64
- process.exit(code);
65
- });
66
- }
67
- const create = program.command('create').description('Create a new entity');
68
- create
69
- .command('issue')
70
- .description('Create a new issue')
71
- .requiredOption('--date <YYYY-MM-DD>', 'Issue date')
72
- .requiredOption('--slug <slug>', 'URL-safe slug for the issue')
73
- .requiredOption('--title <title>', 'English title')
74
- .option('--type <type>', 'Issue type: disruption, maintenance, infra', 'disruption')
75
- .option('--source <source>', 'Title source', 'cli')
76
- .option('--dry-run', 'Print what would be created without writing')
77
- .action(async (opts) => {
78
- const dataDir = program.opts().dataDir;
79
- const code = await runCreateIssue({ dataDir, dryRun: opts.dryRun }, {
80
- date: opts.date,
81
- slug: opts.slug,
82
- title: opts.title,
83
- type: opts.type,
84
- source: opts.source,
85
- });
86
- process.exit(code);
87
- });
88
- create
89
- .command('town')
90
- .description('Create a new town')
91
- .requiredOption('--id <id>', 'Town ID (e.g. yishun)')
92
- .requiredOption('--name <name>', 'English name')
93
- .option('--dry-run', 'Print what would be created without writing')
94
- .action(async (opts) => {
95
- const dataDir = program.opts().dataDir;
96
- const code = await runCreateTown({ dataDir, dryRun: opts.dryRun }, { id: opts.id, name: opts.name });
97
- process.exit(code);
98
- });
99
- create
100
- .command('landmark')
101
- .description('Create a new landmark')
102
- .requiredOption('--id <id>', 'Landmark ID (e.g. northpoint-city)')
103
- .requiredOption('--name <name>', 'English name')
104
- .option('--dry-run', 'Print what would be created without writing')
105
- .action(async (opts) => {
106
- const dataDir = program.opts().dataDir;
107
- const code = await runCreateLandmark({ dataDir, dryRun: opts.dryRun }, { id: opts.id, name: opts.name });
108
- process.exit(code);
109
- });
110
- create
111
- .command('operator')
112
- .description('Create a new operator')
113
- .requiredOption('--id <id>', 'Operator ID (e.g. SMRT_TRAINS)')
114
- .requiredOption('--name <name>', 'English name')
115
- .requiredOption('--founded-at <date>', 'Founded date (YYYY-MM-DD)')
116
- .option('--url <url>', 'Operator website URL')
117
- .option('--dry-run', 'Print what would be created without writing')
118
- .action(async (opts) => {
119
- const dataDir = program.opts().dataDir;
120
- const code = await runCreateOperator({ dataDir, dryRun: opts.dryRun }, {
121
- id: opts.id,
122
- name: opts.name,
123
- foundedAt: opts.foundedAt,
124
- url: opts.url,
125
- });
126
- process.exit(code);
127
- });
128
- create
129
- .command('station')
130
- .description('Create a station from JSON (--stdin or --file)')
131
- .option('--stdin', 'Read JSON from stdin')
132
- .option('--file <path>', 'Read JSON from file')
133
- .option('--dry-run', 'Print what would be created without writing')
134
- .action(async (opts) => {
135
- const dataDir = program.opts().dataDir;
136
- const code = await runCreateStation({ dataDir, dryRun: opts.dryRun, stdin: opts.stdin }, { file: opts.file });
137
- process.exit(code);
138
- });
139
- create
140
- .command('line')
141
- .description('Create a line from JSON (--stdin or --file)')
142
- .option('--stdin', 'Read JSON from stdin')
143
- .option('--file <path>', 'Read JSON from file')
144
- .option('--dry-run', 'Print what would be created without writing')
145
- .action(async (opts) => {
146
- const dataDir = program.opts().dataDir;
147
- const code = await runCreateLine({ dataDir, dryRun: opts.dryRun, stdin: opts.stdin }, { file: opts.file });
148
- process.exit(code);
149
- });
150
- create
151
- .command('service')
152
- .description('Create a service from JSON (--stdin or --file)')
153
- .option('--stdin', 'Read JSON from stdin')
154
- .option('--file <path>', 'Read JSON from file')
155
- .option('--dry-run', 'Print what would be created without writing')
156
- .action(async (opts) => {
157
- const dataDir = program.opts().dataDir;
158
- const code = await runCreateService({ dataDir, dryRun: opts.dryRun, stdin: opts.stdin }, { file: opts.file });
159
- process.exit(code);
160
- });
161
- program.parse();
162
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"/","sources":["cli/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport { join } from 'node:path';\nimport { Command } from 'commander';\nimport {\n runCreateIssue,\n runCreateLandmark,\n runCreateLine,\n runCreateOperator,\n runCreateService,\n runCreateStation,\n runCreateTown,\n} from './commands/create.js';\nimport { runList } from './commands/list.js';\nimport { runShowIssue } from './commands/show.js';\nimport { runValidate } from './commands/validate.js';\n\nconst program = new Command();\n\nprogram\n .name('mrtdown-cli')\n .description('CLI for mrtdown-data: create entities and validate data')\n .option(\n '-d, --data-dir <path>',\n 'Data directory',\n join(process.cwd(), 'data'),\n );\n\nprogram\n .command('validate')\n .description('Validate all data files against schemas')\n .option(\n '--scope <scope>',\n 'Only validate these entity types (repeatable): town, landmark, operator, station, line, service, issue',\n (val: string, prev: string[] | undefined) => (prev ?? []).concat(val),\n )\n .action((opts) => {\n const dataDir = program.opts().dataDir;\n const scope = opts.scope as string[] | undefined;\n const code = runValidate({\n dataDir,\n scope: scope?.length\n ? (scope as import('../../src/validators/index.js').ValidationScope[])\n : undefined,\n });\n process.exit(code);\n });\n\nprogram\n .command('show')\n .description('Display the current state of an issue')\n .argument('<issue-id>', 'Issue ID (e.g. 2011-09-20-faulty-cable-led-to-circle-line-disruption)')\n .option('--json', 'Output as JSON')\n .action((issueId, opts) => {\n const dataDir = program.opts().dataDir;\n const code = runShowIssue({\n dataDir,\n issueId,\n json: opts.json,\n });\n process.exit(code);\n });\n\nconst list = program.command('list').description('List entities');\n\nconst listEntities = [\n 'issue',\n 'town',\n 'landmark',\n 'operator',\n 'station',\n 'line',\n 'service',\n] as const;\n\nfor (const entity of listEntities) {\n list\n .command(entity)\n .description(`List ${entity}s`)\n .option('--json', 'Output as JSON')\n .action((opts) => {\n const dataDir = program.opts().dataDir;\n const code = runList({\n dataDir,\n entity,\n json: opts.json,\n });\n process.exit(code);\n });\n}\n\nconst create = program.command('create').description('Create a new entity');\n\ncreate\n .command('issue')\n .description('Create a new issue')\n .requiredOption('--date <YYYY-MM-DD>', 'Issue date')\n .requiredOption('--slug <slug>', 'URL-safe slug for the issue')\n .requiredOption('--title <title>', 'English title')\n .option(\n '--type <type>',\n 'Issue type: disruption, maintenance, infra',\n 'disruption',\n )\n .option('--source <source>', 'Title source', 'cli')\n .option('--dry-run', 'Print what would be created without writing')\n .action(async (opts) => {\n const dataDir = program.opts().dataDir;\n const code = await runCreateIssue(\n { dataDir, dryRun: opts.dryRun },\n {\n date: opts.date,\n slug: opts.slug,\n title: opts.title,\n type: opts.type,\n source: opts.source,\n },\n );\n process.exit(code);\n });\n\ncreate\n .command('town')\n .description('Create a new town')\n .requiredOption('--id <id>', 'Town ID (e.g. yishun)')\n .requiredOption('--name <name>', 'English name')\n .option('--dry-run', 'Print what would be created without writing')\n .action(async (opts) => {\n const dataDir = program.opts().dataDir;\n const code = await runCreateTown(\n { dataDir, dryRun: opts.dryRun },\n { id: opts.id, name: opts.name },\n );\n process.exit(code);\n });\n\ncreate\n .command('landmark')\n .description('Create a new landmark')\n .requiredOption('--id <id>', 'Landmark ID (e.g. northpoint-city)')\n .requiredOption('--name <name>', 'English name')\n .option('--dry-run', 'Print what would be created without writing')\n .action(async (opts) => {\n const dataDir = program.opts().dataDir;\n const code = await runCreateLandmark(\n { dataDir, dryRun: opts.dryRun },\n { id: opts.id, name: opts.name },\n );\n process.exit(code);\n });\n\ncreate\n .command('operator')\n .description('Create a new operator')\n .requiredOption('--id <id>', 'Operator ID (e.g. SMRT_TRAINS)')\n .requiredOption('--name <name>', 'English name')\n .requiredOption('--founded-at <date>', 'Founded date (YYYY-MM-DD)')\n .option('--url <url>', 'Operator website URL')\n .option('--dry-run', 'Print what would be created without writing')\n .action(async (opts) => {\n const dataDir = program.opts().dataDir;\n const code = await runCreateOperator(\n { dataDir, dryRun: opts.dryRun },\n {\n id: opts.id,\n name: opts.name,\n foundedAt: opts.foundedAt,\n url: opts.url,\n },\n );\n process.exit(code);\n });\n\ncreate\n .command('station')\n .description('Create a station from JSON (--stdin or --file)')\n .option('--stdin', 'Read JSON from stdin')\n .option('--file <path>', 'Read JSON from file')\n .option('--dry-run', 'Print what would be created without writing')\n .action(async (opts) => {\n const dataDir = program.opts().dataDir;\n const code = await runCreateStation(\n { dataDir, dryRun: opts.dryRun, stdin: opts.stdin },\n { file: opts.file },\n );\n process.exit(code);\n });\n\ncreate\n .command('line')\n .description('Create a line from JSON (--stdin or --file)')\n .option('--stdin', 'Read JSON from stdin')\n .option('--file <path>', 'Read JSON from file')\n .option('--dry-run', 'Print what would be created without writing')\n .action(async (opts) => {\n const dataDir = program.opts().dataDir;\n const code = await runCreateLine(\n { dataDir, dryRun: opts.dryRun, stdin: opts.stdin },\n { file: opts.file },\n );\n process.exit(code);\n });\n\ncreate\n .command('service')\n .description('Create a service from JSON (--stdin or --file)')\n .option('--stdin', 'Read JSON from stdin')\n .option('--file <path>', 'Read JSON from file')\n .option('--dry-run', 'Print what would be created without writing')\n .action(async (opts) => {\n const dataDir = program.opts().dataDir;\n const code = await runCreateService(\n { dataDir, dryRun: opts.dryRun, stdin: opts.stdin },\n { file: opts.file },\n );\n process.exit(code);\n });\n\nprogram.parse();\n"]}
@@ -1,10 +0,0 @@
1
- export declare const DIR_ISSUE = "issue";
2
- export declare const DIR_LINE = "line";
3
- export declare const DIR_LANDMARK = "landmark";
4
- export declare const DIR_OPERATOR = "operator";
5
- export declare const DIR_SERVICE = "service";
6
- export declare const DIR_STATION = "station";
7
- export declare const DIR_TOWN = "town";
8
- export declare const FILE_ISSUE = "issue.json";
9
- export declare const FILE_ISSUE_EVIDENCE = "evidence.ndjson";
10
- export declare const FILE_ISSUE_IMPACT = "impact.ndjson";
package/dist/constants.js DELETED
@@ -1,11 +0,0 @@
1
- export const DIR_ISSUE = 'issue';
2
- export const DIR_LINE = 'line';
3
- export const DIR_LANDMARK = 'landmark';
4
- export const DIR_OPERATOR = 'operator';
5
- export const DIR_SERVICE = 'service';
6
- export const DIR_STATION = 'station';
7
- export const DIR_TOWN = 'town';
8
- export const FILE_ISSUE = 'issue.json';
9
- export const FILE_ISSUE_EVIDENCE = 'evidence.ndjson';
10
- export const FILE_ISSUE_IMPACT = 'impact.ndjson';
11
- //# sourceMappingURL=constants.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"/","sources":["constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC;AACjC,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC;AAC/B,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AACvC,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AACvC,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AACrC,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AACrC,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE/B,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC;AACvC,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AACrD,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC","sourcesContent":["export const DIR_ISSUE = 'issue';\nexport const DIR_LINE = 'line';\nexport const DIR_LANDMARK = 'landmark';\nexport const DIR_OPERATOR = 'operator';\nexport const DIR_SERVICE = 'service';\nexport const DIR_STATION = 'station';\nexport const DIR_TOWN = 'town';\n\nexport const FILE_ISSUE = 'issue.json';\nexport const FILE_ISSUE_EVIDENCE = 'evidence.ndjson';\nexport const FILE_ISSUE_IMPACT = 'impact.ndjson';\n"]}
@@ -1,2 +0,0 @@
1
- import { type DateTime, Duration } from 'luxon';
2
- export declare function calculateDurationWithinServiceHours(start: DateTime, end: DateTime): Duration;
@@ -1,13 +0,0 @@
1
- import { Duration, Interval } from 'luxon';
2
- import { assert } from '../util/assert.js';
3
- import { splitIntervalByServiceHours } from './splitIntervalByServiceHours.js';
4
- export function calculateDurationWithinServiceHours(start, end) {
5
- const interval = Interval.fromDateTimes(start, end);
6
- assert(interval.isValid);
7
- let result = Duration.fromObject({ seconds: 0 });
8
- for (const segment of splitIntervalByServiceHours(interval)) {
9
- result = result.plus(segment.toDuration());
10
- }
11
- return result;
12
- }
13
- //# sourceMappingURL=calculateDurationWithinServiceHours.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"calculateDurationWithinServiceHours.js","sourceRoot":"/","sources":["helpers/calculateDurationWithinServiceHours.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,QAAQ,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,MAAM,UAAU,mCAAmC,CACjD,KAAe,EACf,GAAa;IAEb,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEzB,IAAI,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAEjD,KAAK,MAAM,OAAO,IAAI,2BAA2B,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { type DateTime, Duration, Interval } from 'luxon';\nimport { assert } from '../util/assert.js';\nimport { splitIntervalByServiceHours } from './splitIntervalByServiceHours.js';\n\nexport function calculateDurationWithinServiceHours(\n start: DateTime,\n end: DateTime,\n): Duration {\n const interval = Interval.fromDateTimes(start, end);\n assert(interval.isValid);\n\n let result = Duration.fromObject({ seconds: 0 });\n\n for (const segment of splitIntervalByServiceHours(interval)) {\n result = result.plus(segment.toDuration());\n }\n\n return result;\n}\n"]}
@@ -1,83 +0,0 @@
1
- import { describe, expect, test } from 'vitest';
2
- import { calculateDurationWithinServiceHours } from './calculateDurationWithinServiceHours.js';
3
- import { DateTime } from 'luxon';
4
- describe('calculateDurationWithinServiceHours', () => {
5
- test('single day, within service hours', () => {
6
- expect(calculateDurationWithinServiceHours(DateTime.fromObject({
7
- day: 1,
8
- month: 4,
9
- year: 2025,
10
- hour: 8,
11
- minute: 0,
12
- }), DateTime.fromObject({
13
- day: 1,
14
- month: 4,
15
- year: 2025,
16
- hour: 12,
17
- minute: 30,
18
- })).as('hours')).toEqual(4.5);
19
- });
20
- describe('transcends service hour boundaries', () => {
21
- test('single day, starts before service hours', () => {
22
- expect(calculateDurationWithinServiceHours(DateTime.fromObject({
23
- day: 1,
24
- month: 4,
25
- year: 2025,
26
- hour: 5,
27
- minute: 0,
28
- }), DateTime.fromObject({
29
- day: 1,
30
- month: 4,
31
- year: 2025,
32
- hour: 6,
33
- minute: 0,
34
- })).as('hours')).toEqual(0.5);
35
- });
36
- test('single day, ends after service hours', () => {
37
- expect(calculateDurationWithinServiceHours(DateTime.fromObject({
38
- day: 1,
39
- month: 4,
40
- year: 2025,
41
- hour: 18,
42
- minute: 0,
43
- }), DateTime.fromObject({
44
- day: 2,
45
- month: 4,
46
- year: 2025,
47
- hour: 1,
48
- minute: 0,
49
- })).as('hours')).toEqual(6);
50
- });
51
- test('multiple days, transcends multiple service hours/non services hour ranges', () => {
52
- expect(calculateDurationWithinServiceHours(DateTime.fromObject({
53
- day: 1,
54
- month: 4,
55
- year: 2025,
56
- hour: 18,
57
- minute: 0,
58
- }), DateTime.fromObject({
59
- day: 2,
60
- month: 4,
61
- year: 2025,
62
- hour: 18,
63
- minute: 0,
64
- })).as('hours')).toEqual(18.5);
65
- });
66
- });
67
- test('outside service hours', () => {
68
- expect(calculateDurationWithinServiceHours(DateTime.fromObject({
69
- day: 1,
70
- month: 4,
71
- year: 2025,
72
- hour: 3,
73
- minute: 0,
74
- }), DateTime.fromObject({
75
- day: 1,
76
- month: 4,
77
- year: 2025,
78
- hour: 4,
79
- minute: 30,
80
- })).as('hours')).toEqual(0);
81
- });
82
- });
83
- //# sourceMappingURL=calculateDurationWithinServiceHours.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"calculateDurationWithinServiceHours.test.js","sourceRoot":"/","sources":["helpers/calculateDurationWithinServiceHours.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, test } from 'vitest';\nimport { calculateDurationWithinServiceHours } from './calculateDurationWithinServiceHours.js';\nimport { DateTime } from 'luxon';\n\ndescribe('calculateDurationWithinServiceHours', () => {\n test('single day, within service hours', () => {\n expect(\n calculateDurationWithinServiceHours(\n DateTime.fromObject({\n day: 1,\n month: 4,\n year: 2025,\n hour: 8,\n minute: 0,\n }),\n DateTime.fromObject({\n day: 1,\n month: 4,\n year: 2025,\n hour: 12,\n minute: 30,\n }),\n ).as('hours'),\n ).toEqual(4.5);\n });\n describe('transcends service hour boundaries', () => {\n test('single day, starts before service hours', () => {\n expect(\n calculateDurationWithinServiceHours(\n DateTime.fromObject({\n day: 1,\n month: 4,\n year: 2025,\n hour: 5,\n minute: 0,\n }),\n DateTime.fromObject({\n day: 1,\n month: 4,\n year: 2025,\n hour: 6,\n minute: 0,\n }),\n ).as('hours'),\n ).toEqual(0.5);\n });\n test('single day, ends after service hours', () => {\n expect(\n calculateDurationWithinServiceHours(\n DateTime.fromObject({\n day: 1,\n month: 4,\n year: 2025,\n hour: 18,\n minute: 0,\n }),\n DateTime.fromObject({\n day: 2,\n month: 4,\n year: 2025,\n hour: 1,\n minute: 0,\n }),\n ).as('hours'),\n ).toEqual(6);\n });\n test('multiple days, transcends multiple service hours/non services hour ranges', () => {\n expect(\n calculateDurationWithinServiceHours(\n DateTime.fromObject({\n day: 1,\n month: 4,\n year: 2025,\n hour: 18,\n minute: 0,\n }),\n DateTime.fromObject({\n day: 2,\n month: 4,\n year: 2025,\n hour: 18,\n minute: 0,\n }),\n ).as('hours'),\n ).toEqual(18.5);\n });\n });\n test('outside service hours', () => {\n expect(\n calculateDurationWithinServiceHours(\n DateTime.fromObject({\n day: 1,\n month: 4,\n year: 2025,\n hour: 3,\n minute: 0,\n }),\n DateTime.fromObject({\n day: 1,\n month: 4,\n year: 2025,\n hour: 4,\n minute: 30,\n }),\n ).as('hours'),\n ).toEqual(0);\n });\n});\n"]}
@@ -1,21 +0,0 @@
1
- import { type IssueBundleState } from '../repo/issue/helpers/deriveCurrentState.js';
2
- import type { IssueBundle } from '../schema/issue/bundle.js';
3
- import type { Claim } from '../schema/issue/claim.js';
4
- import type { ImpactEvent } from '../schema/issue/impactEvent.js';
5
- type Params = {
6
- issueBundle: IssueBundle;
7
- evidenceId: string;
8
- evidenceTs: string;
9
- claims: Claim[];
10
- };
11
- type Result = {
12
- newState: IssueBundleState;
13
- newImpactEvents: ImpactEvent[];
14
- };
15
- /**
16
- * Compute the impact from the evidence claims.
17
- * @param params - The parameters.
18
- * @returns The result.
19
- */
20
- export declare function computeImpactFromEvidenceClaims(params: Params): Result;
21
- export {};
@@ -1,293 +0,0 @@
1
- import { deepStrictEqual } from 'node:assert';
2
- import { DateTime } from 'luxon';
3
- import { deriveCurrentState, } from '../repo/issue/helpers/deriveCurrentState.js';
4
- import { assert } from '../util/assert.js';
5
- import { IdGenerator } from '../write/id/IdGenerator.js';
6
- import { keyForAffectedEntity } from './keyForAffectedEntity.js';
7
- /**
8
- * Compute the impact from the evidence claims.
9
- * @param params - The parameters.
10
- * @returns The result.
11
- */
12
- export function computeImpactFromEvidenceClaims(params) {
13
- const result = {
14
- newState: {
15
- services: {},
16
- servicesProvenance: {},
17
- facilities: {},
18
- facilitiesProvenance: {},
19
- impactEventIds: [],
20
- },
21
- newImpactEvents: [],
22
- };
23
- const eventTs = params.evidenceTs;
24
- const eventDateTime = DateTime.fromISO(eventTs);
25
- assert(eventDateTime.isValid, `Invalid date: ${eventTs}`);
26
- const currentState = deriveCurrentState(params.issueBundle);
27
- const claimsKeyedByAffectedEntity = Object.fromEntries(params.claims.map((claim) => [keyForAffectedEntity(claim.entity), claim]));
28
- for (const [key, claim] of Object.entries(claimsKeyedByAffectedEntity)) {
29
- switch (claim.entity.type) {
30
- case 'service': {
31
- const currentServiceState = currentState.services[key] ?? {
32
- effect: null,
33
- scopes: [],
34
- periods: [],
35
- causes: [],
36
- };
37
- const currentServiceProvenance = currentState.servicesProvenance[key] ?? {};
38
- if (claim.effect?.service != null &&
39
- !isEqual(currentServiceState.effect, claim.effect.service)) {
40
- currentServiceState.effect = claim.effect.service;
41
- currentServiceProvenance.effect = {
42
- evidenceId: params.evidenceId,
43
- };
44
- result.newImpactEvents.push({
45
- id: IdGenerator.impactEventId(eventDateTime),
46
- type: 'service_effects.set',
47
- ts: eventTs,
48
- basis: { evidenceId: params.evidenceId },
49
- entity: claim.entity,
50
- effect: claim.effect.service,
51
- });
52
- }
53
- switch (params.issueBundle.issue.type) {
54
- case 'disruption': {
55
- const isCleared = currentServiceState.periods.every((period) => period.kind === 'fixed' && period.endAt != null);
56
- let currentStatus = 'open';
57
- if (isCleared) {
58
- currentStatus = 'cleared';
59
- }
60
- if (currentStatus !== claim.statusSignal) {
61
- switch (claim.statusSignal) {
62
- case 'open': {
63
- break;
64
- }
65
- case 'cleared': {
66
- break;
67
- }
68
- }
69
- }
70
- break;
71
- }
72
- }
73
- if (claim.timeHints != null) {
74
- const { newPeriods, hasChanged } = reconcilePeriodsWithTimeHints(currentServiceState.periods, claim.timeHints);
75
- if (hasChanged) {
76
- currentServiceState.periods = newPeriods;
77
- currentServiceProvenance.periods = {
78
- evidenceId: params.evidenceId,
79
- };
80
- result.newImpactEvents.push({
81
- id: IdGenerator.impactEventId(eventDateTime),
82
- type: 'periods.set',
83
- ts: eventTs,
84
- basis: { evidenceId: params.evidenceId },
85
- entity: claim.entity,
86
- periods: currentServiceState.periods,
87
- });
88
- }
89
- }
90
- if (claim.scopes?.service != null &&
91
- !isEqual(currentServiceState.scopes, claim.scopes.service)) {
92
- currentServiceState.scopes = claim.scopes.service;
93
- currentServiceProvenance.scopes = {
94
- evidenceId: params.evidenceId,
95
- };
96
- result.newImpactEvents.push({
97
- id: IdGenerator.impactEventId(eventDateTime),
98
- type: 'service_scopes.set',
99
- ts: eventTs,
100
- basis: { evidenceId: params.evidenceId },
101
- entity: claim.entity,
102
- serviceScopes: claim.scopes.service,
103
- });
104
- }
105
- if (claim.causes != null &&
106
- !isEqual(currentServiceState.causes, claim.causes)) {
107
- currentServiceState.causes = claim.causes;
108
- currentServiceProvenance.causes = {
109
- evidenceId: params.evidenceId,
110
- };
111
- result.newImpactEvents.push({
112
- id: IdGenerator.impactEventId(eventDateTime),
113
- type: 'causes.set',
114
- ts: eventTs,
115
- basis: { evidenceId: params.evidenceId },
116
- entity: claim.entity,
117
- causes: claim.causes,
118
- });
119
- }
120
- result.newState.services[key] = currentServiceState;
121
- result.newState.servicesProvenance[key] = currentServiceProvenance;
122
- break;
123
- }
124
- case 'facility': {
125
- const currentFacilityState = currentState.facilities[key] ?? {
126
- effect: null,
127
- periods: [],
128
- };
129
- const currentFacilityProvenance = currentState.facilitiesProvenance[key] ?? {};
130
- if (claim.effect?.facility != null &&
131
- !isEqual(currentFacilityState.effect, claim.effect.facility)) {
132
- currentFacilityState.effect = claim.effect.facility;
133
- currentFacilityProvenance.effect = {
134
- evidenceId: params.evidenceId,
135
- };
136
- result.newImpactEvents.push({
137
- id: IdGenerator.impactEventId(eventDateTime),
138
- type: 'facility_effects.set',
139
- ts: eventTs,
140
- basis: { evidenceId: params.evidenceId },
141
- entity: claim.entity,
142
- effect: claim.effect.facility,
143
- });
144
- }
145
- if (claim.timeHints != null) {
146
- const { newPeriods, hasChanged } = reconcilePeriodsWithTimeHints(currentFacilityState.periods, claim.timeHints);
147
- if (hasChanged) {
148
- currentFacilityState.periods = newPeriods;
149
- currentFacilityProvenance.periods = {
150
- evidenceId: params.evidenceId,
151
- };
152
- result.newImpactEvents.push({
153
- id: IdGenerator.impactEventId(eventDateTime),
154
- type: 'periods.set',
155
- ts: eventTs,
156
- basis: { evidenceId: params.evidenceId },
157
- entity: claim.entity,
158
- periods: currentFacilityState.periods,
159
- });
160
- }
161
- }
162
- if (claim.causes != null &&
163
- !isEqual(currentFacilityState.causes, claim.causes)) {
164
- currentFacilityState.causes = claim.causes;
165
- currentFacilityProvenance.causes = {
166
- evidenceId: params.evidenceId,
167
- };
168
- result.newImpactEvents.push({
169
- id: IdGenerator.impactEventId(eventDateTime),
170
- type: 'causes.set',
171
- ts: eventTs,
172
- basis: { evidenceId: params.evidenceId },
173
- entity: claim.entity,
174
- causes: claim.causes,
175
- });
176
- }
177
- result.newState.facilities[key] = currentFacilityState;
178
- result.newState.facilitiesProvenance[key] = currentFacilityProvenance;
179
- break;
180
- }
181
- }
182
- }
183
- return result;
184
- }
185
- /**
186
- * Reconcile the periods with the time hints.
187
- * @param currentPeriods - The current periods.
188
- * @param timeHints - The time hints.
189
- * @returns The new periods and whether the periods have changed.
190
- */
191
- function reconcilePeriodsWithTimeHints(currentPeriods, timeHints) {
192
- switch (timeHints.kind) {
193
- case 'fixed': {
194
- return {
195
- newPeriods: [timeHints],
196
- hasChanged: true,
197
- };
198
- }
199
- case 'recurring': {
200
- return {
201
- newPeriods: [timeHints],
202
- hasChanged: true,
203
- };
204
- }
205
- case 'start-only': {
206
- let hasChanged = false;
207
- const newPeriods = [];
208
- if (currentPeriods.length === 0) {
209
- newPeriods.push({
210
- kind: 'fixed',
211
- startAt: timeHints.startAt,
212
- endAt: null,
213
- });
214
- hasChanged = true;
215
- return { newPeriods, hasChanged };
216
- }
217
- for (const period of currentPeriods) {
218
- switch (period.kind) {
219
- case 'fixed': {
220
- newPeriods.push({
221
- ...period,
222
- startAt: timeHints.startAt,
223
- });
224
- hasChanged = true;
225
- break;
226
- }
227
- case 'recurring': {
228
- const newPeriod = {
229
- ...period,
230
- startAt: timeHints.startAt,
231
- };
232
- if (newPeriod.timeWindow != null) {
233
- const startAt = DateTime.fromISO(timeHints.startAt);
234
- assert(startAt.isValid);
235
- newPeriod.timeWindow.startAt = startAt.toFormat('HH:mm:ss');
236
- }
237
- newPeriods.push(newPeriod);
238
- hasChanged = true;
239
- break;
240
- }
241
- }
242
- }
243
- return {
244
- newPeriods,
245
- hasChanged,
246
- };
247
- }
248
- case 'end-only': {
249
- let hasChanged = false;
250
- const newPeriods = [];
251
- for (const period of currentPeriods) {
252
- switch (period.kind) {
253
- case 'fixed': {
254
- newPeriods.push({
255
- ...period,
256
- endAt: timeHints.endAt,
257
- });
258
- hasChanged = true;
259
- break;
260
- }
261
- case 'recurring': {
262
- const newPeriod = {
263
- ...period,
264
- endAt: timeHints.endAt,
265
- };
266
- if (newPeriod.timeWindow != null) {
267
- const endAt = DateTime.fromISO(timeHints.endAt);
268
- assert(endAt.isValid);
269
- newPeriod.timeWindow.endAt = endAt.toFormat('HH:mm:ss');
270
- }
271
- newPeriods.push(newPeriod);
272
- hasChanged = true;
273
- break;
274
- }
275
- }
276
- }
277
- return {
278
- newPeriods,
279
- hasChanged,
280
- };
281
- }
282
- }
283
- }
284
- function isEqual(a, b) {
285
- try {
286
- deepStrictEqual(a, b);
287
- return true;
288
- }
289
- catch (error) {
290
- return false;
291
- }
292
- }
293
- //# sourceMappingURL=computeImpactFromEvidenceClaims.js.map