@jrpool/kilotest 46.1.0 → 47.0.1

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 (147) hide show
  1. package/.claude/settings.local.json +13 -1
  2. package/.devin/config.local.json +8 -1
  3. package/.github/workflows/ci.yml +0 -3
  4. package/.github/workflows/periodic-smoke-tests.yml +30 -0
  5. package/.github/workflows/publish-mcp.yml +4 -4
  6. package/{alerts.test.js → alerts.test.ts} +17 -29
  7. package/{alerts.js → alerts.ts} +10 -13
  8. package/api/{getReport.test.js → getReport.test.ts} +9 -10
  9. package/api/{getReport.js → getReport.ts} +23 -24
  10. package/api/{listDiagnoses.test.js → listDiagnoses.test.ts} +26 -27
  11. package/api/{listDiagnoses.js → listDiagnoses.ts} +46 -70
  12. package/api/{listIssues.test.js → listIssues.test.ts} +21 -14
  13. package/api/{listIssues.js → listIssues.ts} +75 -74
  14. package/api/{listReports.test.js → listReports.test.ts} +17 -16
  15. package/api/listReports.ts +87 -0
  16. package/api/{listViolators.test.js → listViolators.test.ts} +19 -20
  17. package/api/{listViolators.js → listViolators.ts} +45 -70
  18. package/api/requestFeature.test.ts +54 -0
  19. package/api/{requestFeature.js → requestFeature.ts} +18 -15
  20. package/api/{requestRetest.test.js → requestRetest.test.ts} +33 -28
  21. package/api/{requestRetest.js → requestRetest.ts} +32 -25
  22. package/api/{requestTest.test.js → requestTest.test.ts} +35 -30
  23. package/api/{requestTest.js → requestTest.ts} +35 -28
  24. package/api/{routes.test.js → routes.test.ts} +5 -5
  25. package/api/{routes.js → routes.ts} +6 -6
  26. package/api/{schemas.js → schemas.ts} +69 -50
  27. package/api/{util.test.js → util.test.ts} +31 -11
  28. package/api/{util.js → util.ts} +75 -46
  29. package/api/version.ts +8 -0
  30. package/{apiIntegration.test.js → apiIntegration.test.ts} +13 -14
  31. package/balances.ts +87 -0
  32. package/{checkinfo.js → checkinfo.ts} +24 -20
  33. package/docs/AI-TOOLS.md +4 -4
  34. package/docs/BACKLOG.md +356 -0
  35. package/docs/SERVICE.md +144 -17
  36. package/docs/decisions/002-coverage-tool.md +40 -0
  37. package/docs/decisions/003-adr-threshold.md +34 -0
  38. package/docs/decisions/004-docs-directory.md +23 -0
  39. package/docs/decisions/005-observability.md +28 -0
  40. package/docs/decisions/006-git-workflow.md +28 -0
  41. package/docs/decisions/007-internal-testing.md +34 -0
  42. package/docs/decisions/008-dependencies.md +28 -0
  43. package/docs/decisions/009-qai-integration.md +40 -0
  44. package/docs/decisions/QAI-HISTORICAL-CONTEXT.md +42 -0
  45. package/eslint.config.mjs +27 -0
  46. package/index.html +3 -3
  47. package/{index.test.js → index.test.ts} +462 -137
  48. package/{index.js → index.ts} +388 -283
  49. package/{indexBalances.test.js → indexBalances.test.ts} +21 -17
  50. package/{indexServe.test.js → indexServe.test.ts} +9 -9
  51. package/linkValidation.test.ts +190 -0
  52. package/{mcp.test.js → mcp.test.ts} +53 -26
  53. package/{mcp.js → mcp.ts} +29 -20
  54. package/memory/MEMORY.md +7 -0
  55. package/memory/user_maintainer_context.md +24 -0
  56. package/openapi.yaml +115 -68
  57. package/package.json +35 -15
  58. package/pm2.config.cjs +29 -0
  59. package/{routes.test.js → routes.test.ts} +8 -7
  60. package/{routing.test.js → routing.test.ts} +11 -12
  61. package/scripts/{generate-openapi.js → generate-openapi.ts} +13 -13
  62. package/serve.ts +15 -0
  63. package/smokeTest.ts +234 -0
  64. package/test/dbFixture.ts +21 -0
  65. package/test/fixtures/{buildFixtures.js → buildFixtures.ts} +14 -13
  66. package/test/{setup.cjs → setup.ts} +2 -2
  67. package/tsconfig.json +16 -0
  68. package/{util.test.js → util.test.ts} +350 -257
  69. package/util.ts +921 -0
  70. package/web/ai0BalanceForm/{ai0BalanceForm.test.js → ai0BalanceForm.test.ts} +15 -15
  71. package/web/ai0BalanceForm/{index.js → index.ts} +10 -18
  72. package/web/enqueue/index.ts +56 -0
  73. package/web/enqueueForm/index.html +9 -9
  74. package/web/enqueueForm/index.ts +43 -0
  75. package/web/expungeReportsForm/{expungeReportsForm.test.js → expungeReportsForm.test.ts} +18 -20
  76. package/web/expungeReportsForm/index.ts +18 -0
  77. package/web/hideReportForm/{hideReportForm.test.js → hideReportForm.test.ts} +14 -14
  78. package/web/hideReportForm/{index.js → index.ts} +17 -21
  79. package/web/listDiagnoses/{index.js → index.ts} +48 -58
  80. package/web/listDiagnoses/{listDiagnoses.test.js → listDiagnoses.test.ts} +39 -34
  81. package/web/listIssues/{index.js → index.ts} +67 -92
  82. package/web/listIssues/{listIssues.test.js → listIssues.test.ts} +45 -51
  83. package/web/listReports/index.html +3 -3
  84. package/web/listReports/{index.js → index.ts} +48 -53
  85. package/web/listReports/{listReports.test.js → listReports.test.ts} +41 -43
  86. package/web/listRules/{index.js → index.ts} +18 -23
  87. package/web/listRules/{listRules.test.js → listRules.test.ts} +26 -19
  88. package/web/listTopIssues/{index.js → index.ts} +36 -47
  89. package/web/listTopIssues/{listTopIssues.test.js → listTopIssues.test.ts} +26 -17
  90. package/web/listViolators/{index.js → index.ts} +51 -71
  91. package/web/listViolators/{listViolators.test.js → listViolators.test.ts} +43 -36
  92. package/web/manage/index.ts +22 -0
  93. package/web/pruneReportsForm/index.ts +18 -0
  94. package/web/pruneReportsForm/{pruneReportsForm.test.js → pruneReportsForm.test.ts} +11 -11
  95. package/web/reannotate/index.ts +70 -0
  96. package/web/reannotate/{reannotate.test.js → reannotate.test.ts} +19 -22
  97. package/web/reannotateForm/{index.js → index.ts} +41 -50
  98. package/web/reannotateForm/{reannotateForm.test.js → reannotateForm.test.ts} +13 -16
  99. package/web/renewWCAG/{index.js → index.ts} +9 -9
  100. package/web/renewWCAG/{renewWCAG.test.js → renewWCAG.test.ts} +17 -20
  101. package/web/renewWCAGForm/index.ts +22 -0
  102. package/web/{expungeReportsForm/index.js → reportDeletion.ts} +56 -38
  103. package/web/requestRetest/index.html +7 -7
  104. package/web/requestRetest/index.ts +31 -0
  105. package/web/requestRetest/requestRetest.test.ts +116 -0
  106. package/web/requestRetestForm/{index.js → index.ts} +10 -16
  107. package/web/requestRetestForm/{requestRetestForm.test.js → requestRetestForm.test.ts} +11 -12
  108. package/web/requestTest/index.html +7 -7
  109. package/web/requestTest/{index.js → index.ts} +5 -5
  110. package/web/requestTest/{requestTest.test.js → requestTest.test.ts} +21 -21
  111. package/web/requestTestForm/index.html +4 -4
  112. package/web/requestTestForm/index.ts +21 -0
  113. package/web/requestTestForm/{requestTestForm.test.js → requestTestForm.test.ts} +9 -9
  114. package/web/rewindReportsForm/index.ts +18 -0
  115. package/web/rewindReportsForm/{rewindReportsForm.test.js → rewindReportsForm.test.ts} +11 -11
  116. package/web/tutorialAI/index.html +184 -0
  117. package/web/tutorialAI/index.ts +80 -0
  118. package/web/tutorialAI/tutorialAI.test.ts +192 -0
  119. package/web/{tutorial → tutorialWeb}/index.html +9 -8
  120. package/web/tutorialWeb/index.ts +78 -0
  121. package/web/tutorialWeb/tutorialWeb.test.ts +195 -0
  122. package/web/unhideReportForm/{index.js → index.ts} +17 -21
  123. package/web/unhideReportForm/{unhideReportForm.test.js → unhideReportForm.test.ts} +16 -16
  124. package/aceconfig.js +0 -28
  125. package/api/listReports.js +0 -87
  126. package/api/requestFeature.test.js +0 -58
  127. package/api/version.js +0 -8
  128. package/indexFallback.test.js +0 -33
  129. package/indexWorkers.test.js +0 -79
  130. package/jsconfig.json +0 -8
  131. package/pm2.config.js +0 -18
  132. package/smokeTest.js +0 -126
  133. package/util.js +0 -733
  134. package/web/enqueue/index.js +0 -67
  135. package/web/enqueueForm/index.js +0 -49
  136. package/web/manage/index.js +0 -22
  137. package/web/pruneReportsForm/index.js +0 -123
  138. package/web/reannotate/index.js +0 -58
  139. package/web/renewWCAGForm/index.js +0 -22
  140. package/web/requestRetest/index.js +0 -31
  141. package/web/requestRetest/requestRetest.test.js +0 -119
  142. package/web/requestTestForm/index.js +0 -21
  143. package/web/rewindReportsForm/index.js +0 -121
  144. package/web/tutorial/index.js +0 -63
  145. package/web/tutorial/tutorial.test.js +0 -97
  146. /package/test/fixtures/db/jobs/{recs.json → testRequests.json} +0 -0
  147. /package/web/{tutorial → tutorialWeb}/images/newsletter-form.png +0 -0
