@shipfox/api-projects 11.0.0 → 12.2.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 +4 -4
- package/CHANGELOG.md +53 -0
- package/README.md +83 -0
- package/dist/core/entities/project.d.ts +4 -0
- package/dist/core/entities/project.d.ts.map +1 -1
- package/dist/core/entities/project.js.map +1 -1
- package/dist/core/errors.d.ts +4 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +6 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/projects.d.ts +8 -0
- package/dist/core/projects.d.ts.map +1 -1
- package/dist/core/projects.js +62 -19
- package/dist/core/projects.js.map +1 -1
- package/dist/db/db.d.ts +144 -6
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js.map +1 -1
- package/dist/db/index.d.ts +2 -2
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/projects.d.ts +53 -0
- package/dist/db/projects.d.ts.map +1 -1
- package/dist/db/projects.js +116 -18
- package/dist/db/projects.js.map +1 -1
- package/dist/db/schema/integration-event-dedup.d.ts +1 -1
- package/dist/db/schema/outbox.d.ts +1 -1
- package/dist/db/schema/projects.d.ts +69 -1
- package/dist/db/schema/projects.d.ts.map +1 -1
- package/dist/db/schema/projects.js +12 -1
- package/dist/db/schema/projects.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/presentation/dto/project.d.ts +2 -1
- package/dist/presentation/dto/project.d.ts.map +1 -1
- package/dist/presentation/dto/project.js +1 -0
- package/dist/presentation/dto/project.js.map +1 -1
- package/dist/presentation/e2eRoutes/create-project.d.ts.map +1 -1
- package/dist/presentation/e2eRoutes/create-project.js +34 -8
- package/dist/presentation/e2eRoutes/create-project.js.map +1 -1
- package/dist/presentation/inter-module.d.ts +4 -1
- package/dist/presentation/inter-module.d.ts.map +1 -1
- package/dist/presentation/inter-module.js +63 -3
- package/dist/presentation/inter-module.js.map +1 -1
- package/dist/presentation/routes/create-project.d.ts.map +1 -1
- package/dist/presentation/routes/create-project.js +8 -2
- package/dist/presentation/routes/create-project.js.map +1 -1
- package/dist/presentation/routes/index.d.ts.map +1 -1
- package/dist/presentation/routes/index.js +3 -1
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/presentation/routes/update-project.d.ts +2 -0
- package/dist/presentation/routes/update-project.d.ts.map +1 -0
- package/dist/presentation/routes/update-project.js +53 -0
- package/dist/presentation/routes/update-project.js.map +1 -0
- package/dist/presentation/subscribers/index.d.ts +1 -0
- package/dist/presentation/subscribers/index.d.ts.map +1 -1
- package/dist/presentation/subscribers/index.js +1 -0
- package/dist/presentation/subscribers/index.js.map +1 -1
- package/dist/presentation/subscribers/on-source-repository-updated.d.ts +4 -0
- package/dist/presentation/subscribers/on-source-repository-updated.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-source-repository-updated.js +39 -0
- package/dist/presentation/subscribers/on-source-repository-updated.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0000_initial.sql +6 -0
- package/drizzle/meta/0000_snapshot.json +78 -0
- package/package.json +13 -12
- package/src/core/entities/project.ts +4 -0
- package/src/core/errors.ts +7 -0
- package/src/core/index.ts +3 -2
- package/src/core/projects.test.ts +10 -0
- package/src/core/projects.ts +90 -35
- package/src/db/db.ts +3 -0
- package/src/db/index.ts +6 -0
- package/src/db/projects.test.ts +44 -1
- package/src/db/projects.ts +242 -33
- package/src/db/schema/projects.ts +16 -0
- package/src/index.ts +9 -3
- package/src/presentation/dto/project.ts +1 -0
- package/src/presentation/e2eRoutes/create-project.test.ts +23 -0
- package/src/presentation/e2eRoutes/create-project.ts +39 -10
- package/src/presentation/inter-module.test.ts +349 -0
- package/src/presentation/inter-module.ts +90 -4
- package/src/presentation/routes/create-project.ts +10 -2
- package/src/presentation/routes/index.ts +7 -1
- package/src/presentation/routes/projects.test.ts +300 -4
- package/src/presentation/routes/update-project.ts +46 -0
- package/src/presentation/subscribers/index.ts +1 -0
- package/src/presentation/subscribers/on-source-commit-pushed.test.ts +2 -0
- package/src/presentation/subscribers/on-source-repository-updated.test.ts +108 -0
- package/src/presentation/subscribers/on-source-repository-updated.ts +50 -0
- package/test/factories/project.ts +6 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/routes/create-project.ts"],"sourcesContent":["import {AUTH_USER, requireUserContext, requireWorkspaceAccess} from '@shipfox/api-auth-context';\nimport {\n type IntegrationsModuleClient,\n integrationsInterModuleContract,\n} from '@shipfox/api-integration-core-dto/inter-module';\nimport {createProjectBodySchema, projectResponseSchema} from '@shipfox/api-projects-dto';\nimport {isInterModuleKnownError} from '@shipfox/inter-module';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {createProjectFromSource
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/create-project.ts"],"sourcesContent":["import {AUTH_USER, requireUserContext, requireWorkspaceAccess} from '@shipfox/api-auth-context';\nimport {\n type IntegrationsModuleClient,\n integrationsInterModuleContract,\n} from '@shipfox/api-integration-core-dto/inter-module';\nimport {createProjectBodySchema, projectResponseSchema} from '@shipfox/api-projects-dto';\nimport {isInterModuleKnownError} from '@shipfox/inter-module';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {\n createProjectFromSource,\n ProjectAlreadyExistsError,\n ProjectSlugConflictError,\n} from '#core/index.js';\nimport {toProjectDto} from '#presentation/dto/index.js';\n\nfunction providerStatus(reason: string): number {\n if (reason === 'rate-limited') return 429;\n if (reason === 'timeout' || reason === 'provider-unavailable') return 503;\n return 422;\n}\n\nexport function createProjectRoute(integrations: IntegrationsModuleClient) {\n return defineRoute({\n method: 'POST',\n path: '/',\n auth: AUTH_USER,\n description: 'Create a project bound to a source repository.',\n schema: {\n body: createProjectBodySchema,\n response: {\n 201: projectResponseSchema,\n },\n },\n errorHandler: (error) => {\n const known = isInterModuleKnownError(\n integrationsInterModuleContract.methods.resolveSourceRepository,\n error,\n )\n ? error\n : undefined;\n if (known?.code === 'connection-not-found') {\n throw new ClientError('Source connection not found', 'source-connection-not-found', {\n status: 404,\n });\n }\n if (known?.code === 'connection-workspace-mismatch') {\n throw new ClientError('Source connection does not belong to this workspace', 'forbidden', {\n status: 403,\n });\n }\n if (known?.code === 'connection-inactive') {\n throw new ClientError('Source connection is not active', 'source-connection-inactive', {\n status: 422,\n });\n }\n if (known?.code === 'provider-unavailable') {\n throw new ClientError(\n 'Integration provider is unavailable',\n 'integration-provider-unavailable',\n {status: 422},\n );\n }\n if (known?.code === 'capability-unavailable') {\n throw new ClientError(\n 'Integration capability is unavailable',\n 'integration-capability-unavailable',\n {status: 422},\n );\n }\n if (error instanceof ProjectAlreadyExistsError) {\n throw new ClientError(error.message, 'project-already-exists', {\n details: {\n existing_project_id: error.existingProjectId,\n source_connection_id: error.sourceConnectionId,\n source_external_repository_id: error.sourceExternalRepositoryId,\n },\n status: 409,\n });\n }\n if (error instanceof ProjectSlugConflictError) {\n throw new ClientError('Project slug already exists', 'slug-conflict', {status: 409});\n }\n if (known?.code === 'provider-failure') {\n throw new ClientError('Integration provider request failed', known.details.reason, {\n details: {retry_after_seconds: known.details.retryAfterSeconds},\n status: providerStatus(known.details.reason),\n });\n }\n throw error;\n },\n handler: async (request, reply) => {\n const {workspace_id: workspaceId, name, slug, source} = request.body;\n const actor = requireUserContext(request);\n\n requireWorkspaceAccess({request, workspaceId});\n const project = await createProjectFromSource({\n actorId: actor.userId,\n workspaceId,\n name,\n slug,\n sourceConnectionId: source.connection_id,\n sourceExternalRepositoryId: source.external_repository_id,\n integrations,\n });\n\n reply.status(201);\n return toProjectDto(project);\n },\n });\n}\n"],"names":["AUTH_USER","requireUserContext","requireWorkspaceAccess","integrationsInterModuleContract","createProjectBodySchema","projectResponseSchema","isInterModuleKnownError","ClientError","defineRoute","createProjectFromSource","ProjectAlreadyExistsError","ProjectSlugConflictError","toProjectDto","providerStatus","reason","createProjectRoute","integrations","method","path","auth","description","schema","body","response","errorHandler","error","known","methods","resolveSourceRepository","undefined","code","status","message","details","existing_project_id","existingProjectId","source_connection_id","sourceConnectionId","source_external_repository_id","sourceExternalRepositoryId","retry_after_seconds","retryAfterSeconds","handler","request","reply","workspace_id","workspaceId","name","slug","source","actor","project","actorId","userId","connection_id","external_repository_id"],"mappings":"AAAA,SAAQA,SAAS,EAAEC,kBAAkB,EAAEC,sBAAsB,QAAO,4BAA4B;AAChG,SAEEC,+BAA+B,QAC1B,iDAAiD;AACxD,SAAQC,uBAAuB,EAAEC,qBAAqB,QAAO,4BAA4B;AACzF,SAAQC,uBAAuB,QAAO,wBAAwB;AAC9D,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SACEC,uBAAuB,EACvBC,yBAAyB,EACzBC,wBAAwB,QACnB,iBAAiB;AACxB,SAAQC,YAAY,QAAO,6BAA6B;AAExD,SAASC,eAAeC,MAAc;IACpC,IAAIA,WAAW,gBAAgB,OAAO;IACtC,IAAIA,WAAW,aAAaA,WAAW,wBAAwB,OAAO;IACtE,OAAO;AACT;AAEA,OAAO,SAASC,mBAAmBC,YAAsC;IACvE,OAAOR,YAAY;QACjBS,QAAQ;QACRC,MAAM;QACNC,MAAMnB;QACNoB,aAAa;QACbC,QAAQ;YACNC,MAAMlB;YACNmB,UAAU;gBACR,KAAKlB;YACP;QACF;QACAmB,cAAc,CAACC;YACb,MAAMC,QAAQpB,wBACZH,gCAAgCwB,OAAO,CAACC,uBAAuB,EAC/DH,SAEEA,QACAI;YACJ,IAAIH,OAAOI,SAAS,wBAAwB;gBAC1C,MAAM,IAAIvB,YAAY,+BAA+B,+BAA+B;oBAClFwB,QAAQ;gBACV;YACF;YACA,IAAIL,OAAOI,SAAS,iCAAiC;gBACnD,MAAM,IAAIvB,YAAY,uDAAuD,aAAa;oBACxFwB,QAAQ;gBACV;YACF;YACA,IAAIL,OAAOI,SAAS,uBAAuB;gBACzC,MAAM,IAAIvB,YAAY,mCAAmC,8BAA8B;oBACrFwB,QAAQ;gBACV;YACF;YACA,IAAIL,OAAOI,SAAS,wBAAwB;gBAC1C,MAAM,IAAIvB,YACR,uCACA,oCACA;oBAACwB,QAAQ;gBAAG;YAEhB;YACA,IAAIL,OAAOI,SAAS,0BAA0B;gBAC5C,MAAM,IAAIvB,YACR,yCACA,sCACA;oBAACwB,QAAQ;gBAAG;YAEhB;YACA,IAAIN,iBAAiBf,2BAA2B;gBAC9C,MAAM,IAAIH,YAAYkB,MAAMO,OAAO,EAAE,0BAA0B;oBAC7DC,SAAS;wBACPC,qBAAqBT,MAAMU,iBAAiB;wBAC5CC,sBAAsBX,MAAMY,kBAAkB;wBAC9CC,+BAA+Bb,MAAMc,0BAA0B;oBACjE;oBACAR,QAAQ;gBACV;YACF;YACA,IAAIN,iBAAiBd,0BAA0B;gBAC7C,MAAM,IAAIJ,YAAY,+BAA+B,iBAAiB;oBAACwB,QAAQ;gBAAG;YACpF;YACA,IAAIL,OAAOI,SAAS,oBAAoB;gBACtC,MAAM,IAAIvB,YAAY,uCAAuCmB,MAAMO,OAAO,CAACnB,MAAM,EAAE;oBACjFmB,SAAS;wBAACO,qBAAqBd,MAAMO,OAAO,CAACQ,iBAAiB;oBAAA;oBAC9DV,QAAQlB,eAAea,MAAMO,OAAO,CAACnB,MAAM;gBAC7C;YACF;YACA,MAAMW;QACR;QACAiB,SAAS,OAAOC,SAASC;YACvB,MAAM,EAACC,cAAcC,WAAW,EAAEC,IAAI,EAAEC,IAAI,EAAEC,MAAM,EAAC,GAAGN,QAAQrB,IAAI;YACpE,MAAM4B,QAAQjD,mBAAmB0C;YAEjCzC,uBAAuB;gBAACyC;gBAASG;YAAW;YAC5C,MAAMK,UAAU,MAAM1C,wBAAwB;gBAC5C2C,SAASF,MAAMG,MAAM;gBACrBP;gBACAC;gBACAC;gBACAX,oBAAoBY,OAAOK,aAAa;gBACxCf,4BAA4BU,OAAOM,sBAAsB;gBACzDvC;YACF;YAEA4B,MAAMb,MAAM,CAAC;YACb,OAAOnB,aAAauC;QACtB;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,gDAAgD,CAAC;AAC7F,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,gDAAgD,CAAC;AAC7F,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAOtD,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,wBAAwB,EACtC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,kBAAkB,CAAC,GACpD,UAAU,EAAE,CAgBd"}
|
|
@@ -2,6 +2,7 @@ import { createAdminProjectsRoute } from './admin-projects.js';
|
|
|
2
2
|
import { createProjectRoute } from './create-project.js';
|
|
3
3
|
import { getProjectRoute } from './get-project.js';
|
|
4
4
|
import { listProjectsRoute } from './list-projects.js';
|
|
5
|
+
import { updateProjectRoute } from './update-project.js';
|
|
5
6
|
export function createProjectRoutes(integrations, auth) {
|
|
6
7
|
return [
|
|
7
8
|
{
|
|
@@ -9,7 +10,8 @@ export function createProjectRoutes(integrations, auth) {
|
|
|
9
10
|
routes: [
|
|
10
11
|
createProjectRoute(integrations),
|
|
11
12
|
listProjectsRoute,
|
|
12
|
-
getProjectRoute
|
|
13
|
+
getProjectRoute,
|
|
14
|
+
updateProjectRoute
|
|
13
15
|
]
|
|
14
16
|
},
|
|
15
17
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/routes/index.ts"],"sourcesContent":["import type {AuthInterModuleClient} from '@shipfox/api-auth-dto/inter-module';\nimport type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport type {RouteGroup} from '@shipfox/node-fastify';\nimport {createAdminProjectsRoute} from './admin-projects.js';\nimport {createProjectRoute} from './create-project.js';\nimport {getProjectRoute} from './get-project.js';\nimport {listProjectsRoute} from './list-projects.js';\n\nexport function createProjectRoutes(\n integrations: IntegrationsModuleClient,\n auth: Pick<AuthInterModuleClient, 'requireAdminRole'>,\n): RouteGroup[] {\n return [\n {\n prefix: '/projects',\n routes: [createProjectRoute(integrations)
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/index.ts"],"sourcesContent":["import type {AuthInterModuleClient} from '@shipfox/api-auth-dto/inter-module';\nimport type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport type {RouteGroup} from '@shipfox/node-fastify';\nimport {createAdminProjectsRoute} from './admin-projects.js';\nimport {createProjectRoute} from './create-project.js';\nimport {getProjectRoute} from './get-project.js';\nimport {listProjectsRoute} from './list-projects.js';\nimport {updateProjectRoute} from './update-project.js';\n\nexport function createProjectRoutes(\n integrations: IntegrationsModuleClient,\n auth: Pick<AuthInterModuleClient, 'requireAdminRole'>,\n): RouteGroup[] {\n return [\n {\n prefix: '/projects',\n routes: [\n createProjectRoute(integrations),\n listProjectsRoute,\n getProjectRoute,\n updateProjectRoute,\n ],\n },\n {\n prefix: '/admin/projects',\n routes: [createAdminProjectsRoute(auth)],\n },\n ];\n}\n"],"names":["createAdminProjectsRoute","createProjectRoute","getProjectRoute","listProjectsRoute","updateProjectRoute","createProjectRoutes","integrations","auth","prefix","routes"],"mappings":"AAGA,SAAQA,wBAAwB,QAAO,sBAAsB;AAC7D,SAAQC,kBAAkB,QAAO,sBAAsB;AACvD,SAAQC,eAAe,QAAO,mBAAmB;AACjD,SAAQC,iBAAiB,QAAO,qBAAqB;AACrD,SAAQC,kBAAkB,QAAO,sBAAsB;AAEvD,OAAO,SAASC,oBACdC,YAAsC,EACtCC,IAAqD;IAErD,OAAO;QACL;YACEC,QAAQ;YACRC,QAAQ;gBACNR,mBAAmBK;gBACnBH;gBACAD;gBACAE;aACD;QACH;QACA;YACEI,QAAQ;YACRC,QAAQ;gBAACT,yBAAyBO;aAAM;QAC1C;KACD;AACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-project.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/update-project.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,kBAAkB,iDAiC7B,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { AUTH_USER, requireUserContext } from '@shipfox/api-auth-context';
|
|
2
|
+
import { projectResponseSchema, updateProjectBodySchema } from '@shipfox/api-projects-dto';
|
|
3
|
+
import { ClientError, defineRoute } from '@shipfox/node-fastify';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { ProjectNotFoundError, ProjectSlugConflictError, updateProjectDetails } from '#core/index.js';
|
|
6
|
+
import { requireProjectAccess } from '#presentation/auth/require-project-access.js';
|
|
7
|
+
import { toProjectDto } from '#presentation/dto/index.js';
|
|
8
|
+
const projectParamsSchema = z.object({
|
|
9
|
+
projectId: z.string().uuid()
|
|
10
|
+
});
|
|
11
|
+
export const updateProjectRoute = defineRoute({
|
|
12
|
+
method: 'PATCH',
|
|
13
|
+
path: '/:projectId',
|
|
14
|
+
auth: AUTH_USER,
|
|
15
|
+
description: 'Update a project.',
|
|
16
|
+
schema: {
|
|
17
|
+
params: projectParamsSchema,
|
|
18
|
+
body: updateProjectBodySchema,
|
|
19
|
+
response: {
|
|
20
|
+
200: projectResponseSchema
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
errorHandler: (error)=>{
|
|
24
|
+
if (error instanceof ProjectSlugConflictError) {
|
|
25
|
+
throw new ClientError('Project slug already exists', 'slug-conflict', {
|
|
26
|
+
status: 409
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (error instanceof ProjectNotFoundError) {
|
|
30
|
+
throw new ClientError('Project not found', 'project-not-found', {
|
|
31
|
+
status: 404
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
},
|
|
36
|
+
handler: async (request)=>{
|
|
37
|
+
const { projectId } = request.params;
|
|
38
|
+
await requireProjectAccess({
|
|
39
|
+
request,
|
|
40
|
+
projectId
|
|
41
|
+
});
|
|
42
|
+
const actor = requireUserContext(request);
|
|
43
|
+
const project = await updateProjectDetails({
|
|
44
|
+
actorId: actor.userId,
|
|
45
|
+
projectId,
|
|
46
|
+
name: request.body.name,
|
|
47
|
+
slug: request.body.slug
|
|
48
|
+
});
|
|
49
|
+
return toProjectDto(project);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=update-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/update-project.ts"],"sourcesContent":["import {AUTH_USER, requireUserContext} from '@shipfox/api-auth-context';\nimport {projectResponseSchema, updateProjectBodySchema} from '@shipfox/api-projects-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {z} from 'zod';\nimport {ProjectNotFoundError, ProjectSlugConflictError, updateProjectDetails} from '#core/index.js';\nimport {requireProjectAccess} from '#presentation/auth/require-project-access.js';\nimport {toProjectDto} from '#presentation/dto/index.js';\n\nconst projectParamsSchema = z.object({\n projectId: z.string().uuid(),\n});\n\nexport const updateProjectRoute = defineRoute({\n method: 'PATCH',\n path: '/:projectId',\n auth: AUTH_USER,\n description: 'Update a project.',\n schema: {\n params: projectParamsSchema,\n body: updateProjectBodySchema,\n response: {\n 200: projectResponseSchema,\n },\n },\n errorHandler: (error) => {\n if (error instanceof ProjectSlugConflictError) {\n throw new ClientError('Project slug already exists', 'slug-conflict', {status: 409});\n }\n if (error instanceof ProjectNotFoundError) {\n throw new ClientError('Project not found', 'project-not-found', {status: 404});\n }\n throw error;\n },\n handler: async (request) => {\n const {projectId} = request.params;\n await requireProjectAccess({request, projectId});\n const actor = requireUserContext(request);\n const project = await updateProjectDetails({\n actorId: actor.userId,\n projectId,\n name: request.body.name,\n slug: request.body.slug,\n });\n return toProjectDto(project);\n },\n});\n"],"names":["AUTH_USER","requireUserContext","projectResponseSchema","updateProjectBodySchema","ClientError","defineRoute","z","ProjectNotFoundError","ProjectSlugConflictError","updateProjectDetails","requireProjectAccess","toProjectDto","projectParamsSchema","object","projectId","string","uuid","updateProjectRoute","method","path","auth","description","schema","params","body","response","errorHandler","error","status","handler","request","actor","project","actorId","userId","name","slug"],"mappings":"AAAA,SAAQA,SAAS,EAAEC,kBAAkB,QAAO,4BAA4B;AACxE,SAAQC,qBAAqB,EAAEC,uBAAuB,QAAO,4BAA4B;AACzF,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,CAAC,QAAO,MAAM;AACtB,SAAQC,oBAAoB,EAAEC,wBAAwB,EAAEC,oBAAoB,QAAO,iBAAiB;AACpG,SAAQC,oBAAoB,QAAO,+CAA+C;AAClF,SAAQC,YAAY,QAAO,6BAA6B;AAExD,MAAMC,sBAAsBN,EAAEO,MAAM,CAAC;IACnCC,WAAWR,EAAES,MAAM,GAAGC,IAAI;AAC5B;AAEA,OAAO,MAAMC,qBAAqBZ,YAAY;IAC5Ca,QAAQ;IACRC,MAAM;IACNC,MAAMpB;IACNqB,aAAa;IACbC,QAAQ;QACNC,QAAQX;QACRY,MAAMrB;QACNsB,UAAU;YACR,KAAKvB;QACP;IACF;IACAwB,cAAc,CAACC;QACb,IAAIA,iBAAiBnB,0BAA0B;YAC7C,MAAM,IAAIJ,YAAY,+BAA+B,iBAAiB;gBAACwB,QAAQ;YAAG;QACpF;QACA,IAAID,iBAAiBpB,sBAAsB;YACzC,MAAM,IAAIH,YAAY,qBAAqB,qBAAqB;gBAACwB,QAAQ;YAAG;QAC9E;QACA,MAAMD;IACR;IACAE,SAAS,OAAOC;QACd,MAAM,EAAChB,SAAS,EAAC,GAAGgB,QAAQP,MAAM;QAClC,MAAMb,qBAAqB;YAACoB;YAAShB;QAAS;QAC9C,MAAMiB,QAAQ9B,mBAAmB6B;QACjC,MAAME,UAAU,MAAMvB,qBAAqB;YACzCwB,SAASF,MAAMG,MAAM;YACrBpB;YACAqB,MAAML,QAAQN,IAAI,CAACW,IAAI;YACvBC,MAAMN,QAAQN,IAAI,CAACY,IAAI;QACzB;QACA,OAAOzB,aAAaqB;IACtB;AACF,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/subscribers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,8BAA8B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/subscribers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAC,yBAAyB,EAAC,MAAM,mCAAmC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/subscribers/index.ts"],"sourcesContent":["export {onSourceCommitPushed} from './on-source-commit-pushed.js';\n"],"names":["onSourceCommitPushed"],"mappings":"AAAA,SAAQA,oBAAoB,QAAO,+BAA+B"}
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/subscribers/index.ts"],"sourcesContent":["export {onSourceCommitPushed} from './on-source-commit-pushed.js';\nexport {onSourceRepositoryUpdated} from './on-source-repository-updated.js';\n"],"names":["onSourceCommitPushed","onSourceRepositoryUpdated"],"mappings":"AAAA,SAAQA,oBAAoB,QAAO,+BAA+B;AAClE,SAAQC,yBAAyB,QAAO,oCAAoC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { IntegrationSourceRepositoryUpdatedEvent } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import type { DomainEvent } from '@shipfox/node-outbox';
|
|
3
|
+
export declare function onSourceRepositoryUpdated(payload: IntegrationSourceRepositoryUpdatedEvent, event: DomainEvent<IntegrationSourceRepositoryUpdatedEvent>): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=on-source-repository-updated.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"on-source-repository-updated.d.ts","sourceRoot":"","sources":["../../../src/presentation/subscribers/on-source-repository-updated.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,uCAAuC,EAAC,MAAM,mCAAmC,CAAC;AAE/F,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,sBAAsB,CAAC;AAKtD,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,uCAAuC,EAChD,KAAK,EAAE,WAAW,CAAC,uCAAuC,CAAC,GAC1D,OAAO,CAAC,IAAI,CAAC,CAuCf"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { logger } from '@shipfox/node-opentelemetry';
|
|
2
|
+
import { db } from '#db/db.js';
|
|
3
|
+
import { recordIntegrationEventForProject } from '#db/integration-event-dedup.js';
|
|
4
|
+
import { getProjectBySource, updateProjectSourceRepository } from '#db/projects.js';
|
|
5
|
+
export async function onSourceRepositoryUpdated(payload, event) {
|
|
6
|
+
const project = await getProjectBySource({
|
|
7
|
+
workspaceId: payload.workspaceId,
|
|
8
|
+
sourceConnectionId: payload.connectionId,
|
|
9
|
+
sourceExternalRepositoryId: payload.repository.externalRepositoryId
|
|
10
|
+
});
|
|
11
|
+
if (project) {
|
|
12
|
+
const outcome = await db().transaction(async (tx)=>{
|
|
13
|
+
const { firstSeen } = await recordIntegrationEventForProject({
|
|
14
|
+
tx,
|
|
15
|
+
integrationEventId: event.id,
|
|
16
|
+
projectId: project.id
|
|
17
|
+
});
|
|
18
|
+
if (!firstSeen) return 'duplicate';
|
|
19
|
+
const updated = await updateProjectSourceRepository({
|
|
20
|
+
tx,
|
|
21
|
+
workspaceId: payload.workspaceId,
|
|
22
|
+
sourceConnectionId: payload.connectionId,
|
|
23
|
+
sourceExternalRepositoryId: payload.repository.externalRepositoryId,
|
|
24
|
+
sourceRepositoryOwner: payload.repository.owner,
|
|
25
|
+
sourceRepositoryName: payload.repository.name,
|
|
26
|
+
sourceDefaultBranch: payload.repository.defaultBranch
|
|
27
|
+
});
|
|
28
|
+
return updated ? 'updated' : 'missing';
|
|
29
|
+
});
|
|
30
|
+
if (outcome !== 'missing') return;
|
|
31
|
+
}
|
|
32
|
+
logger().info({
|
|
33
|
+
eventId: event.id,
|
|
34
|
+
connectionId: payload.connectionId,
|
|
35
|
+
externalRepositoryId: payload.repository.externalRepositoryId
|
|
36
|
+
}, 'source repository updated: no project bound to source, dropping');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=on-source-repository-updated.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/subscribers/on-source-repository-updated.ts"],"sourcesContent":["import type {IntegrationSourceRepositoryUpdatedEvent} from '@shipfox/api-integration-core-dto';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport type {DomainEvent} from '@shipfox/node-outbox';\nimport {db} from '#db/db.js';\nimport {recordIntegrationEventForProject} from '#db/integration-event-dedup.js';\nimport {getProjectBySource, updateProjectSourceRepository} from '#db/projects.js';\n\nexport async function onSourceRepositoryUpdated(\n payload: IntegrationSourceRepositoryUpdatedEvent,\n event: DomainEvent<IntegrationSourceRepositoryUpdatedEvent>,\n): Promise<void> {\n const project = await getProjectBySource({\n workspaceId: payload.workspaceId,\n sourceConnectionId: payload.connectionId,\n sourceExternalRepositoryId: payload.repository.externalRepositoryId,\n });\n\n if (project) {\n const outcome = await db().transaction(async (tx) => {\n const {firstSeen} = await recordIntegrationEventForProject({\n tx,\n integrationEventId: event.id,\n projectId: project.id,\n });\n if (!firstSeen) return 'duplicate';\n\n const updated = await updateProjectSourceRepository({\n tx,\n workspaceId: payload.workspaceId,\n sourceConnectionId: payload.connectionId,\n sourceExternalRepositoryId: payload.repository.externalRepositoryId,\n sourceRepositoryOwner: payload.repository.owner,\n sourceRepositoryName: payload.repository.name,\n sourceDefaultBranch: payload.repository.defaultBranch,\n });\n return updated ? 'updated' : 'missing';\n });\n\n if (outcome !== 'missing') return;\n }\n\n logger().info(\n {\n eventId: event.id,\n connectionId: payload.connectionId,\n externalRepositoryId: payload.repository.externalRepositoryId,\n },\n 'source repository updated: no project bound to source, dropping',\n );\n}\n"],"names":["logger","db","recordIntegrationEventForProject","getProjectBySource","updateProjectSourceRepository","onSourceRepositoryUpdated","payload","event","project","workspaceId","sourceConnectionId","connectionId","sourceExternalRepositoryId","repository","externalRepositoryId","outcome","transaction","tx","firstSeen","integrationEventId","id","projectId","updated","sourceRepositoryOwner","owner","sourceRepositoryName","name","sourceDefaultBranch","defaultBranch","info","eventId"],"mappings":"AACA,SAAQA,MAAM,QAAO,8BAA8B;AAEnD,SAAQC,EAAE,QAAO,YAAY;AAC7B,SAAQC,gCAAgC,QAAO,iCAAiC;AAChF,SAAQC,kBAAkB,EAAEC,6BAA6B,QAAO,kBAAkB;AAElF,OAAO,eAAeC,0BACpBC,OAAgD,EAChDC,KAA2D;IAE3D,MAAMC,UAAU,MAAML,mBAAmB;QACvCM,aAAaH,QAAQG,WAAW;QAChCC,oBAAoBJ,QAAQK,YAAY;QACxCC,4BAA4BN,QAAQO,UAAU,CAACC,oBAAoB;IACrE;IAEA,IAAIN,SAAS;QACX,MAAMO,UAAU,MAAMd,KAAKe,WAAW,CAAC,OAAOC;YAC5C,MAAM,EAACC,SAAS,EAAC,GAAG,MAAMhB,iCAAiC;gBACzDe;gBACAE,oBAAoBZ,MAAMa,EAAE;gBAC5BC,WAAWb,QAAQY,EAAE;YACvB;YACA,IAAI,CAACF,WAAW,OAAO;YAEvB,MAAMI,UAAU,MAAMlB,8BAA8B;gBAClDa;gBACAR,aAAaH,QAAQG,WAAW;gBAChCC,oBAAoBJ,QAAQK,YAAY;gBACxCC,4BAA4BN,QAAQO,UAAU,CAACC,oBAAoB;gBACnES,uBAAuBjB,QAAQO,UAAU,CAACW,KAAK;gBAC/CC,sBAAsBnB,QAAQO,UAAU,CAACa,IAAI;gBAC7CC,qBAAqBrB,QAAQO,UAAU,CAACe,aAAa;YACvD;YACA,OAAON,UAAU,YAAY;QAC/B;QAEA,IAAIP,YAAY,WAAW;IAC7B;IAEAf,SAAS6B,IAAI,CACX;QACEC,SAASvB,MAAMa,EAAE;QACjBT,cAAcL,QAAQK,YAAY;QAClCG,sBAAsBR,QAAQO,UAAU,CAACC,oBAAoB;IAC/D,GACA;AAEJ"}
|