@shipfox/annotations 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/.turbo/turbo-build.log +2 -0
  2. package/.turbo/turbo-type$colon$emit.log +1 -0
  3. package/.turbo/turbo-type.log +1 -0
  4. package/CHANGELOG.md +67 -0
  5. package/LICENSE +21 -0
  6. package/dist/config.d.ts +6 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +26 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/core/entities/annotation.d.ts +21 -0
  11. package/dist/core/entities/annotation.d.ts.map +1 -0
  12. package/dist/core/entities/annotation.js +3 -0
  13. package/dist/core/entities/annotation.js.map +1 -0
  14. package/dist/core/entities/index.d.ts +2 -0
  15. package/dist/core/entities/index.d.ts.map +1 -0
  16. package/dist/core/entities/index.js +3 -0
  17. package/dist/core/entities/index.js.map +1 -0
  18. package/dist/core/errors.d.ts +13 -0
  19. package/dist/core/errors.d.ts.map +1 -0
  20. package/dist/core/errors.js +20 -0
  21. package/dist/core/errors.js.map +1 -0
  22. package/dist/core/write-annotations.d.ts +25 -0
  23. package/dist/core/write-annotations.d.ts.map +1 -0
  24. package/dist/core/write-annotations.js +105 -0
  25. package/dist/core/write-annotations.js.map +1 -0
  26. package/dist/db/annotations.d.ts +63 -0
  27. package/dist/db/annotations.d.ts.map +1 -0
  28. package/dist/db/annotations.js +96 -0
  29. package/dist/db/annotations.js.map +1 -0
  30. package/dist/db/db.d.ts +304 -0
  31. package/dist/db/db.d.ts.map +1 -0
  32. package/dist/db/db.js +18 -0
  33. package/dist/db/db.js.map +1 -0
  34. package/dist/db/index.d.ts +4 -0
  35. package/dist/db/index.d.ts.map +1 -0
  36. package/dist/db/index.js +6 -0
  37. package/dist/db/index.js.map +1 -0
  38. package/dist/db/schema/annotations.d.ts +302 -0
  39. package/dist/db/schema/annotations.d.ts.map +1 -0
  40. package/dist/db/schema/annotations.js +67 -0
  41. package/dist/db/schema/annotations.js.map +1 -0
  42. package/dist/db/schema/common.d.ts +2 -0
  43. package/dist/db/schema/common.d.ts.map +1 -0
  44. package/dist/db/schema/common.js +4 -0
  45. package/dist/db/schema/common.js.map +1 -0
  46. package/dist/index.d.ts +5 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +15 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/presentation/dto/annotation.d.ts +4 -0
  51. package/dist/presentation/dto/annotation.d.ts.map +1 -0
  52. package/dist/presentation/dto/annotation.js +15 -0
  53. package/dist/presentation/dto/annotation.js.map +1 -0
  54. package/dist/presentation/dto/index.d.ts +2 -0
  55. package/dist/presentation/dto/index.d.ts.map +1 -0
  56. package/dist/presentation/dto/index.js +3 -0
  57. package/dist/presentation/dto/index.js.map +1 -0
  58. package/dist/presentation/routes/index.d.ts +3 -0
  59. package/dist/presentation/routes/index.d.ts.map +1 -0
  60. package/dist/presentation/routes/index.js +21 -0
  61. package/dist/presentation/routes/index.js.map +1 -0
  62. package/dist/presentation/routes/read-annotations.d.ts +2 -0
  63. package/dist/presentation/routes/read-annotations.d.ts.map +1 -0
  64. package/dist/presentation/routes/read-annotations.js +49 -0
  65. package/dist/presentation/routes/read-annotations.js.map +1 -0
  66. package/dist/presentation/routes/write-annotations.d.ts +2 -0
  67. package/dist/presentation/routes/write-annotations.d.ts.map +1 -0
  68. package/dist/presentation/routes/write-annotations.js +73 -0
  69. package/dist/presentation/routes/write-annotations.js.map +1 -0
  70. package/dist/tsconfig.test.tsbuildinfo +1 -0
  71. package/drizzle/0000_initial.sql +32 -0
  72. package/drizzle/meta/0000_snapshot.json +247 -0
  73. package/drizzle/meta/_journal.json +13 -0
  74. package/drizzle.config.ts +7 -0
  75. package/package.json +69 -0
  76. package/src/config.test.ts +45 -0
  77. package/src/config.ts +26 -0
  78. package/src/core/entities/annotation.ts +21 -0
  79. package/src/core/entities/index.ts +1 -0
  80. package/src/core/errors.ts +20 -0
  81. package/src/core/write-annotations.test.ts +261 -0
  82. package/src/core/write-annotations.ts +142 -0
  83. package/src/db/annotations.test.ts +261 -0
  84. package/src/db/annotations.ts +180 -0
  85. package/src/db/db.ts +19 -0
  86. package/src/db/index.ts +7 -0
  87. package/src/db/schema/annotations.test.ts +50 -0
  88. package/src/db/schema/annotations.ts +96 -0
  89. package/src/db/schema/common.ts +3 -0
  90. package/src/index.ts +17 -0
  91. package/src/presentation/dto/annotation.test.ts +42 -0
  92. package/src/presentation/dto/annotation.ts +16 -0
  93. package/src/presentation/dto/index.ts +1 -0
  94. package/src/presentation/routes/index.ts +17 -0
  95. package/src/presentation/routes/read-annotations.test.ts +279 -0
  96. package/src/presentation/routes/read-annotations.ts +50 -0
  97. package/src/presentation/routes/write-annotations.test.ts +188 -0
  98. package/src/presentation/routes/write-annotations.ts +76 -0
  99. package/test/env.ts +5 -0
  100. package/test/factories/annotation.ts +57 -0
  101. package/test/fixtures/lease-token.ts +43 -0
  102. package/test/globalSetup.ts +20 -0
  103. package/test/index.ts +2 -0
  104. package/test/setup.ts +17 -0
  105. package/tsconfig.build.json +9 -0
  106. package/tsconfig.build.tsbuildinfo +1 -0
  107. package/tsconfig.json +3 -0
  108. package/tsconfig.test.json +8 -0
  109. package/vitest.config.ts +13 -0