package/openapi.yaml CHANGED
@@ -69,7 +69,9 @@ paths:
69
69
  completion date and time:
70
70
  type: string
71
71
  days since the report was completed:
72
- type: number
72
+ type:
73
+ - number
74
+ - 'null'
73
75
  tested web page:
74
76
  type: object
75
77
  properties:
@@ -372,50 +374,54 @@ paths:
372
374
  additionalProperties: false
373
375
  - type: 'null'
374
376
  basics about all issues reported in the report:
375
- type: array
376
- items:
377
- type: object
378
- properties:
379
- identifier:
380
- type: string
381
- summary:
382
- type: string
383
- impact on a user:
384
- type: string
385
- priority:
386
- type: string
387
- enum:
388
- - lowest
389
- - low
390
- - high
391
- - highest
392
- rule engines with any violations belonging to the issue:
393
- type: array
394
- items:
395
- type: string
396
- how to get details about the issue:
377
+ anyOf:
378
+ - type: array
379
+ items:
397
380
  type: object
398
381
  properties:
399
- method:
382
+ identifier:
400
383
  type: string
401
- const: GET
402
- URL:
384
+ summary:
385
+ type: string
386
+ impact on a user:
387
+ type: string
388
+ priority:
389
+ type: string
390
+ enum:
391
+ - lowest
392
+ - low
393
+ - high
394
+ - highest
395
+ rule engines with any violations belonging to the issue:
396
+ type: array
397
+ items:
398
+ type:
399
+ - string
400
+ - 'null'
401
+ how to get details about the issue:
402
+ type: object
403
+ properties:
404
+ method:
405
+ type: string
406
+ const: GET
407
+ URL:
408
+ type: string
409
+ required:
410
+ - method
411
+ - URL
412
+ additionalProperties: false
413
+ web users can get details about the issue at:
403
414
  type: string
