@shipfox/annotations 5.0.0 → 7.1.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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +36 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/presentation/inter-module.d.ts +5 -0
- package/dist/presentation/inter-module.d.ts.map +1 -0
- package/dist/presentation/inter-module.js +50 -0
- package/dist/presentation/inter-module.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +8 -21
- package/src/index.ts +2 -7
- package/src/presentation/inter-module.test.ts +84 -0
- package/src/presentation/inter-module.ts +55 -0
- package/test/env.ts +1 -3
- package/test/fixtures/lease-token.ts +2 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipfox/annotations",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "7.1.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
@@ -24,33 +24,20 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"drizzle-orm": "^0.45.2",
|
|
26
26
|
"zod": "^4.4.3",
|
|
27
|
-
"@shipfox/annotations-dto": "
|
|
28
|
-
"@shipfox/api-auth-context": "
|
|
27
|
+
"@shipfox/annotations-dto": "6.0.0",
|
|
28
|
+
"@shipfox/api-auth-context": "7.1.0",
|
|
29
29
|
"@shipfox/config": "1.2.2",
|
|
30
|
-
"@shipfox/
|
|
31
|
-
"@shipfox/node-
|
|
32
|
-
"@shipfox/node-
|
|
30
|
+
"@shipfox/inter-module": "0.2.0",
|
|
31
|
+
"@shipfox/node-drizzle": "0.3.2",
|
|
32
|
+
"@shipfox/node-fastify": "0.3.0",
|
|
33
|
+
"@shipfox/node-module": "0.5.0",
|
|
33
34
|
"@shipfox/node-postgres": "0.4.2"
|
|
34
35
|
},
|
|
35
|
-
"devDependencies": {
|
|
36
|
-
"@types/pg": "^8.15.5",
|
|
37
|
-
"drizzle-kit": "^0.31.10",
|
|
38
|
-
"fastify": "^5.3.3",
|
|
39
|
-
"fastify-type-provider-zod": "^6.0.0",
|
|
40
|
-
"fishery": "^2.4.0",
|
|
41
|
-
"@shipfox/api-auth": "5.0.0",
|
|
42
|
-
"@shipfox/api-auth-dto": "5.0.0",
|
|
43
|
-
"@shipfox/biome": "1.8.2",
|
|
44
|
-
"@shipfox/node-jwt": "0.2.1",
|
|
45
|
-
"@shipfox/swc": "1.2.6",
|
|
46
|
-
"@shipfox/ts-config": "1.3.8",
|
|
47
|
-
"@shipfox/typescript": "1.1.7",
|
|
48
|
-
"@shipfox/vitest": "1.2.3"
|
|
49
|
-
},
|
|
50
36
|
"scripts": {
|
|
51
37
|
"build": "shipfox-swc",
|
|
52
38
|
"check": "shipfox-biome-check",
|
|
53
39
|
"check:fix": "shipfox-biome-check --write",
|
|
40
|
+
"depcruise": "shipfox-depcruise",
|
|
54
41
|
"test": "shipfox-vitest-run",
|
|
55
42
|
"test:watch": "shipfox-vitest-watch",
|
|
56
43
|
"type": "shipfox-tsc-check",
|
package/src/index.ts
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import type {ShipfoxModule} from '@shipfox/node-module';
|
|
2
2
|
import {db} from '#db/db.js';
|
|
3
3
|
import {migrationsPath} from '#db/index.js';
|
|
4
|
+
import {createAnnotationsInterModulePresentation} from '#presentation/inter-module.js';
|
|
4
5
|
import {annotationsRoutes} from '#presentation/routes/index.js';
|
|
5
6
|
|
|
6
|
-
export {
|
|
7
|
-
AnnotationBodyTooLargeError,
|
|
8
|
-
AnnotationCountLimitExceededError,
|
|
9
|
-
AnnotationTotalBytesLimitExceededError,
|
|
10
|
-
} from '#core/errors.js';
|
|
11
|
-
export {type WriteAnnotationsParams, writeAnnotations} from '#core/write-annotations.js';
|
|
12
|
-
|
|
13
7
|
export const annotationsModule: ShipfoxModule = {
|
|
14
8
|
name: 'annotations',
|
|
15
9
|
database: {db, migrationsPath},
|
|
16
10
|
routes: annotationsRoutes,
|
|
11
|
+
interModulePresentations: [createAnnotationsInterModulePresentation()],
|
|
17
12
|
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {annotationsInterModuleContract} from '@shipfox/annotations-dto/inter-module';
|
|
2
|
+
import {isInterModuleKnownError} from '@shipfox/inter-module';
|
|
3
|
+
import {eq} from 'drizzle-orm';
|
|
4
|
+
import {
|
|
5
|
+
AnnotationBodyTooLargeError,
|
|
6
|
+
AnnotationCountLimitExceededError,
|
|
7
|
+
AnnotationTotalBytesLimitExceededError,
|
|
8
|
+
} from '#core/errors.js';
|
|
9
|
+
import {db} from '#db/db.js';
|
|
10
|
+
import {annotations} from '#db/schema/annotations.js';
|
|
11
|
+
import {
|
|
12
|
+
createAnnotationsInterModulePresentation,
|
|
13
|
+
toReplaceOrRemoveAnnotationKnownError,
|
|
14
|
+
} from './inter-module.js';
|
|
15
|
+
|
|
16
|
+
function input() {
|
|
17
|
+
return {
|
|
18
|
+
workspaceId: crypto.randomUUID(),
|
|
19
|
+
projectId: crypto.randomUUID(),
|
|
20
|
+
workflowRunId: crypto.randomUUID(),
|
|
21
|
+
workflowRunAttempt: 1,
|
|
22
|
+
workflowRunAttemptId: crypto.randomUUID(),
|
|
23
|
+
jobId: crypto.randomUUID(),
|
|
24
|
+
jobExecutionId: crypto.randomUUID(),
|
|
25
|
+
originStepId: crypto.randomUUID(),
|
|
26
|
+
originStepAttempt: 1,
|
|
27
|
+
context: 'agent-tool-capability:step',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe('Annotations inter-module presentation', () => {
|
|
32
|
+
test('replaces and removes a warning annotation through PostgreSQL', async () => {
|
|
33
|
+
const presentation = createAnnotationsInterModulePresentation();
|
|
34
|
+
const target = input();
|
|
35
|
+
const handlerContext = {signal: new AbortController().signal};
|
|
36
|
+
|
|
37
|
+
await presentation.handlers.replaceOrRemoveAnnotation(
|
|
38
|
+
{
|
|
39
|
+
...target,
|
|
40
|
+
annotation: {op: 'replace', style: 'warning', body: 'Missing tool'},
|
|
41
|
+
},
|
|
42
|
+
handlerContext,
|
|
43
|
+
);
|
|
44
|
+
const afterReplace = await db()
|
|
45
|
+
.select()
|
|
46
|
+
.from(annotations)
|
|
47
|
+
.where(eq(annotations.jobExecutionId, target.jobExecutionId));
|
|
48
|
+
|
|
49
|
+
await presentation.handlers.replaceOrRemoveAnnotation(
|
|
50
|
+
{
|
|
51
|
+
...target,
|
|
52
|
+
annotation: {op: 'remove'},
|
|
53
|
+
},
|
|
54
|
+
handlerContext,
|
|
55
|
+
);
|
|
56
|
+
const afterRemove = await db()
|
|
57
|
+
.select()
|
|
58
|
+
.from(annotations)
|
|
59
|
+
.where(eq(annotations.jobExecutionId, target.jobExecutionId));
|
|
60
|
+
|
|
61
|
+
expect(afterReplace).toHaveLength(1);
|
|
62
|
+
expect(afterReplace[0]).toMatchObject({
|
|
63
|
+
context: target.context,
|
|
64
|
+
style: 'warning',
|
|
65
|
+
body: 'Missing tool',
|
|
66
|
+
});
|
|
67
|
+
expect(afterRemove).toEqual([]);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test.each([
|
|
71
|
+
['annotation-body-too-large', () => new AnnotationBodyTooLargeError(10)],
|
|
72
|
+
['annotation-count-limit-exceeded', () => new AnnotationCountLimitExceededError(10)],
|
|
73
|
+
['annotation-total-bytes-limit-exceeded', () => new AnnotationTotalBytesLimitExceededError(10)],
|
|
74
|
+
] as const)('maps %s to the published contract error', (code, createError) => {
|
|
75
|
+
const result = toReplaceOrRemoveAnnotationKnownError(createError());
|
|
76
|
+
|
|
77
|
+
expect(
|
|
78
|
+
isInterModuleKnownError(
|
|
79
|
+
annotationsInterModuleContract.methods.replaceOrRemoveAnnotation,
|
|
80
|
+
result,
|
|
81
|
+
) && result.code,
|
|
82
|
+
).toBe(code);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {annotationsInterModuleContract} from '@shipfox/annotations-dto/inter-module';
|
|
2
|
+
import {
|
|
3
|
+
createInterModuleKnownError,
|
|
4
|
+
defineInterModulePresentation,
|
|
5
|
+
type InterModulePresentation,
|
|
6
|
+
} from '@shipfox/inter-module';
|
|
7
|
+
import {
|
|
8
|
+
AnnotationBodyTooLargeError,
|
|
9
|
+
AnnotationCountLimitExceededError,
|
|
10
|
+
AnnotationTotalBytesLimitExceededError,
|
|
11
|
+
} from '#core/errors.js';
|
|
12
|
+
import {writeAnnotations} from '#core/write-annotations.js';
|
|
13
|
+
|
|
14
|
+
export function createAnnotationsInterModulePresentation(): InterModulePresentation<
|
|
15
|
+
typeof annotationsInterModuleContract
|
|
16
|
+
> {
|
|
17
|
+
return defineInterModulePresentation(annotationsInterModuleContract, {
|
|
18
|
+
replaceOrRemoveAnnotation: async (input) => {
|
|
19
|
+
try {
|
|
20
|
+
const {annotation, context, ...target} = input;
|
|
21
|
+
await writeAnnotations({
|
|
22
|
+
...target,
|
|
23
|
+
operations: [
|
|
24
|
+
annotation.op === 'remove'
|
|
25
|
+
? {context, style: 'warning', op: 'remove'}
|
|
26
|
+
: {context, ...annotation},
|
|
27
|
+
],
|
|
28
|
+
});
|
|
29
|
+
return {};
|
|
30
|
+
} catch (error) {
|
|
31
|
+
throw toReplaceOrRemoveAnnotationKnownError(error);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function toReplaceOrRemoveAnnotationKnownError(error: unknown): unknown {
|
|
38
|
+
const method = annotationsInterModuleContract.methods.replaceOrRemoveAnnotation;
|
|
39
|
+
if (error instanceof AnnotationBodyTooLargeError) {
|
|
40
|
+
return createInterModuleKnownError(method, 'annotation-body-too-large', {
|
|
41
|
+
maxBytes: error.maxBytes,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (error instanceof AnnotationCountLimitExceededError) {
|
|
45
|
+
return createInterModuleKnownError(method, 'annotation-count-limit-exceeded', {
|
|
46
|
+
maxAnnotations: error.maxAnnotations,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (error instanceof AnnotationTotalBytesLimitExceededError) {
|
|
50
|
+
return createInterModuleKnownError(method, 'annotation-total-bytes-limit-exceeded', {
|
|
51
|
+
maxBytes: error.maxBytes,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return error;
|
|
55
|
+
}
|
package/test/env.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
process.env.DATABASE_URL ??= 'postgres://shipfox:shipfox@127.0.0.1:5432/api_test';
|
|
2
|
-
process.env.
|
|
3
|
-
process.env.AUTH_JOB_LEASE_TOKEN_SECRET = 'test-lease-secret';
|
|
4
|
-
process.env.AUTH_RUNNER_SESSION_TOKEN_SECRET = 'test-runner-session-secret';
|
|
2
|
+
process.env.AUTH_ROOT_KEY = 'MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=';
|
|
5
3
|
process.env.TZ = 'UTC';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {JOB_LEASE_TOKEN_AUDIENCE} from '@shipfox/api-auth-dto';
|
|
2
|
+
import {jobLeaseTokenKey} from '@shipfox/node-auth-root-key';
|
|
2
3
|
import {signHs256} from '@shipfox/node-jwt';
|
|
3
4
|
|
|
4
|
-
const SECRET =
|
|
5
|
+
const SECRET = jobLeaseTokenKey();
|
|
5
6
|
|
|
6
7
|
export interface MintLeaseTokenParams {
|
|
7
8
|
jobId: string;
|