@mrtdown/core 2.0.0-alpha.1 → 2.0.0-alpha.10

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 (153) hide show
  1. package/dist/helpers/normalizeRecurringPeriod.d.ts +1 -1
  2. package/dist/helpers/normalizeRecurringPeriod.js +1 -1
  3. package/dist/helpers/normalizeRecurringPeriod.js.map +1 -1
  4. package/dist/helpers/normalizeRecurringPeriod.test.js.map +1 -1
  5. package/dist/helpers/resolvePeriods.d.ts +20 -5
  6. package/dist/helpers/resolvePeriods.js +15 -1
  7. package/dist/helpers/resolvePeriods.js.map +1 -1
  8. package/dist/helpers/resolvePeriods.test.js.map +1 -1
  9. package/dist/index.d.ts +22 -18
  10. package/dist/index.js +22 -18
  11. package/dist/index.js.map +1 -1
  12. package/dist/schema/Landmark.js.map +1 -1
  13. package/dist/schema/Line.d.ts +6 -0
  14. package/dist/schema/Line.js +2 -1
  15. package/dist/schema/Line.js.map +1 -1
  16. package/dist/schema/Operator.js.map +1 -1
  17. package/dist/schema/Service.js.map +1 -1
  18. package/dist/schema/Station.d.ts +7 -0
  19. package/dist/schema/Station.js +7 -6
  20. package/dist/schema/Station.js.map +1 -1
  21. package/dist/schema/Town.js.map +1 -1
  22. package/dist/schema/common.d.ts +4 -0
  23. package/dist/schema/common.js +3 -0
  24. package/dist/schema/common.js.map +1 -1
  25. package/dist/schema/issue/bundle.js.map +1 -1
  26. package/dist/schema/issue/cause.js.map +1 -1
  27. package/dist/schema/issue/claim.js.map +1 -1
  28. package/dist/schema/issue/entity.d.ts +6 -0
  29. package/dist/schema/issue/entity.js +6 -1
  30. package/dist/schema/issue/entity.js.map +1 -1
  31. package/dist/schema/issue/evidence.d.ts +6 -0
  32. package/dist/schema/issue/evidence.js +9 -4
  33. package/dist/schema/issue/evidence.js.map +1 -1
  34. package/dist/schema/issue/facilityEffect.d.ts +5 -0
  35. package/dist/schema/issue/facilityEffect.js +6 -2
  36. package/dist/schema/issue/facilityEffect.js.map +1 -1
  37. package/dist/schema/issue/id.js.map +1 -1
  38. package/dist/schema/issue/impactEvent.js.map +1 -1
  39. package/dist/schema/issue/issue.js +2 -4
  40. package/dist/schema/issue/issue.js.map +1 -1
  41. package/dist/schema/issue/issueType.js.map +1 -1
  42. package/dist/schema/issue/period.js.map +1 -1
  43. package/dist/schema/issue/serviceEffect.d.ts +7 -0
  44. package/dist/schema/issue/serviceEffect.js +10 -4
  45. package/dist/schema/issue/serviceEffect.js.map +1 -1
  46. package/dist/schema/issue/serviceScope.d.ts +6 -0
  47. package/dist/schema/issue/serviceScope.js +8 -3
  48. package/dist/schema/issue/serviceScope.js.map +1 -1
  49. package/dist/util/assert.js.map +1 -1
  50. package/package.json +21 -61
  51. package/README.md +0 -107
  52. package/dist/constants.d.ts +0 -10
  53. package/dist/constants.js +0 -11
  54. package/dist/constants.js.map +0 -1
  55. package/dist/helpers/calculateDurationWithinServiceHours.d.ts +0 -2
  56. package/dist/helpers/calculateDurationWithinServiceHours.js +0 -13
  57. package/dist/helpers/calculateDurationWithinServiceHours.js.map +0 -1
  58. package/dist/helpers/calculateDurationWithinServiceHours.test.d.ts +0 -1
  59. package/dist/helpers/calculateDurationWithinServiceHours.test.js +0 -83
  60. package/dist/helpers/calculateDurationWithinServiceHours.test.js.map +0 -1
  61. package/dist/helpers/computeImpactFromEvidenceClaims.d.ts +0 -21
  62. package/dist/helpers/computeImpactFromEvidenceClaims.js +0 -293
  63. package/dist/helpers/computeImpactFromEvidenceClaims.js.map +0 -1
  64. package/dist/helpers/computeImpactFromEvidenceClaims.test.d.ts +0 -1
  65. package/dist/helpers/computeImpactFromEvidenceClaims.test.js +0 -544
  66. package/dist/helpers/computeImpactFromEvidenceClaims.test.js.map +0 -1
  67. package/dist/helpers/computeStartOfDaysWithinInterval.d.ts +0 -2
  68. package/dist/helpers/computeStartOfDaysWithinInterval.js +0 -15
  69. package/dist/helpers/computeStartOfDaysWithinInterval.js.map +0 -1
  70. package/dist/helpers/computeStartOfDaysWithinInterval.test.d.ts +0 -1
  71. package/dist/helpers/computeStartOfDaysWithinInterval.test.js +0 -126
  72. package/dist/helpers/computeStartOfDaysWithinInterval.test.js.map +0 -1
  73. package/dist/helpers/estimateOpenAICost.d.ts +0 -40
  74. package/dist/helpers/estimateOpenAICost.js +0 -55
  75. package/dist/helpers/estimateOpenAICost.js.map +0 -1
  76. package/dist/helpers/keyForAffectedEntity.d.ts +0 -7
  77. package/dist/helpers/keyForAffectedEntity.js +0 -14
  78. package/dist/helpers/keyForAffectedEntity.js.map +0 -1
  79. package/dist/helpers/splitIntervalByServiceHours.d.ts +0 -2
  80. package/dist/helpers/splitIntervalByServiceHours.js +0 -30
  81. package/dist/helpers/splitIntervalByServiceHours.js.map +0 -1
  82. package/dist/helpers/splitIntervalByServiceHours.test.d.ts +0 -1
  83. package/dist/helpers/splitIntervalByServiceHours.test.js +0 -152
  84. package/dist/helpers/splitIntervalByServiceHours.test.js.map +0 -1
  85. package/dist/helpers/sumIntervalDuration.d.ts +0 -2
  86. package/dist/helpers/sumIntervalDuration.js +0 -9
  87. package/dist/helpers/sumIntervalDuration.js.map +0 -1
  88. package/dist/repo/MRTDownRepository.d.ts +0 -23
  89. package/dist/repo/MRTDownRepository.js +0 -28
  90. package/dist/repo/MRTDownRepository.js.map +0 -1
  91. package/dist/repo/common/FileStore.d.ts +0 -12
  92. package/dist/repo/common/FileStore.js +0 -27
  93. package/dist/repo/common/FileStore.js.map +0 -1
  94. package/dist/repo/common/StandardRepository.d.ts +0 -32
  95. package/dist/repo/common/StandardRepository.js +0 -58
  96. package/dist/repo/common/StandardRepository.js.map +0 -1
  97. package/dist/repo/common/store.d.ts +0 -29
  98. package/dist/repo/common/store.js +0 -2
  99. package/dist/repo/common/store.js.map +0 -1
  100. package/dist/repo/issue/IssueRepository.d.ts +0 -36
  101. package/dist/repo/issue/IssueRepository.js +0 -177
  102. package/dist/repo/issue/IssueRepository.js.map +0 -1
  103. package/dist/repo/issue/helpers/deriveCurrentState.d.ts +0 -51
  104. package/dist/repo/issue/helpers/deriveCurrentState.js +0 -113
  105. package/dist/repo/issue/helpers/deriveCurrentState.js.map +0 -1
  106. package/dist/repo/issue/helpers/deriveCurrentState.test.d.ts +0 -1
  107. package/dist/repo/issue/helpers/deriveCurrentState.test.js +0 -477
  108. package/dist/repo/issue/helpers/deriveCurrentState.test.js.map +0 -1
  109. package/dist/repo/landmark/LandmarkRepository.d.ts +0 -7
  110. package/dist/repo/landmark/LandmarkRepository.js +0 -12
  111. package/dist/repo/landmark/LandmarkRepository.js.map +0 -1
  112. package/dist/repo/line/LineRepository.d.ts +0 -13
  113. package/dist/repo/line/LineRepository.js +0 -32
  114. package/dist/repo/line/LineRepository.js.map +0 -1
  115. package/dist/repo/operator/OperatorRepository.d.ts +0 -7
  116. package/dist/repo/operator/OperatorRepository.js +0 -12
  117. package/dist/repo/operator/OperatorRepository.js.map +0 -1
  118. package/dist/repo/service/ServiceRepository.d.ts +0 -19
  119. package/dist/repo/service/ServiceRepository.js +0 -39
  120. package/dist/repo/service/ServiceRepository.js.map +0 -1
  121. package/dist/repo/station/StationRepository.d.ts +0 -13
  122. package/dist/repo/station/StationRepository.js +0 -30
  123. package/dist/repo/station/StationRepository.js.map +0 -1
  124. package/dist/repo/town/TownRepository.d.ts +0 -7
  125. package/dist/repo/town/TownRepository.js +0 -12
  126. package/dist/repo/town/TownRepository.js.map +0 -1
  127. package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.d.ts +0 -7
  128. package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.js +0 -24
  129. package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.js.map +0 -1
  130. package/dist/util/ingestContent/index.d.ts +0 -12
  131. package/dist/util/ingestContent/index.js +0 -171
  132. package/dist/util/ingestContent/index.js.map +0 -1
  133. package/dist/util/ingestContent/types.d.ts +0 -32
  134. package/dist/util/ingestContent/types.js +0 -2
  135. package/dist/util/ingestContent/types.js.map +0 -1
  136. package/dist/write/MRTDownWriter.d.ts +0 -27
  137. package/dist/write/MRTDownWriter.js +0 -27
  138. package/dist/write/MRTDownWriter.js.map +0 -1
  139. package/dist/write/common/FileWriteStore.d.ts +0 -13
  140. package/dist/write/common/FileWriteStore.js +0 -31
  141. package/dist/write/common/FileWriteStore.js.map +0 -1
  142. package/dist/write/common/StandardWriter.d.ts +0 -14
  143. package/dist/write/common/StandardWriter.js +0 -17
  144. package/dist/write/common/StandardWriter.js.map +0 -1
  145. package/dist/write/common/store.d.ts +0 -32
  146. package/dist/write/common/store.js +0 -2
  147. package/dist/write/common/store.js.map +0 -1
  148. package/dist/write/id/IdGenerator.d.ts +0 -18
  149. package/dist/write/id/IdGenerator.js +0 -23
  150. package/dist/write/id/IdGenerator.js.map +0 -1
  151. package/dist/write/issue/IssueWriter.d.ts +0 -12
  152. package/dist/write/issue/IssueWriter.js +0 -33
  153. package/dist/write/issue/IssueWriter.js.map +0 -1