404
415
  required:
405
- - method
406
- - URL
416
+ - identifier
417
+ - summary
418
+ - impact on a user
419
+ - priority
420
+ - rule engines with any violations belonging to the issue
421
+ - how to get details about the issue
422
+ - web users can get details about the issue at
407
423
  additionalProperties: false
408
- web users can get details about the issue at:
409
- type: string
410
- required:
411
- - identifier
412
- - summary
413
- - impact on a user
414
- - priority
415
- - rule engines with any violations belonging to the issue
416
- - how to get details about the issue
417
- - web users can get details about the issue at
418
- additionalProperties: false
424
+ - type: 'null'
419
425
  required:
420
426
  - basics about the report
421
427
  - details about the report
@@ -514,14 +520,17 @@ paths:
514
520
  - rule engines reporting violations belonging to the issue
515
521
  additionalProperties: false
516
522
  - type: 'null'
517
- basics about all elements reported as exhibiting the issue:
523
+ basics about all elements exhibiting the issue:
518
524
  anyOf:
519
525
  - type: array
520
526
  items:
521
527
  type: object
522
528
  properties:
523
529
  identifier:
524
- type: string
530
+ description: Catalog index of the element in the report; a string or number, copied verbatim.
531
+ type:
532
+ - string
533
+ - number
525
534
  tag name:
526
535
  description: Copied from the report catalog entry; type not guaranteed.
527
536
  inner text:
@@ -555,7 +564,7 @@ paths:
555
564
  - basics about the report
556
565
  - basics about the issue
557
566
  - details about the issue
558
- - basics about all elements reported as exhibiting the issue
567
+ - basics about all elements exhibiting the issue
559
568
  additionalProperties: false
560
569
  required:
561
570
  - tool collection
@@ -683,31 +692,33 @@ paths:
683
692
  - type: 'null'
684
693
  diagnoses of how the element exhibited the issue:
685
694
  anyOf:
686
- - type: array
687
- items:
688
- type: object
689
- properties:
690
- identifier of the violated rule:
691
- description: Copied from the report instance (ruleID); type not guaranteed.
692
- description of the violation:
693
- description: Copied from the report instance (what); type not guaranteed.
694
- severity of the violation on a 0-to-3 scale:
695
- description: Copied from the report instance (ordinalSeverity); type not guaranteed.
696
- count of violations of the rule by the element:
697
- type: number
698
- required:
699
- - identifier of the violated rule
700
- - description of the violation
701
- - severity of the violation on a 0-to-3 scale
702
- - count of violations of the rule by the element
703
- additionalProperties: false
704
- - type: object
705
- properties:
706
- error:
707
- type: string
708
- required:
709
- - error
710
- additionalProperties: false
695
+ - anyOf:
696
+ - type: array
697
+ items:
698
+ type: object
699
+ properties:
700
+ identifier of the violated rule:
701
+ description: Copied from the report instance (ruleID); type not guaranteed.
702
+ description of the violation:
703
+ description: Copied from the report instance (what); type not guaranteed.
704
+ severity of the violation on a 0-to-3 scale:
705
+ description: Copied from the report instance (ordinalSeverity); type not guaranteed.
706
+ count of violations of the rule by the element:
707
+ type: number
708
+ required:
709
+ - identifier of the violated rule
710
+ - description of the violation
711
+ - severity of the violation on a 0-to-3 scale
712
+ - count of violations of the rule by the element
713
+ additionalProperties: false
714
+ - type: object
715
+ properties:
716
+ error:
717
+ type: string
718
+ required:
719
+ - error
720
+ additionalProperties: false
721
+ - type: 'null'
711
722
  required:
712
723
  - basics about the report
713
724
  - basics about the issue
@@ -910,8 +921,25 @@ paths:
910
921
  - page to be tested
911
922
  - reason why the page should be tested
912
923
  additionalProperties: false
924
+ disposition of your request:
925
+ anyOf:
926
+ - type: object
927
+ properties:
928
+ what happens next:
929
+ type: string
930
+ how you can check for completion:
931
+ type: string
932
+ how a web user can check for completion:
933
+ type: string
934
+ required:
935
+ - what happens next
936
+ - how you can check for completion
937
+ - how a web user can check for completion
938
+ additionalProperties: false
939
+ - type: 'null'
913
940
  required:
914
941
  - details about your request
942
+ - disposition of your request
915
943
  additionalProperties: false
916
944
  required:
917
945
  - tool collection
@@ -1031,8 +1059,25 @@ paths:
1031
1059
  - page to be retested
1032
1060
  - reason why the page should be retested
1033
1061
  additionalProperties: false
1062
+ disposition of your request:
1063
+ anyOf:
1064
+ - type: object
1065
+ properties:
1066
+ what happens next:
1067
+ type: string
1068
+ how you can check for completion:
1069
+ type: string
1070
+ how a web user can check for completion:
1071
+ type: string
1072
+ required:
1073
+ - what happens next
1074
+ - how you can check for completion
1075
+ - how a web user can check for completion
1076
+ additionalProperties: false
1077
+ - type: 'null'
1034
1078
  required:
1035
1079
  - details about your request
1080
+ - disposition of your request
1036
1081
  additionalProperties: false
1037
1082
  required:
1038
1083
  - tool collection
@@ -1263,7 +1308,9 @@ components:
1263
1308
  completion date and time:
1264
1309
  type: string
1265
1310
  days since the report was completed:
1266
- type: number
1311
+ type:
1312
+ - number
1313
+ - 'null'
1267
1314
  tested web page:
1268
1315
  type: object
1269
1316
  properties:
package/package.json CHANGED
@@ -1,18 +1,20 @@
1
1
  {
2
2
  "name": "@jrpool/kilotest",
3
- "version": "46.1.0",
3
+ "version": "47.0.1",
4
4
  "description": "Ensemble testing for front-end web quality",
5
- "main": "index.js",
5
+ "type": "module",
6
+ "main": "index.ts",
6
7
  "engines": {
7
8
  "node": ">=24.16.0"
8
9
  },
9
10
  "scripts": {
10
- "start": "node index",
11
+ "start": "node index.ts",
12
+ "typecheck": "tsc --noEmit",
11
13
  "lint": "npx eslint && out=$(npx markdownlint-cli2 2>&1); code=$?; if [ $code -ne 0 ]; then echo \"$out\"; exit $code; fi",
12
- "test": "c8 node --require ./test/setup.cjs --test --test-concurrency=1 --test-timeout=100 --test-randomize",
13
- "test:smoke": "node smokeTest",
14
- "checkinfo": "node checkinfo",
15
- "generate:openapi": "node scripts/generate-openapi"
14
+ "test": "c8 node --require ./test/setup.ts --experimental-test-module-mocks --test --test-concurrency=1 --test-randomize '**/*.test.ts'",
15
+ "test:smoke": "node smokeTest.ts",
16
+ "checkinfo": "node checkinfo.ts",
17
+ "generate:openapi": "node scripts/generate-openapi.ts"
16
18
  },
17
19
  "repository": {
18
20
  "type": "git",
@@ -45,12 +47,16 @@
45
47
  "@eslint/json": "*",
46
48
  "@eslint/markdown": "*",
47
49
  "@redocly/cli": "*",
50
+ "@types/node": "*",
48
51
  "c8": "*",
49
52
  "eslint": "*",
50
53
  "globals": "*",
51
54
  "js-yaml": "*",
52
- "markdownlint-cli2": "*",
55
+ "markdownlint-cli2": "^0.23.2",
53
56
  "node-html-parser": "*",
57
+ "testaro": "*",
58
+ "typescript": "*",
59
+ "typescript-eslint": "*",
54
60
  "zod-openapi": "*"
55
61
  },
56
62
  "allowScripts": {
@@ -58,23 +64,34 @@
58
64
  },
59
65
  "c8": {
60
66
  "all": true,
67
+ "extension": [
68
+ ".js",
69
+ ".cjs",
70
+ ".mjs",
71
+ ".ts",
72
+ ".tsx",
73
+ ".jsx",
74
+ ".cts",
75
+ ".mts"
76
+ ],
61
77
  "reporter": [
62
78
  "text",
63
79
  "html"
64
80
  ],
65
81
  "include": [
66
- "index.js",
67
- "mcp.js",
68
- "alerts.js",
69
- "util.js",
70
- "api/**/*.js",
71
- "web/**/*.js"
82
+ "index.ts",
83
+ "mcp.ts",
84
+ "alerts.ts",
85
+ "balances.ts",
86
+ "util.ts",
87
+ "api/**/*.{js,ts,cts}",
88
+ "web/**/*.{js,ts,cts}"
72
89
  ],
73
90
  "exclude": [
74
91
  "coverage/**",
75
92
  "test{,s}/**",
76
93
  "test{,-*}.{js,cjs,mjs}",
77
- "**/*{.,-}test.{js,cjs,mjs}",
94
+ "**/*{.,-}test.{js,cjs,mjs,ts}",
78
95
  "**/__tests__/**",
79
96
  "scripts/**"
80
97
  ],
@@ -83,5 +100,8 @@
83
100
  "statements": 100,
84
101
  "functions": 100,
85
102
  "branches": 100
103
+ },
104
+ "overrides": {
105
+ "smol-toml": "^1.8.0"
86
106
  }
87
107
  }