@@ -0,0 +1,32 @@
1
+ CREATE TYPE "public"."annotations_style" AS ENUM('default', 'info', 'success', 'warning', 'error');--> statement-breakpoint
2
+ CREATE TABLE "annotations_annotations" (
3
+ "id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
4
+ "workspace_id" uuid NOT NULL,
5
+ "project_id" uuid NOT NULL,
6
+ "workflow_run_id" uuid NOT NULL,
7
+ "workflow_run_attempt" integer NOT NULL,
8
+ "workflow_run_attempt_id" uuid NOT NULL,
9
+ "job_id" uuid NOT NULL,
10
+ "job_execution_id" uuid NOT NULL,
11
+ "origin_step_id" uuid NOT NULL,
12
+ "origin_step_attempt" integer NOT NULL,
13
+ "context" text NOT NULL,
14
+ "style" "annotations_style" DEFAULT 'default' NOT NULL,
15
+ "body" text NOT NULL,
16
+ "body_bytes" integer NOT NULL,
17
+ "sequence" integer NOT NULL,
18
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
19
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
20
+ CONSTRAINT "annotations_workflow_run_attempt_positive_ck" CHECK ("annotations_annotations"."workflow_run_attempt" > 0),
21
+ CONSTRAINT "annotations_origin_step_attempt_positive_ck" CHECK ("annotations_annotations"."origin_step_attempt" > 0),
22
+ CONSTRAINT "annotations_body_bytes_matches_body_ck" CHECK ("annotations_annotations"."body_bytes" = octet_length("annotations_annotations"."body")),
23
+ CONSTRAINT "annotations_sequence_positive_ck" CHECK ("annotations_annotations"."sequence" > 0),
24
+ CONSTRAINT "annotations_context_not_empty_ck" CHECK (length("annotations_annotations"."context") > 0),
25
+ CONSTRAINT "annotations_context_trimmed_ck" CHECK ("annotations_annotations"."context" = btrim("annotations_annotations"."context", concat(chr(9), chr(10), chr(11), chr(12), chr(13), chr(32), chr(160), chr(5760), chr(8192), chr(8193), chr(8194), chr(8195), chr(8196), chr(8197), chr(8198), chr(8199), chr(8200), chr(8201), chr(8202), chr(8232), chr(8233), chr(8239), chr(8287), chr(12288), chr(65279)))),
26
+ CONSTRAINT "annotations_context_max_length_ck" CHECK (length("annotations_annotations"."context") <= 255)
27
+ );
28
+ --> statement-breakpoint
29
+ CREATE UNIQUE INDEX "annotations_job_execution_context_unique" ON "annotations_annotations" USING btree ("job_execution_id","context");--> statement-breakpoint
30
+ CREATE INDEX "annotations_workflow_run_attempt_idx" ON "annotations_annotations" USING btree ("workflow_run_id","workflow_run_attempt");--> statement-breakpoint
31
+ CREATE INDEX "annotations_workflow_run_attempt_id_idx" ON "annotations_annotations" USING btree ("workflow_run_attempt_id");--> statement-breakpoint
32
+ CREATE INDEX "annotations_job_execution_id_idx" ON "annotations_annotations" USING btree ("job_execution_id");
@@ -0,0 +1,247 @@
1
+ {
2
+ "id": "b920fb4a-f313-42df-88bf-a2f929f35884",
3
+ "prevId": "00000000-0000-0000-0000-000000000000",
4
+ "version": "7",
5
+ "dialect": "postgresql",
6
+ "tables": {
7
+ "public.annotations_annotations": {
8
+ "name": "annotations_annotations",
9
+ "schema": "",
10
+ "columns": {
11
+ "id": {
12
+ "name": "id",
13
+ "type": "uuid",
14
+ "primaryKey": true,
15
+ "notNull": true,
16
+ "default": "uuidv7()"
17
+ },
18
+ "workspace_id": {
19
+ "name": "workspace_id",
20
+ "type": "uuid",
21
+ "primaryKey": false,
22
+ "notNull": true
23
+ },
24
+ "project_id": {
25
+ "name": "project_id",
26
+ "type": "uuid",
27
+ "primaryKey": false,
28
+ "notNull": true
29
+ },
30
+ "workflow_run_id": {
31
+ "name": "workflow_run_id",
32
+ "type": "uuid",
33
+ "primaryKey": false,
34
+ "notNull": true
35
+ },
36
+ "workflow_run_attempt": {
37
+ "name": "workflow_run_attempt",
38
+ "type": "integer",
39
+ "primaryKey": false,
40
+ "notNull": true
41
+ },
42
+ "workflow_run_attempt_id": {
43
+ "name": "workflow_run_attempt_id",
44
+ "type": "uuid",
45
+ "primaryKey": false,
46
+ "notNull": true
47
+ },
48
+ "job_id": {
49
+ "name": "job_id",
50
+ "type": "uuid",
51
+ "primaryKey": false,
52
+ "notNull": true
53
+ },
54
+ "job_execution_id": {
55
+ "name": "job_execution_id",
56
+ "type": "uuid",
57
+ "primaryKey": false,
58
+ "notNull": true
59
+ },
60
+ "origin_step_id": {
61
+ "name": "origin_step_id",
62
+ "type": "uuid",
63
+ "primaryKey": false,
64
+ "notNull": true
65
+ },
66
+ "origin_step_attempt": {
67
+ "name": "origin_step_attempt",
68
+ "type": "integer",
69
+ "primaryKey": false,
70
+ "notNull": true
71
+ },
72
+ "context": {
73
+ "name": "context",
74
+ "type": "text",
75
+ "primaryKey": false,
76
+ "notNull": true
77
+ },
78
+ "style": {
79
+ "name": "style",
80
+ "type": "annotations_style",
81
+ "typeSchema": "public",
82
+ "primaryKey": false,
83
+ "notNull": true,
84
+ "default": "'default'"
85
+ },
86
+ "body": {
87
+ "name": "body",
88
+ "type": "text",
89
+ "primaryKey": false,
90
+ "notNull": true
91
+ },
92
+ "body_bytes": {
93
+ "name": "body_bytes",
94
+ "type": "integer",
95
+ "primaryKey": false,
96
+ "notNull": true
97
+ },
98
+ "sequence": {
99
+ "name": "sequence",
100
+ "type": "integer",
101
+ "primaryKey": false,
102
+ "notNull": true
103
+ },
104
+ "created_at": {
105
+ "name": "created_at",
106
+ "type": "timestamp with time zone",
107
+ "primaryKey": false,
108
+ "notNull": true,
109
+ "default": "now()"
110
+ },
111
+ "updated_at": {
112
+ "name": "updated_at",
113
+ "type": "timestamp with time zone",
114
+ "primaryKey": false,
115
+ "notNull": true,
116
+ "default": "now()"
117
+ }
118
+ },
119
+ "indexes": {
120
+ "annotations_job_execution_context_unique": {
121
+ "name": "annotations_job_execution_context_unique",
122
+ "columns": [
123
+ {
124
+ "expression": "job_execution_id",
125
+ "isExpression": false,
126
+ "asc": true,
127
+ "nulls": "last"
128
+ },
129
+ {
130
+ "expression": "context",
131
+ "isExpression": false,
132
+ "asc": true,
133
+ "nulls": "last"
134
+ }
135
+ ],
136
+ "isUnique": true,
137
+ "concurrently": false,
138
+ "method": "btree",
139
+ "with": {}
140
+ },
141
+ "annotations_workflow_run_attempt_idx": {
142
+ "name": "annotations_workflow_run_attempt_idx",
143
+ "columns": [
144
+ {
145
+ "expression": "workflow_run_id",
146
+ "isExpression": false,
147
+ "asc": true,
148
+ "nulls": "last"
149
+ },
150
+ {
151
+ "expression": "workflow_run_attempt",
152
+ "isExpression": false,
153
+ "asc": true,
154
+ "nulls": "last"
155
+ }
156
+ ],
157
+ "isUnique": false,
158
+ "concurrently": false,
159
+ "method": "btree",
160
+ "with": {}
161
+ },
162
+ "annotations_workflow_run_attempt_id_idx": {
163
+ "name": "annotations_workflow_run_attempt_id_idx",
164
+ "columns": [
165
+ {
166
+ "expression": "workflow_run_attempt_id",
167
+ "isExpression": false,
168
+ "asc": true,
169
+ "nulls": "last"
170
+ }
171
+ ],
172
+ "isUnique": false,
173
+ "concurrently": false,
174
+ "method": "btree",
175
+ "with": {}
176
+ },
177
+ "annotations_job_execution_id_idx": {
178
+ "name": "annotations_job_execution_id_idx",
179
+ "columns": [
180
+ {
181
+ "expression": "job_execution_id",
182
+ "isExpression": false,
183
+ "asc": true,
184
+ "nulls": "last"
185
+ }
186
+ ],
187
+ "isUnique": false,
188
+ "concurrently": false,
189
+ "method": "btree",
190
+ "with": {}
191
+ }
192
+ },
193
+ "foreignKeys": {},
194
+ "compositePrimaryKeys": {},
195
+ "uniqueConstraints": {},
196
+ "policies": {},
197
+ "checkConstraints": {
198
+ "annotations_workflow_run_attempt_positive_ck": {
199
+ "name": "annotations_workflow_run_attempt_positive_ck",
200
+ "value": "\"annotations_annotations\".\"workflow_run_attempt\" > 0"
201
+ },
202
+ "annotations_origin_step_attempt_positive_ck": {
203
+ "name": "annotations_origin_step_attempt_positive_ck",
204
+ "value": "\"annotations_annotations\".\"origin_step_attempt\" > 0"
205
+ },
206
+ "annotations_body_bytes_matches_body_ck": {
207
+ "name": "annotations_body_bytes_matches_body_ck",
208
+ "value": "\"annotations_annotations\".\"body_bytes\" = octet_length(\"annotations_annotations\".\"body\")"
209
+ },
210
+ "annotations_sequence_positive_ck": {
211
+ "name": "annotations_sequence_positive_ck",
212
+ "value": "\"annotations_annotations\".\"sequence\" > 0"
213
+ },
214
+ "annotations_context_not_empty_ck": {
215
+ "name": "annotations_context_not_empty_ck",
216
+ "value": "length(\"annotations_annotations\".\"context\") > 0"
217
+ },
218
+ "annotations_context_trimmed_ck": {
219
+ "name": "annotations_context_trimmed_ck",
220
+ "value": "\"annotations_annotations\".\"context\" = btrim(\"annotations_annotations\".\"context\", concat(chr(9), chr(10), chr(11), chr(12), chr(13), chr(32), chr(160), chr(5760), chr(8192), chr(8193), chr(8194), chr(8195), chr(8196), chr(8197), chr(8198), chr(8199), chr(8200), chr(8201), chr(8202), chr(8232), chr(8233), chr(8239), chr(8287), chr(12288), chr(65279)))"
221
+ },
222
+ "annotations_context_max_length_ck": {
223
+ "name": "annotations_context_max_length_ck",
224
+ "value": "length(\"annotations_annotations\".\"context\") <= 255"
225
+ }
226
+ },
227
+ "isRLSEnabled": false
228
+ }
229
+ },
230
+ "enums": {
231
+ "public.annotations_style": {
232
+ "name": "annotations_style",
233
+ "schema": "public",
234
+ "values": ["default", "info", "success", "warning", "error"]
235
+ }
236
+ },
237
+ "schemas": {},
238
+ "sequences": {},
239
+ "roles": {},
240
+ "policies": {},
241
+ "views": {},
242
+ "_meta": {
243
+ "columns": {},
244
+ "schemas": {},
245
+ "tables": {}
246
+ }
247
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": "7",
3
+ "dialect": "postgresql",
4
+ "entries": [
5
+ {
6
+ "idx": 0,
7
+ "version": "7",
8
+ "when": 1782017246000,
9
+ "tag": "0000_initial",
10
+ "breakpoints": true
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,7 @@
1
+ import {defineConfig} from 'drizzle-kit';
2
+
3
+ export default defineConfig({
4
+ schema: './src/db/schema/*.ts',
5
+ out: './drizzle',
6
+ dialect: 'postgresql',
7
+ });
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@shipfox/annotations",
3
+ "license": "MIT",
4
+ "version": "2.0.0",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/ShipfoxHQ/shipfox.git",
8
+ "directory": "libs/api/annotations"
9
+ },
10
+ "private": false,
11
+ "type": "module",
12
+ "main": "dist/index.js",
13
+ "types": "dist/index.d.ts",
14
+ "imports": {
15
+ "#test/*": "./test/*",
16
+ "#*": {
17
+ "workspace-source": "./src/*",
18
+ "development": "./src/*",
19
+ "default": "./dist/*"
20
+ }
21
+ },
22
+ "exports": {
23
+ ".": {
24
+ "development": {
25
+ "types": "./src/index.ts",
26
+ "default": "./src/index.ts"
27
+ },
28
+ "default": {
29
+ "types": "./dist/index.d.ts",
30
+ "default": "./dist/index.js"
31
+ }
32
+ }
33
+ },
34
+ "dependencies": {
35
+ "drizzle-orm": "^0.45.2",
36
+ "zod": "^4.4.3",
37
+ "@shipfox/annotations-dto": "2.0.0",
38
+ "@shipfox/api-auth-context": "2.0.0",
39
+ "@shipfox/node-drizzle": "0.2.1",
40
+ "@shipfox/node-fastify": "0.2.1",
41
+ "@shipfox/config": "1.2.1",
42
+ "@shipfox/node-module": "0.2.0",
43
+ "@shipfox/node-postgres": "0.4.1"
44
+ },
45
+ "devDependencies": {
46
+ "@types/pg": "^8.15.5",
47
+ "drizzle-kit": "^0.31.10",
48
+ "fastify": "^5.3.3",
49
+ "fastify-type-provider-zod": "^6.0.0",
50
+ "fishery": "^2.2.2",
51
+ "@shipfox/api-auth-dto": "2.0.0",
52
+ "@shipfox/biome": "1.8.1",
53
+ "@shipfox/node-jwt": "0.2.0",
54
+ "@shipfox/ts-config": "1.3.8",
55
+ "@shipfox/swc": "1.2.5",
56
+ "@shipfox/typescript": "1.1.6",
57
+ "@shipfox/vitest": "1.2.2",
58
+ "@shipfox/api-auth": "2.0.0"
59
+ },
60
+ "scripts": {
61
+ "build": "shipfox-swc",
62
+ "check": "shipfox-biome-check",
63
+ "check:fix": "shipfox-biome-check --write",
64
+ "test": "shipfox-vitest-run",
65
+ "test:watch": "shipfox-vitest-watch",
66
+ "type": "shipfox-tsc-check",
67
+ "type:emit": "shipfox-tsc-emit"
68
+ }
69
+ }
@@ -0,0 +1,45 @@
1
+ import {vi} from '@shipfox/vitest/vi';
2
+
3
+ describe.each([
4
+ 'ANNOTATIONS_MAX_BODY_BYTES',
5
+ 'ANNOTATIONS_MAX_PER_EXECUTION',
6
+ 'ANNOTATIONS_MAX_TOTAL_BYTES',
7
+ ] as const)('%s validation', (name) => {
8
+ afterEach(() => {
9
+ vi.unstubAllEnvs();
10
+ vi.resetModules();
11
+ });
12
+
13
+ it.each(['0', '-5', '1.5'])('fails startup when the value is %s', async (value) => {
14
+ vi.stubEnv(name, value);
15
+ vi.resetModules();
16
+
17
+ await expect(import('#config.js')).rejects.toThrow(name);
18
+ });
19
+
20
+ it('accepts a whole number greater than 0', async () => {
21
+ vi.stubEnv(name, '1');
22
+ vi.resetModules();
23
+
24
+ const {config} = await import('#config.js');
25
+
26
+ expect(config[name]).toBe(1);
27
+ });
28
+ });
29
+
30
+ describe('annotation config defaults', () => {
31
+ afterEach(() => {
32
+ vi.unstubAllEnvs();
33
+ vi.resetModules();
34
+ });
35
+
36
+ it('uses the documented annotation budget defaults', async () => {
37
+ vi.resetModules();
38
+
39
+ const {config} = await import('#config.js');
40
+
41
+ expect(config.ANNOTATIONS_MAX_BODY_BYTES).toBe(1048576);
42
+ expect(config.ANNOTATIONS_MAX_PER_EXECUTION).toBe(50);
43
+ expect(config.ANNOTATIONS_MAX_TOTAL_BYTES).toBe(4194304);
44
+ });
45
+ });
package/src/config.ts ADDED
@@ -0,0 +1,26 @@
1
+ import {createConfig, num} from '@shipfox/config';
2
+
3
+ export const config = createConfig({
4
+ ANNOTATIONS_MAX_BODY_BYTES: num({
5
+ desc: 'Maximum UTF-8 byte size of one annotation body. Writes that would make an annotation body larger than this are rejected.',
6
+ default: 1048576,
7
+ }),
8
+ ANNOTATIONS_MAX_PER_EXECUTION: num({
9
+ desc: 'Maximum number of distinct annotation contexts one job execution may store.',
10
+ default: 50,
11
+ }),
12
+ ANNOTATIONS_MAX_TOTAL_BYTES: num({
13
+ desc: 'Maximum total UTF-8 bytes of annotation bodies one job execution may store.',
14
+ default: 4194304,
15
+ }),
16
+ });
17
+
18
+ for (const name of [
19
+ 'ANNOTATIONS_MAX_BODY_BYTES',
20
+ 'ANNOTATIONS_MAX_PER_EXECUTION',
21
+ 'ANNOTATIONS_MAX_TOTAL_BYTES',
22
+ ] as const) {
23
+ if (!Number.isInteger(config[name]) || config[name] < 1) {
24
+ throw new Error(`${name} (${config[name]}) must be a whole number greater than 0.`);
25
+ }
26
+ }
@@ -0,0 +1,21 @@
1
+ import type {AnnotationStyleDto} from '@shipfox/annotations-dto';
2
+
3
+ export interface Annotation {
4
+ id: string;
5
+ workspaceId: string;
6
+ projectId: string;
7
+ workflowRunId: string;
8
+ workflowRunAttempt: number;
9
+ workflowRunAttemptId: string;
10
+ jobId: string;
11
+ jobExecutionId: string;
12
+ originStepId: string;
13
+ originStepAttempt: number;
14
+ context: string;
15
+ style: AnnotationStyleDto;
16
+ body: string;
17
+ bodyBytes: number;
18
+ sequence: number;
19
+ createdAt: Date;
20
+ updatedAt: Date;
21
+ }
@@ -0,0 +1 @@
1
+ export type {Annotation} from './annotation.js';
@@ -0,0 +1,20 @@
1
+ export class AnnotationBodyTooLargeError extends Error {
2
+ constructor(public readonly maxBytes: number) {
3
+ super(`Annotation body exceeds ${maxBytes} bytes`);
4
+ this.name = 'AnnotationBodyTooLargeError';
5
+ }
6
+ }
7
+
8
+ export class AnnotationCountLimitExceededError extends Error {
9
+ constructor(public readonly maxAnnotations: number) {
10
+ super(`Annotation count exceeds ${maxAnnotations}`);
11
+ this.name = 'AnnotationCountLimitExceededError';
12
+ }
13
+ }
14
+
15
+ export class AnnotationTotalBytesLimitExceededError extends Error {
16
+ constructor(public readonly maxBytes: number) {
17
+ super(`Annotation total body bytes exceed ${maxBytes}`);
18
+ this.name = 'AnnotationTotalBytesLimitExceededError';
19
+ }
20
+ }