@@ -1,19 +0,0 @@
1
- import { type Service } from '../../schema/Service.js';
2
- import { StandardRepository } from '../common/StandardRepository.js';
3
- import type { IStore } from '../common/store.js';
4
- export declare class ServiceRepository extends StandardRepository<Service> {
5
- constructor(store: IStore);
6
- protected parseItem(json: unknown): Service;
7
- /**
8
- * Search services by name.
9
- * @param names
10
- * @returns
11
- */
12
- searchByName(names: string[]): Service[];
13
- /**
14
- * Search services by line ID.
15
- * @param lineId
16
- * @returns
17
- */
18
- searchByLineId(lineId: string): Service[];
19
- }
@@ -1,39 +0,0 @@
1
- import Fuse from 'fuse.js';
2
- import { DIR_SERVICE } from '../../constants.js';
3
- import { ServiceSchema } from '../../schema/Service.js';
4
- import { StandardRepository } from '../common/StandardRepository.js';
5
- export class ServiceRepository extends StandardRepository {
6
- constructor(store) {
7
- super(store, DIR_SERVICE);
8
- }
9
- parseItem(json) {
10
- return ServiceSchema.parse(json);
11
- }
12
- /**
13
- * Search services by name.
14
- * @param names
15
- * @returns
16
- */
17
- searchByName(names) {
18
- this.loadAll();
19
- const fuse = new Fuse(Array.from(this.byId.values()), {
20
- keys: ['id', 'name.en-SG'],
21
- includeScore: true,
22
- threshold: 0.3,
23
- });
24
- const results = fuse.search({
25
- $or: names.flatMap((name) => [{ id: name }, { 'name.en-SG': name }]),
26
- });
27
- return results.map((r) => r.item);
28
- }
29
- /**
30
- * Search services by line ID.
31
- * @param lineId
32
- * @returns
33
- */
34
- searchByLineId(lineId) {
35
- this.loadAll();
36
- return Array.from(this.byId.values()).filter((s) => s.lineId === lineId);
37
- }
38
- }
39
- //# sourceMappingURL=ServiceRepository.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ServiceRepository.js","sourceRoot":"/","sources":["repo/service/ServiceRepository.ts"],"names":[],"mappings":"AAAA,OAAO,IAAyB,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAgB,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAGrE,MAAM,OAAO,iBAAkB,SAAQ,kBAA2B;IAChE,YAAY,KAAa;QACvB,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC5B,CAAC;IAES,SAAS,CAAC,IAAa;QAC/B,OAAO,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,KAAe;QAC1B,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;YACpD,IAAI,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;YAC1B,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;YAC1B,GAAG,EAAE,KAAK,CAAC,OAAO,CAChB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAiB,CACjE;SACF,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED;;;;OAIG;IACH,cAAc,CAAC,MAAc;QAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IAC3E,CAAC;CACF","sourcesContent":["import Fuse, { type Expression } from 'fuse.js';\nimport { DIR_SERVICE } from '../../constants.js';\nimport { type Service, ServiceSchema } from '../../schema/Service.js';\nimport { StandardRepository } from '../common/StandardRepository.js';\nimport type { IStore } from '../common/store.js';\n\nexport class ServiceRepository extends StandardRepository<Service> {\n constructor(store: IStore) {\n super(store, DIR_SERVICE);\n }\n\n protected parseItem(json: unknown): Service {\n return ServiceSchema.parse(json);\n }\n\n /**\n * Search services by name.\n * @param names\n * @returns\n */\n searchByName(names: string[]): Service[] {\n this.loadAll();\n const fuse = new Fuse(Array.from(this.byId.values()), {\n keys: ['id', 'name.en-SG'],\n includeScore: true,\n threshold: 0.3,\n });\n const results = fuse.search({\n $or: names.flatMap(\n (name) => [{ id: name }, { 'name.en-SG': name }] as Expression[],\n ),\n });\n return results.map((r) => r.item);\n }\n\n /**\n * Search services by line ID.\n * @param lineId\n * @returns\n */\n searchByLineId(lineId: string): Service[] {\n this.loadAll();\n return Array.from(this.byId.values()).filter((s) => s.lineId === lineId);\n }\n}\n"]}
@@ -1,13 +0,0 @@
1
- import { type Station } from '../../schema/Station.js';
2
- import { StandardRepository } from '../common/StandardRepository.js';
3
- import type { IStore } from '../common/store.js';
4
- export declare class StationRepository extends StandardRepository<Station> {
5
- constructor(store: IStore);
6
- protected parseItem(json: unknown): Station;
7
- /**
8
- * Search stations by name.
9
- * @param names
10
- * @returns
11
- */
12
- searchByName(names: string[]): Station[];
13
- }
@@ -1,30 +0,0 @@
1
- import Fuse from 'fuse.js';
2
- import { DIR_STATION } from '../../constants.js';
3
- import { StationSchema } from '../../schema/Station.js';
4
- import { StandardRepository } from '../common/StandardRepository.js';
5
- export class StationRepository extends StandardRepository {
6
- constructor(store) {
7
- super(store, DIR_STATION);
8
- }
9
- parseItem(json) {
10
- return StationSchema.parse(json);
11
- }
12
- /**
13
- * Search stations by name.
14
- * @param names
15
- * @returns
16
- */
17
- searchByName(names) {
18
- this.loadAll();
19
- const fuse = new Fuse(Array.from(this.byId.values()), {
20
- keys: ['id', 'name.en-SG'],
21
- includeScore: true,
22
- threshold: 0.2,
23
- });
24
- const results = fuse.search({
25
- $or: names.flatMap((name) => [{ id: name }, { 'name.en-SG': name }]),
26
- });
27
- return results.map((r) => r.item);
28
- }
29
- }
30
- //# sourceMappingURL=StationRepository.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"StationRepository.js","sourceRoot":"/","sources":["repo/station/StationRepository.ts"],"names":[],"mappings":"AAAA,OAAO,IAAyB,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAgB,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAGrE,MAAM,OAAO,iBAAkB,SAAQ,kBAA2B;IAChE,YAAY,KAAa;QACvB,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC5B,CAAC;IAES,SAAS,CAAC,IAAa;QAC/B,OAAO,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,KAAe;QAC1B,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;YACpD,IAAI,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;YAC1B,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;YAC1B,GAAG,EAAE,KAAK,CAAC,OAAO,CAChB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAiB,CACjE;SACF,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;CACF","sourcesContent":["import Fuse, { type Expression } from 'fuse.js';\nimport { DIR_STATION } from '../../constants.js';\nimport { type Station, StationSchema } from '../../schema/Station.js';\nimport { StandardRepository } from '../common/StandardRepository.js';\nimport type { IStore } from '../common/store.js';\n\nexport class StationRepository extends StandardRepository<Station> {\n constructor(store: IStore) {\n super(store, DIR_STATION);\n }\n\n protected parseItem(json: unknown): Station {\n return StationSchema.parse(json);\n }\n\n /**\n * Search stations by name.\n * @param names\n * @returns\n */\n searchByName(names: string[]): Station[] {\n this.loadAll();\n const fuse = new Fuse(Array.from(this.byId.values()), {\n keys: ['id', 'name.en-SG'],\n includeScore: true,\n threshold: 0.2,\n });\n const results = fuse.search({\n $or: names.flatMap(\n (name) => [{ id: name }, { 'name.en-SG': name }] as Expression[],\n ),\n });\n return results.map((r) => r.item);\n }\n}\n"]}
@@ -1,7 +0,0 @@
1
- import { type Town } from '../../schema/Town.js';
2
- import { StandardRepository } from '../common/StandardRepository.js';
3
- import type { IStore } from '../common/store.js';
4
- export declare class TownRepository extends StandardRepository<Town> {
5
- constructor(store: IStore);
6
- protected parseItem(json: unknown): Town;
7
- }
@@ -1,12 +0,0 @@
1
- import { DIR_TOWN } from '../../constants.js';
2
- import { TownSchema } from '../../schema/Town.js';
3
- import { StandardRepository } from '../common/StandardRepository.js';
4
- export class TownRepository extends StandardRepository {
5
- constructor(store) {
6
- super(store, DIR_TOWN);
7
- }
8
- parseItem(json) {
9
- return TownSchema.parse(json);
10
- }
11
- }
12
- //# sourceMappingURL=TownRepository.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TownRepository.js","sourceRoot":"/","sources":["repo/town/TownRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAa,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAGrE,MAAM,OAAO,cAAe,SAAQ,kBAAwB;IAC1D,YAAY,KAAa;QACvB,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACzB,CAAC;IAES,SAAS,CAAC,IAAa;QAC/B,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;CACF","sourcesContent":["import { DIR_TOWN } from '../../constants.js';\nimport { type Town, TownSchema } from '../../schema/Town.js';\nimport { StandardRepository } from '../common/StandardRepository.js';\nimport type { IStore } from '../common/store.js';\n\nexport class TownRepository extends StandardRepository<Town> {\n constructor(store: IStore) {\n super(store, DIR_TOWN);\n }\n\n protected parseItem(json: unknown): Town {\n return TownSchema.parse(json);\n }\n}\n"]}
@@ -1,7 +0,0 @@
1
- import type { Claim } from '#schema/issue/claim.js';
2
- /**
3
- * Get the slug date time from the claims.
4
- * @param claims - The claims.
5
- * @returns The slug date time or null if no time hints are found.
6
- */
7
- export declare function getSlugDateTimeFromClaims(claims: Claim[]): string | null;
@@ -1,24 +0,0 @@
1
- import { assert } from '#util/assert.js';
2
- /**
3
- * Get the slug date time from the claims.
4
- * @param claims - The claims.
5
- * @returns The slug date time or null if no time hints are found.
6
- */
7
- export function getSlugDateTimeFromClaims(claims) {
8
- const timeHints = claims
9
- .filter((claim) => claim.timeHints != null)
10
- .map((claim) => claim.timeHints);
11
- if (timeHints.length > 0) {
12
- assert(timeHints[0] != null, 'Expected time hints');
13
- switch (timeHints[0].kind) {
14
- case 'fixed': {
15
- return timeHints[0].startAt;
16
- }
17
- case 'recurring': {
18
- return timeHints[0].startAt;
19
- }
20
- }
21
- }
22
- return null;
23
- }
24
- //# sourceMappingURL=getSlugDateTimeFromClaims.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getSlugDateTimeFromClaims.js","sourceRoot":"/","sources":["util/ingestContent/helpers/getSlugDateTimeFromClaims.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAe;IACvD,MAAM,SAAS,GAAG,MAAM;SACrB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC;SAC1C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEnC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,qBAAqB,CAAC,CAAC;QACpD,QAAQ,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC1B,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9B,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import type { Claim } from '#schema/issue/claim.js';\nimport { assert } from '#util/assert.js';\n\n/**\n * Get the slug date time from the claims.\n * @param claims - The claims.\n * @returns The slug date time or null if no time hints are found.\n */\nexport function getSlugDateTimeFromClaims(claims: Claim[]): string | null {\n const timeHints = claims\n .filter((claim) => claim.timeHints != null)\n .map((claim) => claim.timeHints);\n\n if (timeHints.length > 0) {\n assert(timeHints[0] != null, 'Expected time hints');\n switch (timeHints[0].kind) {\n case 'fixed': {\n return timeHints[0].startAt;\n }\n case 'recurring': {\n return timeHints[0].startAt;\n }\n }\n }\n\n return null;\n}\n"]}
@@ -1,12 +0,0 @@
1
- import type { IngestContent } from './types.js';
2
- /**
3
- * Ingests content from social media, news, or other sources into the MRTDown issue system.
4
- *
5
- * Triages the content to determine if it belongs to an existing issue or a new one, extracts
6
- * claims, computes impact (affected lines, stations, periods), and persists evidence and impact
7
- * events. Irrelevant content is ignored.
8
- *
9
- * @param content - The content to ingest (Reddit post, news article, or Twitter/Mastodon post).
10
- * @returns `null` when content is irrelevant or after successful ingestion.
11
- */
12
- export declare function ingestContent(content: IngestContent): Promise<null>;
@@ -1,171 +0,0 @@
1
- import { resolve } from 'node:path';
2
- import { DateTime } from 'luxon';
3
- import { ulid } from 'ulid';
4
- import { computeImpactFromEvidenceClaims } from '#helpers/computeImpactFromEvidenceClaims.js';
5
- import { extractClaimsFromNewEvidence } from '#llm/functions/extractClaimsFromNewEvidence/index.js';
6
- import { generateIssueTitleAndSlug } from '#llm/functions/generateIssueTitleAndSlug/index.js';
7
- import { translate } from '#llm/functions/translate/index.js';
8
- import { triageNewEvidence } from '#llm/functions/triageNewEvidence/index.js';
9
- import { FileStore } from '#repo/common/FileStore.js';
10
- import { MRTDownRepository } from '#repo/MRTDownRepository.js';
11
- import { FileWriteStore } from '#write/common/FileWriteStore.js';
12
- import { MRTDownWriter } from '#write/MRTDownWriter.js';
13
- import { assert } from '../assert.js';
14
- import { getSlugDateTimeFromClaims } from './helpers/getSlugDateTimeFromClaims.js';
15
- const DATA_DIR = resolve(import.meta.dirname, '../../../data');
16
- const store = new FileStore(DATA_DIR);
17
- const writeStore = new FileWriteStore(DATA_DIR);
18
- const repo = new MRTDownRepository({ store });
19
- const writer = new MRTDownWriter({ store: writeStore });
20
- /**
21
- * Ingests content from social media, news, or other sources into the MRTDown issue system.
22
- *
23
- * Triages the content to determine if it belongs to an existing issue or a new one, extracts
24
- * claims, computes impact (affected lines, stations, periods), and persists evidence and impact
25
- * events. Irrelevant content is ignored.
26
- *
27
- * @param content - The content to ingest (Reddit post, news article, or Twitter/Mastodon post).
28
- * @returns `null` when content is irrelevant or after successful ingestion.
29
- */
30
- export async function ingestContent(content) {
31
- // --- Normalise input ---
32
- // HACK: Force `createdAt` to be Asia/Singapore timezone
33
- const createdAt = DateTime.fromISO(content.createdAt)
34
- .setZone('Asia/Singapore')
35
- .toISO();
36
- assert(createdAt != null, 'Expected valid createdAt');
37
- content.createdAt = createdAt;
38
- console.log('[ingestContent]', content);
39
- // --- Triage: existing issue, new issue, or irrelevant ---
40
- const triageResult = await triageNewEvidence({
41
- newEvidence: {
42
- ts: content.createdAt,
43
- text: getText(content),
44
- },
45
- repo,
46
- });
47
- console.log('[ingestContent.triageNewEvidence]', triageResult);
48
- if (triageResult.result.kind === 'irrelevant-content') {
49
- console.log('[ingestContent] Nothing to do.');
50
- return null;
51
- }
52
- // --- Extract structured claims (lines, stations, periods, effects) ---
53
- const { claims } = await extractClaimsFromNewEvidence({
54
- newEvidence: {
55
- ts: content.createdAt,
56
- text: getText(content),
57
- },
58
- repo,
59
- });
60
- console.log('[ingestContent.extractClaimsFromNewEvidence]', claims);
61
- // --- Resolve issue bundle: fetch existing or create new ---
62
- let issueBundle;
63
- switch (triageResult.result.kind) {
64
- case 'part-of-existing-issue': {
65
- // Load full bundle (issue + evidence + impact) for impact computation
66
- const { issueId } = triageResult.result;
67
- const existingBundle = repo.issues.get(issueId);
68
- assert(existingBundle != null, `Expected issue for id=${issueId}`);
69
- issueBundle = existingBundle;
70
- break;
71
- }
72
- case 'part-of-new-issue': {
73
- // Create issue: derive date from claims, generate title/slug, translate, persist
74
- const slugDateTime = DateTime.fromISO(getSlugDateTimeFromClaims(claims) ?? content.createdAt);
75
- assert(slugDateTime.isValid, `Invalid date: ${content.createdAt}`);
76
- const { title, slug } = await generateIssueTitleAndSlug({
77
- text: getText(content),
78
- });
79
- console.log('[ingestContent.generateSlug]', slug);
80
- const translatedTitles = await translate(title);
81
- const issueId = `${slugDateTime.toFormat('yyyy-MM-dd')}-${slug}`;
82
- const issue = {
83
- id: issueId,
84
- type: triageResult.result.issueType,
85
- title: translatedTitles,
86
- titleMeta: {
87
- source: '@openai/gpt-5-nano',
88
- },
89
- };
90
- writer.issues.create(issue);
91
- issueBundle = {
92
- issue,
93
- evidence: [],
94
- impactEvents: [],
95
- path: DATA_DIR,
96
- };
97
- break;
98
- }
99
- }
100
- // --- Build evidence record ---
101
- const contentDateTime = DateTime.fromISO(content.createdAt);
102
- assert(contentDateTime.isValid, `Invalid date: ${content.createdAt}`);
103
- const evidence = {
104
- id: `ev_${ulid(contentDateTime.toMillis())}`,
105
- ts: contentDateTime.toISO({ includeOffset: true }),
106
- type: getEvidenceType(content),
107
- text: getText(content),
108
- sourceUrl: content.url,
109
- render: {
110
- text: await translate(getText(content)),
111
- source: '@openai/gpt-5-nano',
112
- },
113
- };
114
- // --- Compute impact events from claims (effects, scopes, periods) ---
115
- const { newImpactEvents } = computeImpactFromEvidenceClaims({
116
- issueBundle: {
117
- ...issueBundle,
118
- evidence: [...issueBundle.evidence, evidence],
119
- },
120
- evidenceId: evidence.id,
121
- evidenceTs: evidence.ts,
122
- claims,
123
- });
124
- // --- Persist to disk ---
125
- writer.issues.appendEvidence(issueBundle.issue.id, evidence);
126
- for (const impact of newImpactEvents) {
127
- writer.issues.appendImpact(issueBundle.issue.id, impact);
128
- }
129
- return null;
130
- }
131
- /**
132
- * Extracts the primary text content from an IngestContent item based on its source type.
133
- *
134
- * @param content - The content to extract text from.
135
- * @returns The text body (selftext for Reddit, summary for news, text for social).
136
- */
137
- function getText(content) {
138
- switch (content.source) {
139
- case 'reddit': {
140
- return content.selftext;
141
- }
142
- case 'news-website': {
143
- return content.summary;
144
- }
145
- case 'twitter':
146
- case 'mastodon': {
147
- return content.text;
148
- }
149
- }
150
- }
151
- /**
152
- * Maps IngestContent source type to the corresponding Evidence type for provenance tracking.
153
- *
154
- * @param content - The content to classify.
155
- * @returns The evidence type: official-statement (Reddit), media.report (news), or public.report (social).
156
- */
157
- function getEvidenceType(content) {
158
- switch (content.source) {
159
- case 'reddit': {
160
- return 'official-statement';
161
- }
162
- case 'news-website': {
163
- return 'media.report';
164
- }
165
- case 'twitter':
166
- case 'mastodon': {
167
- return 'public.report';
168
- }
169
- }
170
- }
171
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"/","sources":["util/ingestContent/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from 'node:path';\nimport { DateTime } from 'luxon';\nimport { ulid } from 'ulid';\nimport { computeImpactFromEvidenceClaims } from '#helpers/computeImpactFromEvidenceClaims.js';\nimport { extractClaimsFromNewEvidence } from '#llm/functions/extractClaimsFromNewEvidence/index.js';\nimport { generateIssueTitleAndSlug } from '#llm/functions/generateIssueTitleAndSlug/index.js';\nimport { translate } from '#llm/functions/translate/index.js';\nimport { triageNewEvidence } from '#llm/functions/triageNewEvidence/index.js';\nimport { FileStore } from '#repo/common/FileStore.js';\nimport { MRTDownRepository } from '#repo/MRTDownRepository.js';\nimport type { IssueBundle } from '#schema/issue/bundle.js';\nimport type { Evidence } from '#schema/issue/evidence.js';\nimport type { Issue } from '#schema/issue/issue.js';\nimport { FileWriteStore } from '#write/common/FileWriteStore.js';\nimport { MRTDownWriter } from '#write/MRTDownWriter.js';\nimport { assert } from '../assert.js';\nimport { getSlugDateTimeFromClaims } from './helpers/getSlugDateTimeFromClaims.js';\nimport type { IngestContent } from './types.js';\n\nconst DATA_DIR = resolve(import.meta.dirname, '../../../data');\n\nconst store = new FileStore(DATA_DIR);\nconst writeStore = new FileWriteStore(DATA_DIR);\nconst repo = new MRTDownRepository({ store });\nconst writer = new MRTDownWriter({ store: writeStore });\n\n/**\n * Ingests content from social media, news, or other sources into the MRTDown issue system.\n *\n * Triages the content to determine if it belongs to an existing issue or a new one, extracts\n * claims, computes impact (affected lines, stations, periods), and persists evidence and impact\n * events. Irrelevant content is ignored.\n *\n * @param content - The content to ingest (Reddit post, news article, or Twitter/Mastodon post).\n * @returns `null` when content is irrelevant or after successful ingestion.\n */\nexport async function ingestContent(content: IngestContent) {\n // --- Normalise input ---\n // HACK: Force `createdAt` to be Asia/Singapore timezone\n const createdAt = DateTime.fromISO(content.createdAt)\n .setZone('Asia/Singapore')\n .toISO();\n assert(createdAt != null, 'Expected valid createdAt');\n\n content.createdAt = createdAt;\n console.log('[ingestContent]', content);\n\n // --- Triage: existing issue, new issue, or irrelevant ---\n const triageResult = await triageNewEvidence({\n newEvidence: {\n ts: content.createdAt,\n text: getText(content),\n },\n repo,\n });\n console.log('[ingestContent.triageNewEvidence]', triageResult);\n\n if (triageResult.result.kind === 'irrelevant-content') {\n console.log('[ingestContent] Nothing to do.');\n return null;\n }\n\n // --- Extract structured claims (lines, stations, periods, effects) ---\n const { claims } = await extractClaimsFromNewEvidence({\n newEvidence: {\n ts: content.createdAt,\n text: getText(content),\n },\n repo,\n });\n console.log('[ingestContent.extractClaimsFromNewEvidence]', claims);\n\n // --- Resolve issue bundle: fetch existing or create new ---\n let issueBundle: IssueBundle;\n\n switch (triageResult.result.kind) {\n case 'part-of-existing-issue': {\n // Load full bundle (issue + evidence + impact) for impact computation\n const { issueId } = triageResult.result;\n const existingBundle = repo.issues.get(issueId);\n assert(existingBundle != null, `Expected issue for id=${issueId}`);\n issueBundle = existingBundle;\n break;\n }\n case 'part-of-new-issue': {\n // Create issue: derive date from claims, generate title/slug, translate, persist\n const slugDateTime = DateTime.fromISO(\n getSlugDateTimeFromClaims(claims) ?? content.createdAt,\n );\n assert(slugDateTime.isValid, `Invalid date: ${content.createdAt}`);\n\n const { title, slug } = await generateIssueTitleAndSlug({\n text: getText(content),\n });\n console.log('[ingestContent.generateSlug]', slug);\n\n const translatedTitles = await translate(title);\n\n const issueId = `${slugDateTime.toFormat('yyyy-MM-dd')}-${slug}`;\n\n const issue: Issue = {\n id: issueId,\n type: triageResult.result.issueType,\n title: translatedTitles,\n titleMeta: {\n source: '@openai/gpt-5-nano',\n },\n };\n writer.issues.create(issue);\n\n issueBundle = {\n issue,\n evidence: [],\n impactEvents: [],\n path: DATA_DIR,\n };\n break;\n }\n }\n\n // --- Build evidence record ---\n const contentDateTime = DateTime.fromISO(content.createdAt);\n assert(contentDateTime.isValid, `Invalid date: ${content.createdAt}`);\n\n const evidence: Evidence = {\n id: `ev_${ulid(contentDateTime.toMillis())}`,\n ts: contentDateTime.toISO({ includeOffset: true }),\n type: getEvidenceType(content),\n text: getText(content),\n sourceUrl: content.url,\n render: {\n text: await translate(getText(content)),\n source: '@openai/gpt-5-nano',\n },\n };\n\n // --- Compute impact events from claims (effects, scopes, periods) ---\n const { newImpactEvents } = computeImpactFromEvidenceClaims({\n issueBundle: {\n ...issueBundle,\n evidence: [...issueBundle.evidence, evidence],\n },\n evidenceId: evidence.id,\n evidenceTs: evidence.ts,\n claims,\n });\n\n // --- Persist to disk ---\n writer.issues.appendEvidence(issueBundle.issue.id, evidence);\n for (const impact of newImpactEvents) {\n writer.issues.appendImpact(issueBundle.issue.id, impact);\n }\n\n return null;\n}\n\n/**\n * Extracts the primary text content from an IngestContent item based on its source type.\n *\n * @param content - The content to extract text from.\n * @returns The text body (selftext for Reddit, summary for news, text for social).\n */\nfunction getText(content: IngestContent) {\n switch (content.source) {\n case 'reddit': {\n return content.selftext;\n }\n case 'news-website': {\n return content.summary;\n }\n case 'twitter':\n case 'mastodon': {\n return content.text;\n }\n }\n}\n\n/**\n * Maps IngestContent source type to the corresponding Evidence type for provenance tracking.\n *\n * @param content - The content to classify.\n * @returns The evidence type: official-statement (Reddit), media.report (news), or public.report (social).\n */\nfunction getEvidenceType(content: IngestContent) {\n switch (content.source) {\n case 'reddit': {\n return 'official-statement';\n }\n case 'news-website': {\n return 'media.report';\n }\n case 'twitter':\n case 'mastodon': {\n return 'public.report';\n }\n }\n}\n"]}
@@ -1,32 +0,0 @@
1
- import type { z } from 'zod';
2
- export type IngestContentTwitter = {
3
- source: 'twitter' | 'mastodon';
4
- accountName: string;
5
- text: string;
6
- url: string;
7
- createdAt: string;
8
- };
9
- export type IngestContentReddit = {
10
- source: 'reddit';
11
- subreddit: string;
12
- title: string;
13
- selftext: string;
14
- url: string;
15
- createdAt: string;
16
- thumbnailUrl: string | null;
17
- };
18
- export type IngestContentNewsArticle = {
19
- source: 'news-website';
20
- title: string;
21
- summary: string;
22
- url: string;
23
- createdAt: string;
24
- };
25
- export type IngestContent = IngestContentTwitter | IngestContentReddit | IngestContentNewsArticle;
26
- export type Tool<TParams = any> = {
27
- name: string;
28
- description: string;
29
- paramSchema: z.ZodType<TParams>;
30
- runner: (param: TParams) => Promise<string>;
31
- };
32
- export type ToolRegistry = Record<string, Tool>;
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"/","sources":["util/ingestContent/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { z } from 'zod';\n\nexport type IngestContentTwitter = {\n source: 'twitter' | 'mastodon';\n accountName: string;\n text: string;\n url: string;\n createdAt: string;\n};\n\nexport type IngestContentReddit = {\n source: 'reddit';\n subreddit: string;\n title: string;\n selftext: string;\n url: string;\n createdAt: string;\n thumbnailUrl: string | null;\n};\n\nexport type IngestContentNewsArticle = {\n source: 'news-website';\n title: string;\n summary: string;\n url: string;\n createdAt: string;\n};\n\nexport type IngestContent =\n | IngestContentTwitter\n | IngestContentReddit\n | IngestContentNewsArticle;\n\nexport type Tool<TParams = any> = {\n name: string;\n description: string;\n paramSchema: z.ZodType<TParams>;\n runner: (param: TParams) => Promise<string>;\n};\n\nexport type ToolRegistry = Record<string, Tool>;\n"]}
@@ -1,27 +0,0 @@
1
- import type { Landmark } from '../schema/Landmark.js';
2
- import type { Line } from '../schema/Line.js';
3
- import type { Operator } from '../schema/Operator.js';
4
- import type { Service } from '../schema/Service.js';
5
- import type { Station } from '../schema/Station.js';
6
- import type { Town } from '../schema/Town.js';
7
- import { StandardWriter } from './common/StandardWriter.js';
8
- import type { IWriteStore } from './common/store.js';
9
- import { IssueWriter } from './issue/IssueWriter.js';
10
- type MRTDownWriterParams = {
11
- store: IWriteStore;
12
- };
13
- /**
14
- * A writer for the MRTDown data.
15
- */
16
- export declare class MRTDownWriter {
17
- private readonly store;
18
- readonly issues: IssueWriter;
19
- readonly stations: StandardWriter<Station>;
20
- readonly lines: StandardWriter<Line>;
21
- readonly operators: StandardWriter<Operator>;
22
- readonly services: StandardWriter<Service>;
23
- readonly landmarks: StandardWriter<Landmark>;
24
- readonly towns: StandardWriter<Town>;
25
- constructor(params: MRTDownWriterParams);
26
- }
27
- export {};
@@ -1,27 +0,0 @@
1
- import { DIR_LANDMARK, DIR_LINE, DIR_OPERATOR, DIR_SERVICE, DIR_STATION, DIR_TOWN, } from '../constants.js';
2
- import { StandardWriter } from './common/StandardWriter.js';
3
- import { IssueWriter } from './issue/IssueWriter.js';
4
- /**
5
- * A writer for the MRTDown data.
6
- */
7
- export class MRTDownWriter {
8
- store;
9
- issues;
10
- stations;
11
- lines;
12
- operators;
13
- services;
14
- landmarks;
15
- towns;
16
- constructor(params) {
17
- this.store = params.store;
18
- this.issues = new IssueWriter(this.store);
19
- this.stations = new StandardWriter(this.store, DIR_STATION);
20
- this.lines = new StandardWriter(this.store, DIR_LINE);
21
- this.operators = new StandardWriter(this.store, DIR_OPERATOR);
22
- this.services = new StandardWriter(this.store, DIR_SERVICE);
23
- this.landmarks = new StandardWriter(this.store, DIR_LANDMARK);
24
- this.towns = new StandardWriter(this.store, DIR_TOWN);
25
- }
26
- }
27
- //# sourceMappingURL=MRTDownWriter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MRTDownWriter.js","sourceRoot":"/","sources":["write/MRTDownWriter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,WAAW,EACX,QAAQ,GACT,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAMrD;;GAEG;AACH,MAAM,OAAO,aAAa;IACP,KAAK,CAAc;IAC3B,MAAM,CAAc;IACpB,QAAQ,CAA0B;IAClC,KAAK,CAAuB;IAC5B,SAAS,CAA2B;IACpC,QAAQ,CAA0B;IAClC,SAAS,CAA2B;IACpC,KAAK,CAAuB;IAErC,YAAY,MAA2B;QACrC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAC5D,IAAI,CAAC,KAAK,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QAC9D,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAC5D,IAAI,CAAC,SAAS,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QAC9D,IAAI,CAAC,KAAK,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACxD,CAAC;CACF","sourcesContent":["import {\n DIR_LANDMARK,\n DIR_LINE,\n DIR_OPERATOR,\n DIR_SERVICE,\n DIR_STATION,\n DIR_TOWN,\n} from '../constants.js';\nimport type { Landmark } from '../schema/Landmark.js';\nimport type { Line } from '../schema/Line.js';\nimport type { Operator } from '../schema/Operator.js';\nimport type { Service } from '../schema/Service.js';\nimport type { Station } from '../schema/Station.js';\nimport type { Town } from '../schema/Town.js';\nimport { StandardWriter } from './common/StandardWriter.js';\nimport type { IWriteStore } from './common/store.js';\nimport { IssueWriter } from './issue/IssueWriter.js';\n\ntype MRTDownWriterParams = {\n store: IWriteStore;\n};\n\n/**\n * A writer for the MRTDown data.\n */\nexport class MRTDownWriter {\n private readonly store: IWriteStore;\n readonly issues: IssueWriter;\n readonly stations: StandardWriter<Station>;\n readonly lines: StandardWriter<Line>;\n readonly operators: StandardWriter<Operator>;\n readonly services: StandardWriter<Service>;\n readonly landmarks: StandardWriter<Landmark>;\n readonly towns: StandardWriter<Town>;\n\n constructor(params: MRTDownWriterParams) {\n this.store = params.store;\n this.issues = new IssueWriter(this.store);\n this.stations = new StandardWriter(this.store, DIR_STATION);\n this.lines = new StandardWriter(this.store, DIR_LINE);\n this.operators = new StandardWriter(this.store, DIR_OPERATOR);\n this.services = new StandardWriter(this.store, DIR_SERVICE);\n this.landmarks = new StandardWriter(this.store, DIR_LANDMARK);\n this.towns = new StandardWriter(this.store, DIR_TOWN);\n }\n}\n"]}
@@ -1,13 +0,0 @@
1
- import type { IWriteStore } from './store.js';
2
- /**
3
- * A write store that writes to the file system.
4
- */
5
- export declare class FileWriteStore implements IWriteStore {
6
- private readonly rootDir;
7
- constructor(rootDir: string);
8
- writeText(path: string, text: string): void;
9
- writeJson(path: string, json: unknown): void;
10
- appendText(path: string, text: string): void;
11
- ensureDir(path: string): void;
12
- delete(path: string): void;
13
- }
@@ -1,31 +0,0 @@
1
- import { appendFileSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- /**
4
- * A write store that writes to the file system.
5
- */
6
- export class FileWriteStore {
7
- rootDir;
8
- constructor(rootDir) {
9
- this.rootDir = rootDir;
10
- }
11
- writeText(path, text) {
12
- const fullPath = join(this.rootDir, path);
13
- writeFileSync(fullPath, text);
14
- }
15
- writeJson(path, json) {
16
- this.writeText(path, JSON.stringify(json, null, 2));
17
- }
18
- appendText(path, text) {
19
- const fullPath = join(this.rootDir, path);
20
- appendFileSync(fullPath, text);
21
- }
22
- ensureDir(path) {
23
- const fullPath = join(this.rootDir, path);
24
- mkdirSync(fullPath, { recursive: true });
25
- }
26
- delete(path) {
27
- const fullPath = join(this.rootDir, path);
28
- rmSync(fullPath);
29
- }
30
- }
31
- //# sourceMappingURL=FileWriteStore.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FileWriteStore.js","sourceRoot":"/","sources":["write/common/FileWriteStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC;;GAEG;AACH,MAAM,OAAO,cAAc;IACI;IAA7B,YAA6B,OAAe;QAAf,YAAO,GAAP,OAAO,CAAQ;IAAG,CAAC;IAEhD,SAAS,CAAC,IAAY,EAAE,IAAY;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1C,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,SAAS,CAAC,IAAY,EAAE,IAAa;QACnC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,UAAU,CAAC,IAAY,EAAE,IAAY;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1C,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1C,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnB,CAAC;CACF","sourcesContent":["import { appendFileSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { IWriteStore } from './store.js';\n\n/**\n * A write store that writes to the file system.\n */\nexport class FileWriteStore implements IWriteStore {\n constructor(private readonly rootDir: string) {}\n\n writeText(path: string, text: string): void {\n const fullPath = join(this.rootDir, path);\n writeFileSync(fullPath, text);\n }\n\n writeJson(path: string, json: unknown): void {\n this.writeText(path, JSON.stringify(json, null, 2));\n }\n\n appendText(path: string, text: string): void {\n const fullPath = join(this.rootDir, path);\n appendFileSync(fullPath, text);\n }\n\n ensureDir(path: string): void {\n const fullPath = join(this.rootDir, path);\n mkdirSync(fullPath, { recursive: true });\n }\n\n delete(path: string): void {\n const fullPath = join(this.rootDir, path);\n rmSync(fullPath);\n }\n}\n"]}
@@ -1,14 +0,0 @@
1
- import type { IWriteStore } from './store.js';
2
- type Item = {
3
- id: string;
4
- };
5
- /**
6
- * A standard writer for items represented by single JSON files that are stored in a directory.
7
- */
8
- export declare class StandardWriter<T extends Item> {
9
- private readonly store;
10
- private readonly dirPath;
11
- constructor(store: IWriteStore, dirPath: string);
12
- create(item: T): void;
13
- }
14
- export {};
@@ -1,17 +0,0 @@
1
- import { join } from 'node:path';
2
- /**
3
- * A standard writer for items represented by single JSON files that are stored in a directory.
4
- */
5
- export class StandardWriter {
6
- store;
7
- dirPath;
8
- constructor(store, dirPath) {
9
- this.store = store;
10
- this.dirPath = dirPath;
11
- }
12
- create(item) {
13
- this.store.ensureDir(this.dirPath);
14
- this.store.writeJson(join(this.dirPath, `${item.id}.json`), item);
15
- }
16
- }
17
- //# sourceMappingURL=StandardWriter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"StandardWriter.js","sourceRoot":"/","sources":["write/common/StandardWriter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAOjC;;GAEG;AACH,MAAM,OAAO,cAAc;IAEN;IACA;IAFnB,YACmB,KAAkB,EAClB,OAAe;QADf,UAAK,GAAL,KAAK,CAAa;QAClB,YAAO,GAAP,OAAO,CAAQ;IAC/B,CAAC;IAEJ,MAAM,CAAC,IAAO;QACZ,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC;CACF","sourcesContent":["import { join } from 'node:path';\nimport type { IWriteStore } from './store.js';\n\ntype Item = {\n id: string;\n};\n\n/**\n * A standard writer for items represented by single JSON files that are stored in a directory.\n */\nexport class StandardWriter<T extends Item> {\n constructor(\n private readonly store: IWriteStore,\n private readonly dirPath: string,\n ) {}\n\n create(item: T): void {\n this.store.ensureDir(this.dirPath);\n this.store.writeJson(join(this.dirPath, `${item.id}.json`), item);\n }\n}\n"]}
@@ -1,32 +0,0 @@
1
- export interface IWriteStore {
2
- /**
3
- * Write a text file.
4
- * @param path
5
- * @param text
6
- */
7
- writeText(path: string, text: string): void;
8
- /**
9
- * Write a JSON file.
10
- * @param path
11
- * @param json
12
- */
13
- writeJson(path: string, json: unknown): void;
14
- /**
15
- * Append text to a file.
16
- * @param path
17
- * @param text
18
- */
19
- appendText(path: string, text: string): void;
20
- /**
21
- * Ensure a directory exists.
22
- * @param path
23
- * @returns
24
- */
25
- ensureDir(path: string): void;
26
- /**
27
- * Delete a file or directory.
28
- * @param path
29
- * @returns
30
- */
31
- delete?(path: string): void;
32
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=store.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"store.js","sourceRoot":"/","sources":["write/common/store.ts"],"names":[],"mappings":"","sourcesContent":["export interface IWriteStore {\n /**\n * Write a text file.\n * @param path\n * @param text\n */\n writeText(path: string, text: string): void;\n /**\n * Write a JSON file.\n * @param path\n * @param json\n */\n writeJson(path: string, json: unknown): void;\n /**\n * Append text to a file.\n * @param path\n * @param text\n */\n appendText(path: string, text: string): void;\n /**\n * Ensure a directory exists.\n * @param path\n * @returns\n */\n ensureDir(path: string): void;\n /**\n * Delete a file or directory.\n * @param path\n * @returns\n */\n delete?(path: string): void;\n}\n"]}