package/pm2.config.cjs ADDED
@@ -0,0 +1,29 @@
1
+ /*
2
+ pm2.config.cjs
3
+ PM2 process configuration for Kilotest. The .cjs extension is required: PM2
4
+ loads configuration files with require() (Common.parseConfig in pm2's
5
+ lib/Common.js), which cannot load ES modules. A .js or .mjs name would fail
6
+ with ERR_REQUIRE_ESM in this type:module package.
7
+ */
8
+ module.exports = {
9
+ apps: [
10
+ {
11
+ name: 'kilotest',
12
+ // index.ts cannot be the PM2 script: its autostart guard (import.meta.main) is
13
+ // false inside PM2's process container, so the server would never start.
14
+ script: 'serve.ts',
15
+ // PM2 maps the .ts extension to the bun interpreter, so node must be specified explicitly.
16
+ interpreter: 'node',
17
+ instances: 1,
18
+ autorestart: true,
19
+ watch: false,
20
+ max_memory_restart: '500M',
21
+ time: true,
22
+ env: {
23
+ NODE_ENV: 'production',
24
+ BASE_PATH: '/',
25
+ DEMO_SSE_DELAY_MS: '100'
26
+ }
27
+ }
28
+ ]
29
+ };
@@ -1,13 +1,13 @@
1
1
  /*
2
- routes.test.js
2
+ routes.test.ts
3
3
  Tests for the centralized routes table exported from index.js.
4
4
  */
5
5
 
6
6
  // IMPORTS
7
7
 
8
- const {test} = require('node:test');
9
- const assert = require('node:assert/strict');
10
- const {routes} = require('./index');
8
+ import {test} from 'node:test';
9
+ import assert from 'node:assert/strict';
10
+ import {routes} from './index.ts';
11
11
 
12
12
  // TESTS
13
13
 
@@ -43,12 +43,12 @@ test('routes POST includes all known POST paths', () => {
43
43
  const required = [
44
44
  '/mcp',
45
45
  '/requestTest.html',
46
- '/recAction.html',
46
+ '/requestAction.html',
47
47
  '/reannotate.html',
48
48
  '/renewWCAG.html',
49
49
  '/worker/job',
50
50
  '/worker/report',
51
- '/tutorialComment.html'
51
+ '/tutorialWebComment.html'
52
52
  ];
53
53
  for (const path of required) {
54
54
  assert.ok(routes.POST.includes(path), `routes.POST missing ${path}`);
@@ -58,7 +58,8 @@ test('routes POST includes all known POST paths', () => {
58
58
  test('routes GET includes wildcard patterns for dynamic paths', () => {
59
59
  assert.ok(routes.GET.some(p => p.includes('fullReport.json')));
60
60
  assert.ok(routes.GET.some(p => p.includes('/api/')));
61
- assert.ok(routes.GET.some(p => p.includes('tutorial/images')));
61
+ assert.ok(routes.GET.some(p => p.includes('tutorialWeb/images')));
62
+ assert.ok(routes.GET.some(p => p.includes('tutorialAI/images')));
62
63
  assert.ok(routes.GET.some(p => p.includes('favicon')));
63
64
  assert.ok(routes.GET.some(p => p.includes('.html')));
64
65
  });
@@ -1,15 +1,14 @@
1
1
  /*
2
- routing.test.js
2
+ routing.test.ts
3
3
  Integration tests for HTTP routing in index.js, verifying that POST-only API services reject GET requests.
4
4
  */
5
5
 
6
6
  // IMPORTS
7
7
 
8
- const {test, before, after} = require('node:test');
9
- const assert = require('node:assert/strict');
10
- const path = require('node:path');
11
- const http = require('node:http');
12
- const {requestHandler} = require('./index');
8
+ import {test, before, after} from 'node:test';
9
+ import assert from 'node:assert/strict';
10
+ import http from 'node:http';
11
+ import {requestHandler} from './index.ts';
13
12
 
14
13
  // CONSTANTS
15
14
 
@@ -18,12 +17,12 @@ const port = 3999;
18
17
  // SETUP AND TEARDOWN
19
18
 
20
19
  const savedDBDir = process.env.DB_DIR;
21
- let server;
20
+ let server: http.Server;
22
21
 
23
22
  before(async () => {
24
- process.env.DB_DIR = path.join(__dirname, 'test', 'fixtures', 'db');
23
+ process.env.DB_DIR = (await import('./test/dbFixture.ts')).fixtureDBDir;
25
24
  server = http.createServer(requestHandler);
26
- await new Promise(resolve => server.listen(port, () => resolve()));
25
+ await new Promise<void>(resolve => server.listen(port, () => resolve()));
27
26
  });
28
27
 
29
28
  after(async () => {
@@ -34,7 +33,7 @@ after(async () => {
34
33
  delete process.env.DB_DIR;
35
34
  }
36
35
  server.closeAllConnections?.();
37
- await new Promise(resolve => {
36
+ await new Promise<void>(resolve => {
38
37
  const timer = setTimeout(() => {
39
38
  server.closeAllConnections?.();
40
39
  resolve();
@@ -49,9 +48,9 @@ after(async () => {
49
48
  // HELPERS
50
49
 
51
50
  // Sends a GET request and returns the response body as a string.
52
- const get = requestPath => new Promise((resolve, reject) => {
51
+ const get = (requestPath: string): Promise<any> => new Promise((resolve, reject) => {
53
52
  http.request({method: 'GET', host: 'localhost', port, path: requestPath}, response => {
54
- const chunks = [];
53
+ const chunks: any[] = [];
55
54
  response.on('data', chunk => chunks.push(chunk));
56
55
  response.on('end', () => {
57
56
  resolve({statusCode: response.statusCode, body: chunks.join('')});
@@ -1,34 +1,34 @@
1
1
  /*
2
- generate-openapi.js
3
- Generates openapi.yaml from the Kilotest API route table (api/routes.js) and Zod schemas (api/schemas.js), keeping the OpenAPI document in sync with schemas.js’s single source of truth.
2
+ generate-openapi.ts
3
+ Generates openapi.yaml from the Kilotest API route table (api/routes.ts) and Zod schemas (api/schemas.ts), keeping the OpenAPI document in sync with schemas.ts’s single source of truth.
4
4
  */
5
5
 
6
6
  // IMPORTS
7
7
 
8
- const fs = require('fs');
9
- const path = require('path');
10
- const yaml = require('js-yaml');
11
- const {createDocument} = require('zod-openapi');
12
- const {license} = require('../package.json');
13
- const routes = require('../api/routes');
14
- const {version} = require('../api/version');
8
+ import fs from 'node:fs';
9
+ import path from 'node:path';
10
+ import * as yaml from 'js-yaml';
11
+ import {createDocument} from 'zod-openapi';
12
+ import pkg from '../package.json' with {type: 'json'};
13
+ import {routes} from '../api/routes.ts';
14
+ import {version} from '../api/version.ts';
15
15
 
16
16
  // CONSTANTS
17
17
 
18
- const outputPath = path.join(__dirname, '..', 'openapi.yaml');
18
+ const {license} = pkg;
19
+ const outputPath = path.join(import.meta.dirname, '..', 'openapi.yaml');
19
20
 
20
21
  // FUNCTIONS
21
22
 
22
23
  // Builds the paths object for createDocument from the route table.
23
24
  const buildPaths = () => {
24
- /** @type {import('zod-openapi').ZodOpenApiPathsObject} */
25
- const paths = {};
25
+ const paths: Record<string, any> = {};
26
26
  routes.forEach(route => {
27
27
  const {method, path: routePath, summary, pathParamsSchema, bodySchema, responseSchema} = route;
28
28
  if (!paths[routePath]) {
29
29
  paths[routePath] = {};
30
30
  }
31
- const operation = {
31
+ const operation: any = {
32
32
  operationId: route.operationId,
33
33
  summary,
34
34
  responses: {
package/serve.ts ADDED
@@ -0,0 +1,15 @@
1
+ /*
2
+ serve.ts
3
+ Entry point for the Kilotest service under PM2. index.ts starts the server only when
4
+ it is the program entry point (import.meta.main), which is false inside PM2's process
5
+ container, so PM2 loads this file, which starts the server unconditionally.
6
+ */
7
+
8
+ // IMPORTS
9
+
10
+ import {errorMessage} from './util.ts';
11
+ import {startServer} from './index.ts';
12
+
13
+ // EXECUTION
14
+
15
+ startServer().catch(error => console.log(errorMessage(error)));