@shipfox/api-projects 9.3.0 → 10.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 +4 -4
- package/CHANGELOG.md +38 -0
- 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 +18 -0
- package/dist/db/projects.d.ts.map +1 -1
- package/dist/db/projects.js +45 -5
- package/dist/db/projects.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/presentation/dto/index.d.ts +1 -1
- package/dist/presentation/dto/index.d.ts.map +1 -1
- package/dist/presentation/dto/index.js +1 -1
- package/dist/presentation/dto/index.js.map +1 -1
- package/dist/presentation/dto/project.d.ts +9 -0
- package/dist/presentation/dto/project.d.ts.map +1 -1
- package/dist/presentation/dto/project.js +10 -0
- package/dist/presentation/dto/project.js.map +1 -1
- package/dist/presentation/inter-module.d.ts.map +1 -1
- package/dist/presentation/inter-module.js +7 -2
- package/dist/presentation/inter-module.js.map +1 -1
- package/dist/presentation/routes/admin-projects.d.ts +3 -0
- package/dist/presentation/routes/admin-projects.d.ts.map +1 -0
- package/dist/presentation/routes/admin-projects.js +61 -0
- package/dist/presentation/routes/admin-projects.js.map +1 -0
- package/dist/presentation/routes/index.d.ts +2 -1
- package/dist/presentation/routes/index.d.ts.map +1 -1
- package/dist/presentation/routes/index.js +8 -1
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +6 -5
- package/src/db/index.ts +5 -0
- package/src/db/projects.test.ts +9 -1
- package/src/db/projects.ts +73 -6
- package/src/index.ts +8 -2
- package/src/presentation/dto/index.ts +1 -1
- package/src/presentation/dto/project.ts +12 -0
- package/src/presentation/inter-module.ts +4 -1
- package/src/presentation/routes/admin-projects.ts +66 -0
- package/src/presentation/routes/index.ts +10 -1
- package/src/presentation/routes/projects.test.ts +173 -1
- package/src/presentation/subscribers/on-source-commit-pushed.test.ts +5 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
$ shipfox-swc && shipfox-temporal-bundle dist/temporal/workflows/index.js
|
|
2
|
-
Successfully compiled:
|
|
3
|
-
2026-07-
|
|
2
|
+
Successfully compiled: 37 files with swc (396.89ms)
|
|
3
|
+
2026-07-28T09:17:50.507Z [INFO] asset workflow-bundle-601f98c1048b285735c6.js 3.17 MiB [emitted] [immutable] (name: main)
|
|
4
4
|
orphan modules 33.5 KiB [orphan] 21 modules
|
|
5
5
|
runtime modules 1.13 KiB 5 modules
|
|
6
6
|
modules by path ../../../node_modules/.pnpm/ 970 KiB 196 modules
|
|
@@ -12,6 +12,6 @@ optional modules 30 bytes [optional]
|
|
|
12
12
|
__temporal_custom_payload_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
13
13
|
__temporal_custom_failure_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
14
14
|
../../shared/node/temporal/dist/workflow-error-interceptor.js 1.21 KiB [built] [code generated]
|
|
15
|
-
webpack 5.107.2 compiled successfully in
|
|
16
|
-
2026-07-
|
|
15
|
+
webpack 5.107.2 compiled successfully in 6246 ms
|
|
16
|
+
2026-07-28T09:17:50.533Z [INFO] Workflow bundle created { size: '3.17MB' }
|
|
17
17
|
/home/runner/work/shipfox/shipfox/libs/api/projects/dist/temporal/workflows/index.js: 3319553 bytes
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# @shipfox/api-projects
|
|
2
2
|
|
|
3
|
+
## 10.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 88ae689: Add a bounded, administrator-authorized project summary route with redacted fields and cursor pagination.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [88ae689]
|
|
12
|
+
- Updated dependencies [fb34b6a]
|
|
13
|
+
- @shipfox/api-projects-dto@10.1.0
|
|
14
|
+
- @shipfox/api-auth-dto@10.1.0
|
|
15
|
+
- @shipfox/api-auth-context@10.1.0
|
|
16
|
+
|
|
17
|
+
## 10.0.0
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- e9280fc: Add an observer-authorized administrator workspace lookup with bounded safe summaries,
|
|
22
|
+
best-effort job counts, and a neutral unavailable-workspace member experience for
|
|
23
|
+
suspended or deleted workspaces.
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [74f9e31]
|
|
28
|
+
- Updated dependencies [e9280fc]
|
|
29
|
+
- @shipfox/node-fastify@0.4.0
|
|
30
|
+
- @shipfox/api-projects-dto@10.0.0
|
|
31
|
+
- @shipfox/api-auth-context@10.0.0
|
|
32
|
+
- @shipfox/node-module@1.0.4
|
|
33
|
+
- @shipfox/api-integration-core-dto@9.0.2
|
|
34
|
+
- @shipfox/inter-module@0.2.2
|
|
35
|
+
- @shipfox/node-drizzle@0.3.4
|
|
36
|
+
- @shipfox/node-opentelemetry@0.6.3
|
|
37
|
+
- @shipfox/node-outbox@0.2.6
|
|
38
|
+
- @shipfox/node-postgres@0.4.4
|
|
39
|
+
- @shipfox/node-temporal@0.4.4
|
|
40
|
+
|
|
3
41
|
## 9.3.0
|
|
4
42
|
|
|
5
43
|
### Patch Changes
|
package/dist/db/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { closeDb, db, schema } from './db.js';
|
|
2
2
|
export { pruneIntegrationEventDedup, recordIntegrationEventForProject, } from './integration-event-dedup.js';
|
|
3
|
-
export type { CreateProjectParams, GetProjectBySourceParams, ListProjectsParams, ListProjectsResult, } from './projects.js';
|
|
4
|
-
export { createProject, getProjectById, getProjectBySource, getProjectCount, listProjects, requireProjectForWorkspace, } from './projects.js';
|
|
3
|
+
export type { AdminProjectSummary, CreateProjectParams, GetProjectBySourceParams, ListAdminProjectsParams, ListAdminProjectsResult, ListProjectsParams, ListProjectsResult, } from './projects.js';
|
|
4
|
+
export { createProject, getProjectById, getProjectBySource, getProjectCount, getWorkspaceProjectCounts, listAdminProjects, listProjects, requireProjectForWorkspace, } from './projects.js';
|
|
5
5
|
export { projectsIntegrationEventDedup } from './schema/integration-event-dedup.js';
|
|
6
6
|
export { projectsOutbox } from './schema/outbox.js';
|
|
7
7
|
export declare const migrationsPath: string;
|
package/dist/db/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAC5C,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,GACjC,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,6BAA6B,EAAC,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAElD,eAAO,MAAM,cAAc,QAAoE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAC5C,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,GACjC,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EACzB,iBAAiB,EACjB,YAAY,EACZ,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,6BAA6B,EAAC,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAElD,eAAO,MAAM,cAAc,QAAoE,CAAC"}
|
package/dist/db/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { dirname, resolve } from 'node:path';
|
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
export { closeDb, db, schema } from './db.js';
|
|
4
4
|
export { pruneIntegrationEventDedup, recordIntegrationEventForProject } from './integration-event-dedup.js';
|
|
5
|
-
export { createProject, getProjectById, getProjectBySource, getProjectCount, listProjects, requireProjectForWorkspace } from './projects.js';
|
|
5
|
+
export { createProject, getProjectById, getProjectBySource, getProjectCount, getWorkspaceProjectCounts, listAdminProjects, listProjects, requireProjectForWorkspace } from './projects.js';
|
|
6
6
|
export { projectsIntegrationEventDedup } from './schema/integration-event-dedup.js';
|
|
7
7
|
export { projectsOutbox } from './schema/outbox.js';
|
|
8
8
|
export const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');
|
package/dist/db/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\nexport {closeDb, db, schema} from './db.js';\nexport {\n pruneIntegrationEventDedup,\n recordIntegrationEventForProject,\n} from './integration-event-dedup.js';\nexport type {\n CreateProjectParams,\n GetProjectBySourceParams,\n ListProjectsParams,\n ListProjectsResult,\n} from './projects.js';\nexport {\n createProject,\n getProjectById,\n getProjectBySource,\n getProjectCount,\n listProjects,\n requireProjectForWorkspace,\n} from './projects.js';\nexport {projectsIntegrationEventDedup} from './schema/integration-event-dedup.js';\nexport {projectsOutbox} from './schema/outbox.js';\n\nexport const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');\n"],"names":["dirname","resolve","fileURLToPath","closeDb","db","schema","pruneIntegrationEventDedup","recordIntegrationEventForProject","createProject","getProjectById","getProjectBySource","getProjectCount","listProjects","requireProjectForWorkspace","projectsIntegrationEventDedup","projectsOutbox","migrationsPath","url"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAEvC,SAAQC,OAAO,EAAEC,EAAE,EAAEC,MAAM,QAAO,UAAU;AAC5C,SACEC,0BAA0B,EAC1BC,gCAAgC,QAC3B,+BAA+B;
|
|
1
|
+
{"version":3,"sources":["../../src/db/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\nexport {closeDb, db, schema} from './db.js';\nexport {\n pruneIntegrationEventDedup,\n recordIntegrationEventForProject,\n} from './integration-event-dedup.js';\nexport type {\n AdminProjectSummary,\n CreateProjectParams,\n GetProjectBySourceParams,\n ListAdminProjectsParams,\n ListAdminProjectsResult,\n ListProjectsParams,\n ListProjectsResult,\n} from './projects.js';\nexport {\n createProject,\n getProjectById,\n getProjectBySource,\n getProjectCount,\n getWorkspaceProjectCounts,\n listAdminProjects,\n listProjects,\n requireProjectForWorkspace,\n} from './projects.js';\nexport {projectsIntegrationEventDedup} from './schema/integration-event-dedup.js';\nexport {projectsOutbox} from './schema/outbox.js';\n\nexport const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');\n"],"names":["dirname","resolve","fileURLToPath","closeDb","db","schema","pruneIntegrationEventDedup","recordIntegrationEventForProject","createProject","getProjectById","getProjectBySource","getProjectCount","getWorkspaceProjectCounts","listAdminProjects","listProjects","requireProjectForWorkspace","projectsIntegrationEventDedup","projectsOutbox","migrationsPath","url"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAEvC,SAAQC,OAAO,EAAEC,EAAE,EAAEC,MAAM,QAAO,UAAU;AAC5C,SACEC,0BAA0B,EAC1BC,gCAAgC,QAC3B,+BAA+B;AAUtC,SACEC,aAAa,EACbC,cAAc,EACdC,kBAAkB,EAClBC,eAAe,EACfC,yBAAyB,EACzBC,iBAAiB,EACjBC,YAAY,EACZC,0BAA0B,QACrB,gBAAgB;AACvB,SAAQC,6BAA6B,QAAO,sCAAsC;AAClF,SAAQC,cAAc,QAAO,qBAAqB;AAElD,OAAO,MAAMC,iBAAiBjB,QAAQD,QAAQE,cAAc,YAAYiB,GAAG,IAAI,iBAAiB"}
|
package/dist/db/projects.d.ts
CHANGED
|
@@ -19,6 +19,17 @@ export interface ListProjectsResult {
|
|
|
19
19
|
projects: Project[];
|
|
20
20
|
nextCursor: ProjectCursor | null;
|
|
21
21
|
}
|
|
22
|
+
export type AdminProjectSummary = Pick<Project, 'id' | 'workspaceId' | 'name' | 'createdAt' | 'updatedAt'>;
|
|
23
|
+
export interface ListAdminProjectsParams {
|
|
24
|
+
limit: number;
|
|
25
|
+
cursor?: ProjectCursor | undefined;
|
|
26
|
+
projectId?: string | undefined;
|
|
27
|
+
search?: string | undefined;
|
|
28
|
+
}
|
|
29
|
+
export interface ListAdminProjectsResult {
|
|
30
|
+
projects: AdminProjectSummary[];
|
|
31
|
+
nextCursor: ProjectCursor | null;
|
|
32
|
+
}
|
|
22
33
|
export declare function createProject(params: CreateProjectParams): Promise<Project>;
|
|
23
34
|
export declare function getProjectById(id: string): Promise<Project | undefined>;
|
|
24
35
|
export interface GetProjectBySourceParams {
|
|
@@ -32,5 +43,12 @@ export declare function requireProjectForWorkspace(params: {
|
|
|
32
43
|
workspaceId: string;
|
|
33
44
|
}): Promise<Project>;
|
|
34
45
|
export declare function listProjects(params: ListProjectsParams): Promise<ListProjectsResult>;
|
|
46
|
+
export declare function listAdminProjects(params: ListAdminProjectsParams): Promise<ListAdminProjectsResult>;
|
|
35
47
|
export declare function getProjectCount(): Promise<number>;
|
|
48
|
+
export declare function getWorkspaceProjectCounts(params: {
|
|
49
|
+
workspaceIds: string[];
|
|
50
|
+
}): Promise<Array<{
|
|
51
|
+
workspaceId: string;
|
|
52
|
+
count: number;
|
|
53
|
+
}>>;
|
|
36
54
|
//# sourceMappingURL=projects.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/db/projects.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,2BAA2B,CAAC;AAMvD,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0BAA0B,EAAE,MAAM,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAMD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,EAAE,aAAa,GAAG,IAAI,CAAC;CAClC;AAUD,wBAAsB,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAwCjF;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAM7E;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0BAA0B,EAAE,MAAM,CAAC;CACpC;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAgB9B;AAED,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,OAAO,CAAC,CAKnB;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAuB1F;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAGvD"}
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/db/projects.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,2BAA2B,CAAC;AAMvD,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0BAA0B,EAAE,MAAM,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAMD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,EAAE,aAAa,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACpC,OAAO,EACP,IAAI,GAAG,aAAa,GAAG,MAAM,GAAG,WAAW,GAAG,WAAW,CAC1D,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,UAAU,EAAE,aAAa,GAAG,IAAI,CAAC;CAClC;AAUD,wBAAsB,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAwCjF;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAM7E;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0BAA0B,EAAE,MAAM,CAAC;CACpC;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAgB9B;AAED,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,OAAO,CAAC,CAKnB;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAuB1F;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,uBAAuB,CAAC,CA8BlC;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAGvD;AAED,wBAAsB,yBAAyB,CAAC,MAAM,EAAE;IACtD,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,GAAG,OAAO,CAAC,KAAK,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,CAYvD"}
|
package/dist/db/projects.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { and, count, desc, eq, ilike, lt, or } from 'drizzle-orm';
|
|
1
|
+
import { and, count, desc, eq, ilike, inArray, lt, or } from 'drizzle-orm';
|
|
2
2
|
import { ProjectAlreadyExistsError, ProjectNotFoundError } from '#core/errors.js';
|
|
3
3
|
import { recordProjectCreated } from '#metrics/instance.js';
|
|
4
4
|
import { db } from './db.js';
|
|
@@ -6,9 +6,9 @@ import { projects, toProject } from './schema/projects.js';
|
|
|
6
6
|
function escapeIlikePattern(value) {
|
|
7
7
|
return value.replace(/[\\%_]/g, (char)=>`\\${char}`);
|
|
8
8
|
}
|
|
9
|
-
function cursorWhere(
|
|
10
|
-
if (!
|
|
11
|
-
return or(lt(projects.createdAt,
|
|
9
|
+
function cursorWhere(cursor) {
|
|
10
|
+
if (!cursor) return undefined;
|
|
11
|
+
return or(lt(projects.createdAt, cursor.createdAt), and(eq(projects.createdAt, cursor.createdAt), lt(projects.id, cursor.id)));
|
|
12
12
|
}
|
|
13
13
|
export async function createProject(params) {
|
|
14
14
|
const project = await db().transaction(async (tx)=>{
|
|
@@ -57,7 +57,7 @@ export async function listProjects(params) {
|
|
|
57
57
|
const conditions = [
|
|
58
58
|
eq(projects.workspaceId, params.workspaceId)
|
|
59
59
|
];
|
|
60
|
-
const cursorCondition = cursorWhere(params);
|
|
60
|
+
const cursorCondition = cursorWhere(params.cursor);
|
|
61
61
|
if (cursorCondition) conditions.push(cursorCondition);
|
|
62
62
|
if (params.search) {
|
|
63
63
|
conditions.push(ilike(projects.name, `%${escapeIlikePattern(params.search)}%`));
|
|
@@ -74,11 +74,51 @@ export async function listProjects(params) {
|
|
|
74
74
|
} : null
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
+
export async function listAdminProjects(params) {
|
|
78
|
+
const conditions = [];
|
|
79
|
+
const cursorCondition = cursorWhere(params.cursor);
|
|
80
|
+
if (cursorCondition) conditions.push(cursorCondition);
|
|
81
|
+
if (params.projectId) conditions.push(eq(projects.id, params.projectId));
|
|
82
|
+
if (params.search) {
|
|
83
|
+
conditions.push(ilike(projects.name, `%${escapeIlikePattern(params.search)}%`));
|
|
84
|
+
}
|
|
85
|
+
const rows = await db().select({
|
|
86
|
+
id: projects.id,
|
|
87
|
+
workspaceId: projects.workspaceId,
|
|
88
|
+
name: projects.name,
|
|
89
|
+
createdAt: projects.createdAt,
|
|
90
|
+
updatedAt: projects.updatedAt
|
|
91
|
+
}).from(projects).where(conditions.length > 0 ? and(...conditions) : undefined).orderBy(desc(projects.createdAt), desc(projects.id)).limit(params.limit + 1);
|
|
92
|
+
const hasMore = rows.length > params.limit;
|
|
93
|
+
const pageRows = hasMore ? rows.slice(0, params.limit) : rows;
|
|
94
|
+
const last = pageRows.at(-1);
|
|
95
|
+
return {
|
|
96
|
+
projects: pageRows,
|
|
97
|
+
nextCursor: hasMore && last ? {
|
|
98
|
+
createdAt: last.createdAt,
|
|
99
|
+
id: last.id
|
|
100
|
+
} : null
|
|
101
|
+
};
|
|
102
|
+
}
|
|
77
103
|
export async function getProjectCount() {
|
|
78
104
|
const [row] = await db().select({
|
|
79
105
|
value: count()
|
|
80
106
|
}).from(projects);
|
|
81
107
|
return row?.value ?? 0;
|
|
82
108
|
}
|
|
109
|
+
export async function getWorkspaceProjectCounts(params) {
|
|
110
|
+
const rows = await db().select({
|
|
111
|
+
workspaceId: projects.workspaceId,
|
|
112
|
+
count: count()
|
|
113
|
+
}).from(projects).where(inArray(projects.workspaceId, params.workspaceIds)).groupBy(projects.workspaceId);
|
|
114
|
+
const countsByWorkspace = new Map(rows.map((row)=>[
|
|
115
|
+
row.workspaceId,
|
|
116
|
+
Number(row.count)
|
|
117
|
+
]));
|
|
118
|
+
return params.workspaceIds.map((workspaceId)=>({
|
|
119
|
+
workspaceId,
|
|
120
|
+
count: countsByWorkspace.get(workspaceId) ?? 0
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
83
123
|
|
|
84
124
|
//# sourceMappingURL=projects.js.map
|
package/dist/db/projects.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/projects.ts"],"sourcesContent":["import {and, count, desc, eq, ilike, lt, or, type SQL} from 'drizzle-orm';\nimport type {Project} from '#core/entities/project.js';\nimport {ProjectAlreadyExistsError, ProjectNotFoundError} from '#core/errors.js';\nimport {recordProjectCreated} from '#metrics/instance.js';\nimport {db} from './db.js';\nimport {projects, toProject} from './schema/projects.js';\n\nexport interface CreateProjectParams {\n workspaceId: string;\n sourceConnectionId: string;\n sourceExternalRepositoryId: string;\n name: string;\n}\n\nexport interface ProjectCursor {\n createdAt: Date;\n id: string;\n}\n\nexport interface ListProjectsParams {\n workspaceId: string;\n limit: number;\n cursor?: ProjectCursor | undefined;\n search?: string | undefined;\n}\n\nfunction escapeIlikePattern(value: string): string {\n return value.replace(/[\\\\%_]/g, (char) => `\\\\${char}`);\n}\n\nexport interface ListProjectsResult {\n projects: Project[];\n nextCursor: ProjectCursor | null;\n}\n\nfunction cursorWhere(params: ListProjectsParams): SQL | undefined {\n if (!params.cursor) return undefined;\n return or(\n lt(projects.createdAt, params.cursor.createdAt),\n and(eq(projects.createdAt, params.cursor.createdAt), lt(projects.id, params.cursor.id)),\n );\n}\n\nexport async function createProject(params: CreateProjectParams): Promise<Project> {\n const project = await db().transaction(async (tx) => {\n const [projectRow] = await tx\n .insert(projects)\n .values({\n workspaceId: params.workspaceId,\n sourceConnectionId: params.sourceConnectionId,\n sourceExternalRepositoryId: params.sourceExternalRepositoryId,\n name: params.name,\n })\n .onConflictDoNothing({\n target: [projects.sourceConnectionId, projects.sourceExternalRepositoryId],\n })\n .returning();\n\n if (!projectRow) {\n const [conflict] = await tx\n .select()\n .from(projects)\n .where(\n and(\n eq(projects.sourceConnectionId, params.sourceConnectionId),\n eq(projects.sourceExternalRepositoryId, params.sourceExternalRepositoryId),\n ),\n )\n .limit(1);\n if (conflict) {\n throw new ProjectAlreadyExistsError(\n conflict.id,\n params.sourceConnectionId,\n params.sourceExternalRepositoryId,\n );\n }\n throw new Error('Insert returned no rows');\n }\n\n return toProject(projectRow);\n });\n recordProjectCreated();\n return project;\n}\n\nexport async function getProjectById(id: string): Promise<Project | undefined> {\n const rows = await db().select().from(projects).where(eq(projects.id, id)).limit(1);\n\n const row = rows[0];\n if (!row) return undefined;\n return toProject(row);\n}\n\nexport interface GetProjectBySourceParams {\n workspaceId: string;\n sourceConnectionId: string;\n sourceExternalRepositoryId: string;\n}\n\nexport async function getProjectBySource(\n params: GetProjectBySourceParams,\n): Promise<Project | undefined> {\n const rows = await db()\n .select()\n .from(projects)\n .where(\n and(\n eq(projects.workspaceId, params.workspaceId),\n eq(projects.sourceConnectionId, params.sourceConnectionId),\n eq(projects.sourceExternalRepositoryId, params.sourceExternalRepositoryId),\n ),\n )\n .limit(1);\n\n const row = rows[0];\n if (!row) return undefined;\n return toProject(row);\n}\n\nexport async function requireProjectForWorkspace(params: {\n projectId: string;\n workspaceId: string;\n}): Promise<Project> {\n const project = await getProjectById(params.projectId);\n if (!project) throw new ProjectNotFoundError(params.projectId);\n if (project.workspaceId !== params.workspaceId) throw new ProjectNotFoundError(params.projectId);\n return project;\n}\n\nexport async function listProjects(params: ListProjectsParams): Promise<ListProjectsResult> {\n const conditions = [eq(projects.workspaceId, params.workspaceId)];\n const cursorCondition = cursorWhere(params);\n if (cursorCondition) conditions.push(cursorCondition);\n if (params.search) {\n conditions.push(ilike(projects.name, `%${escapeIlikePattern(params.search)}%`));\n }\n\n const rows = await db()\n .select()\n .from(projects)\n .where(and(...conditions))\n .orderBy(desc(projects.createdAt), desc(projects.id))\n .limit(params.limit + 1);\n\n const hasMore = rows.length > params.limit;\n const pageRows = hasMore ? rows.slice(0, params.limit) : rows;\n const last = pageRows.at(-1);\n\n return {\n projects: pageRows.map(toProject),\n nextCursor: hasMore && last ? {createdAt: last.createdAt, id: last.id} : null,\n };\n}\n\nexport async function getProjectCount(): Promise<number> {\n const [row] = await db().select({value: count()}).from(projects);\n return row?.value ?? 0;\n}\n"],"names":["and","count","desc","eq","ilike","lt","or","ProjectAlreadyExistsError","ProjectNotFoundError","recordProjectCreated","db","projects","toProject","escapeIlikePattern","value","replace","char","cursorWhere","params","cursor","undefined","createdAt","id","createProject","project","transaction","tx","projectRow","insert","values","workspaceId","sourceConnectionId","sourceExternalRepositoryId","name","onConflictDoNothing","target","returning","conflict","select","from","where","limit","Error","getProjectById","rows","row","getProjectBySource","requireProjectForWorkspace","projectId","listProjects","conditions","cursorCondition","push","search","orderBy","hasMore","length","pageRows","slice","last","at","map","nextCursor","getProjectCount"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/db/projects.ts"],"sourcesContent":["import {and, count, desc, eq, ilike, inArray, lt, or, type SQL} from 'drizzle-orm';\nimport type {Project} from '#core/entities/project.js';\nimport {ProjectAlreadyExistsError, ProjectNotFoundError} from '#core/errors.js';\nimport {recordProjectCreated} from '#metrics/instance.js';\nimport {db} from './db.js';\nimport {projects, toProject} from './schema/projects.js';\n\nexport interface CreateProjectParams {\n workspaceId: string;\n sourceConnectionId: string;\n sourceExternalRepositoryId: string;\n name: string;\n}\n\nexport interface ProjectCursor {\n createdAt: Date;\n id: string;\n}\n\nexport interface ListProjectsParams {\n workspaceId: string;\n limit: number;\n cursor?: ProjectCursor | undefined;\n search?: string | undefined;\n}\n\nfunction escapeIlikePattern(value: string): string {\n return value.replace(/[\\\\%_]/g, (char) => `\\\\${char}`);\n}\n\nexport interface ListProjectsResult {\n projects: Project[];\n nextCursor: ProjectCursor | null;\n}\n\nexport type AdminProjectSummary = Pick<\n Project,\n 'id' | 'workspaceId' | 'name' | 'createdAt' | 'updatedAt'\n>;\n\nexport interface ListAdminProjectsParams {\n limit: number;\n cursor?: ProjectCursor | undefined;\n projectId?: string | undefined;\n search?: string | undefined;\n}\n\nexport interface ListAdminProjectsResult {\n projects: AdminProjectSummary[];\n nextCursor: ProjectCursor | null;\n}\n\nfunction cursorWhere(cursor: ProjectCursor | undefined): SQL | undefined {\n if (!cursor) return undefined;\n return or(\n lt(projects.createdAt, cursor.createdAt),\n and(eq(projects.createdAt, cursor.createdAt), lt(projects.id, cursor.id)),\n );\n}\n\nexport async function createProject(params: CreateProjectParams): Promise<Project> {\n const project = await db().transaction(async (tx) => {\n const [projectRow] = await tx\n .insert(projects)\n .values({\n workspaceId: params.workspaceId,\n sourceConnectionId: params.sourceConnectionId,\n sourceExternalRepositoryId: params.sourceExternalRepositoryId,\n name: params.name,\n })\n .onConflictDoNothing({\n target: [projects.sourceConnectionId, projects.sourceExternalRepositoryId],\n })\n .returning();\n\n if (!projectRow) {\n const [conflict] = await tx\n .select()\n .from(projects)\n .where(\n and(\n eq(projects.sourceConnectionId, params.sourceConnectionId),\n eq(projects.sourceExternalRepositoryId, params.sourceExternalRepositoryId),\n ),\n )\n .limit(1);\n if (conflict) {\n throw new ProjectAlreadyExistsError(\n conflict.id,\n params.sourceConnectionId,\n params.sourceExternalRepositoryId,\n );\n }\n throw new Error('Insert returned no rows');\n }\n\n return toProject(projectRow);\n });\n recordProjectCreated();\n return project;\n}\n\nexport async function getProjectById(id: string): Promise<Project | undefined> {\n const rows = await db().select().from(projects).where(eq(projects.id, id)).limit(1);\n\n const row = rows[0];\n if (!row) return undefined;\n return toProject(row);\n}\n\nexport interface GetProjectBySourceParams {\n workspaceId: string;\n sourceConnectionId: string;\n sourceExternalRepositoryId: string;\n}\n\nexport async function getProjectBySource(\n params: GetProjectBySourceParams,\n): Promise<Project | undefined> {\n const rows = await db()\n .select()\n .from(projects)\n .where(\n and(\n eq(projects.workspaceId, params.workspaceId),\n eq(projects.sourceConnectionId, params.sourceConnectionId),\n eq(projects.sourceExternalRepositoryId, params.sourceExternalRepositoryId),\n ),\n )\n .limit(1);\n\n const row = rows[0];\n if (!row) return undefined;\n return toProject(row);\n}\n\nexport async function requireProjectForWorkspace(params: {\n projectId: string;\n workspaceId: string;\n}): Promise<Project> {\n const project = await getProjectById(params.projectId);\n if (!project) throw new ProjectNotFoundError(params.projectId);\n if (project.workspaceId !== params.workspaceId) throw new ProjectNotFoundError(params.projectId);\n return project;\n}\n\nexport async function listProjects(params: ListProjectsParams): Promise<ListProjectsResult> {\n const conditions = [eq(projects.workspaceId, params.workspaceId)];\n const cursorCondition = cursorWhere(params.cursor);\n if (cursorCondition) conditions.push(cursorCondition);\n if (params.search) {\n conditions.push(ilike(projects.name, `%${escapeIlikePattern(params.search)}%`));\n }\n\n const rows = await db()\n .select()\n .from(projects)\n .where(and(...conditions))\n .orderBy(desc(projects.createdAt), desc(projects.id))\n .limit(params.limit + 1);\n\n const hasMore = rows.length > params.limit;\n const pageRows = hasMore ? rows.slice(0, params.limit) : rows;\n const last = pageRows.at(-1);\n\n return {\n projects: pageRows.map(toProject),\n nextCursor: hasMore && last ? {createdAt: last.createdAt, id: last.id} : null,\n };\n}\n\nexport async function listAdminProjects(\n params: ListAdminProjectsParams,\n): Promise<ListAdminProjectsResult> {\n const conditions: SQL[] = [];\n const cursorCondition = cursorWhere(params.cursor);\n if (cursorCondition) conditions.push(cursorCondition);\n if (params.projectId) conditions.push(eq(projects.id, params.projectId));\n if (params.search) {\n conditions.push(ilike(projects.name, `%${escapeIlikePattern(params.search)}%`));\n }\n\n const rows = await db()\n .select({\n id: projects.id,\n workspaceId: projects.workspaceId,\n name: projects.name,\n createdAt: projects.createdAt,\n updatedAt: projects.updatedAt,\n })\n .from(projects)\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .orderBy(desc(projects.createdAt), desc(projects.id))\n .limit(params.limit + 1);\n\n const hasMore = rows.length > params.limit;\n const pageRows = hasMore ? rows.slice(0, params.limit) : rows;\n const last = pageRows.at(-1);\n\n return {\n projects: pageRows,\n nextCursor: hasMore && last ? {createdAt: last.createdAt, id: last.id} : null,\n };\n}\n\nexport async function getProjectCount(): Promise<number> {\n const [row] = await db().select({value: count()}).from(projects);\n return row?.value ?? 0;\n}\n\nexport async function getWorkspaceProjectCounts(params: {\n workspaceIds: string[];\n}): Promise<Array<{workspaceId: string; count: number}>> {\n const rows = await db()\n .select({workspaceId: projects.workspaceId, count: count()})\n .from(projects)\n .where(inArray(projects.workspaceId, params.workspaceIds))\n .groupBy(projects.workspaceId);\n\n const countsByWorkspace = new Map(rows.map((row) => [row.workspaceId, Number(row.count)]));\n return params.workspaceIds.map((workspaceId) => ({\n workspaceId,\n count: countsByWorkspace.get(workspaceId) ?? 0,\n }));\n}\n"],"names":["and","count","desc","eq","ilike","inArray","lt","or","ProjectAlreadyExistsError","ProjectNotFoundError","recordProjectCreated","db","projects","toProject","escapeIlikePattern","value","replace","char","cursorWhere","cursor","undefined","createdAt","id","createProject","params","project","transaction","tx","projectRow","insert","values","workspaceId","sourceConnectionId","sourceExternalRepositoryId","name","onConflictDoNothing","target","returning","conflict","select","from","where","limit","Error","getProjectById","rows","row","getProjectBySource","requireProjectForWorkspace","projectId","listProjects","conditions","cursorCondition","push","search","orderBy","hasMore","length","pageRows","slice","last","at","map","nextCursor","listAdminProjects","updatedAt","getProjectCount","getWorkspaceProjectCounts","workspaceIds","groupBy","countsByWorkspace","Map","Number","get"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import type { AuthInterModuleClient } from '@shipfox/api-auth-dto/inter-module';
|
|
1
2
|
import type { IntegrationsModuleClient } from '@shipfox/api-integration-core-dto/inter-module';
|
|
2
3
|
import { type ShipfoxModule } from '@shipfox/node-module';
|
|
3
4
|
export type { Project } from '#core/index.js';
|
|
4
5
|
export { createProjectFromSource, ProjectAccessDeniedError, ProjectAlreadyExistsError, ProjectNotFoundError, } from '#core/index.js';
|
|
5
6
|
export type { GetProjectBySourceParams } from '#db/index.js';
|
|
6
|
-
export { createProject, db, getProjectById, getProjectBySource, listProjects, migrationsPath, projectsOutbox, requireProjectForWorkspace, } from '#db/index.js';
|
|
7
|
+
export { createProject, db, getProjectById, getProjectBySource, getWorkspaceProjectCounts, listProjects, migrationsPath, projectsOutbox, requireProjectForWorkspace, } from '#db/index.js';
|
|
7
8
|
export { createProjectRoutes, requireProjectAccess } from '#presentation/index.js';
|
|
8
9
|
export interface CreateProjectsModuleOptions {
|
|
9
10
|
integrations: IntegrationsModuleClient;
|
|
11
|
+
auth: AuthInterModuleClient;
|
|
10
12
|
}
|
|
11
|
-
export declare function createProjectsModule({ integrations }: CreateProjectsModuleOptions): ShipfoxModule;
|
|
13
|
+
export declare function createProjectsModule({ integrations, auth, }: CreateProjectsModuleOptions): ShipfoxModule;
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,oCAAoC,CAAC;AAK9E,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,gDAAgD,CAAC;AAE7F,OAAO,EAAC,KAAK,aAAa,EAAoB,MAAM,sBAAsB,CAAC;AAe3E,YAAY,EAAC,OAAO,EAAC,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAC,wBAAwB,EAAC,MAAM,cAAc,CAAC;AAC3D,OAAO,EACL,aAAa,EACb,EAAE,EACF,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EACzB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAC,mBAAmB,EAAE,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAEjF,MAAM,WAAW,2BAA2B;IAC1C,YAAY,EAAE,wBAAwB,CAAC;IACvC,IAAI,EAAE,qBAAqB,CAAC;CAC7B;AAED,wBAAgB,oBAAoB,CAAC,EACnC,YAAY,EACZ,IAAI,GACL,EAAE,2BAA2B,GAAG,aAAa,CAyB7C"}
|
package/dist/index.js
CHANGED
|
@@ -15,9 +15,9 @@ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
|
15
15
|
const maintenanceWorkflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');
|
|
16
16
|
const subscriber = subscriberFactory();
|
|
17
17
|
export { createProjectFromSource, ProjectAccessDeniedError, ProjectAlreadyExistsError, ProjectNotFoundError } from '#core/index.js';
|
|
18
|
-
export { createProject, db, getProjectById, getProjectBySource, listProjects, migrationsPath, projectsOutbox, requireProjectForWorkspace } from '#db/index.js';
|
|
18
|
+
export { createProject, db, getProjectById, getProjectBySource, getWorkspaceProjectCounts, listProjects, migrationsPath, projectsOutbox, requireProjectForWorkspace } from '#db/index.js';
|
|
19
19
|
export { createProjectRoutes, requireProjectAccess } from '#presentation/index.js';
|
|
20
|
-
export function createProjectsModule({ integrations }) {
|
|
20
|
+
export function createProjectsModule({ integrations, auth }) {
|
|
21
21
|
return {
|
|
22
22
|
name: 'projects',
|
|
23
23
|
database: {
|
|
@@ -25,7 +25,7 @@ export function createProjectsModule({ integrations }) {
|
|
|
25
25
|
migrationsPath,
|
|
26
26
|
databaseNamespace: 'projects'
|
|
27
27
|
},
|
|
28
|
-
routes: createProjectRoutes(integrations),
|
|
28
|
+
routes: createProjectRoutes(integrations, auth),
|
|
29
29
|
e2eRoutes: [
|
|
30
30
|
projectsE2eRoutes
|
|
31
31
|
],
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport {\n INTEGRATION_SOURCE_COMMIT_PUSHED,\n type IntegrationsEventMap,\n} from '@shipfox/api-integration-core-dto';\nimport type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport {projectsEventSchemas} from '@shipfox/api-projects-dto';\nimport {type ShipfoxModule, subscriberFactory} from '@shipfox/node-module';\nimport {db, migrationsPath, projectsOutbox} from '#db/index.js';\nimport {registerProjectsServiceMetrics} from '#metrics/index.js';\nimport {projectsE2eRoutes} from '#presentation/e2eRoutes/index.js';\nimport {createProjectRoutes} from '#presentation/index.js';\nimport {createProjectsInterModulePresentation} from '#presentation/inter-module.js';\nimport {onSourceCommitPushed} from '#presentation/subscribers/index.js';\nimport {createProjectsMaintenanceActivities} from '#temporal/activities/index.js';\nimport {PROJECTS_MAINTENANCE_TASK_QUEUE} from '#temporal/constants.js';\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\nconst maintenanceWorkflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');\n\nconst subscriber = subscriberFactory<IntegrationsEventMap>();\n\nexport type {Project} from '#core/index.js';\nexport {\n createProjectFromSource,\n ProjectAccessDeniedError,\n ProjectAlreadyExistsError,\n ProjectNotFoundError,\n} from '#core/index.js';\nexport type {GetProjectBySourceParams} from '#db/index.js';\nexport {\n createProject,\n db,\n getProjectById,\n getProjectBySource,\n listProjects,\n migrationsPath,\n projectsOutbox,\n requireProjectForWorkspace,\n} from '#db/index.js';\nexport {createProjectRoutes, requireProjectAccess} from '#presentation/index.js';\n\nexport interface CreateProjectsModuleOptions {\n integrations: IntegrationsModuleClient;\n}\n\nexport function createProjectsModule({integrations}: CreateProjectsModuleOptions): ShipfoxModule {\n return {\n name: 'projects',\n database: {db, migrationsPath, databaseNamespace: 'projects'},\n routes: createProjectRoutes(integrations),\n e2eRoutes: [projectsE2eRoutes],\n metrics: registerProjectsServiceMetrics,\n publishers: [{name: 'projects', table: projectsOutbox, db, eventSchemas: projectsEventSchemas}],\n interModulePresentations: [createProjectsInterModulePresentation()],\n subscribers: [subscriber(INTEGRATION_SOURCE_COMMIT_PUSHED, onSourceCommitPushed)],\n workers: [\n {\n taskQueue: PROJECTS_MAINTENANCE_TASK_QUEUE,\n workflowsPath: maintenanceWorkflowsPath,\n activities: createProjectsMaintenanceActivities,\n workflows: [\n {\n name: 'pruneIntegrationEventDedupCron',\n id: 'projects-prune-integration-event-dedup',\n cronSchedule: '0 3 * * *',\n },\n ],\n },\n ],\n };\n}\n"],"names":["dirname","resolve","fileURLToPath","INTEGRATION_SOURCE_COMMIT_PUSHED","projectsEventSchemas","subscriberFactory","db","migrationsPath","projectsOutbox","registerProjectsServiceMetrics","projectsE2eRoutes","createProjectRoutes","createProjectsInterModulePresentation","onSourceCommitPushed","createProjectsMaintenanceActivities","PROJECTS_MAINTENANCE_TASK_QUEUE","packageRoot","url","maintenanceWorkflowsPath","subscriber","createProjectFromSource","ProjectAccessDeniedError","ProjectAlreadyExistsError","ProjectNotFoundError","createProject","getProjectById","getProjectBySource","listProjects","requireProjectForWorkspace","requireProjectAccess","createProjectsModule","integrations","name","database","databaseNamespace","routes","e2eRoutes","metrics","publishers","table","eventSchemas","interModulePresentations","subscribers","workers","taskQueue","workflowsPath","activities","workflows","id","cronSchedule"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport type {AuthInterModuleClient} from '@shipfox/api-auth-dto/inter-module';\nimport {\n INTEGRATION_SOURCE_COMMIT_PUSHED,\n type IntegrationsEventMap,\n} from '@shipfox/api-integration-core-dto';\nimport type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport {projectsEventSchemas} from '@shipfox/api-projects-dto';\nimport {type ShipfoxModule, subscriberFactory} from '@shipfox/node-module';\nimport {db, migrationsPath, projectsOutbox} from '#db/index.js';\nimport {registerProjectsServiceMetrics} from '#metrics/index.js';\nimport {projectsE2eRoutes} from '#presentation/e2eRoutes/index.js';\nimport {createProjectRoutes} from '#presentation/index.js';\nimport {createProjectsInterModulePresentation} from '#presentation/inter-module.js';\nimport {onSourceCommitPushed} from '#presentation/subscribers/index.js';\nimport {createProjectsMaintenanceActivities} from '#temporal/activities/index.js';\nimport {PROJECTS_MAINTENANCE_TASK_QUEUE} from '#temporal/constants.js';\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\nconst maintenanceWorkflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');\n\nconst subscriber = subscriberFactory<IntegrationsEventMap>();\n\nexport type {Project} from '#core/index.js';\nexport {\n createProjectFromSource,\n ProjectAccessDeniedError,\n ProjectAlreadyExistsError,\n ProjectNotFoundError,\n} from '#core/index.js';\nexport type {GetProjectBySourceParams} from '#db/index.js';\nexport {\n createProject,\n db,\n getProjectById,\n getProjectBySource,\n getWorkspaceProjectCounts,\n listProjects,\n migrationsPath,\n projectsOutbox,\n requireProjectForWorkspace,\n} from '#db/index.js';\nexport {createProjectRoutes, requireProjectAccess} from '#presentation/index.js';\n\nexport interface CreateProjectsModuleOptions {\n integrations: IntegrationsModuleClient;\n auth: AuthInterModuleClient;\n}\n\nexport function createProjectsModule({\n integrations,\n auth,\n}: CreateProjectsModuleOptions): ShipfoxModule {\n return {\n name: 'projects',\n database: {db, migrationsPath, databaseNamespace: 'projects'},\n routes: createProjectRoutes(integrations, auth),\n e2eRoutes: [projectsE2eRoutes],\n metrics: registerProjectsServiceMetrics,\n publishers: [{name: 'projects', table: projectsOutbox, db, eventSchemas: projectsEventSchemas}],\n interModulePresentations: [createProjectsInterModulePresentation()],\n subscribers: [subscriber(INTEGRATION_SOURCE_COMMIT_PUSHED, onSourceCommitPushed)],\n workers: [\n {\n taskQueue: PROJECTS_MAINTENANCE_TASK_QUEUE,\n workflowsPath: maintenanceWorkflowsPath,\n activities: createProjectsMaintenanceActivities,\n workflows: [\n {\n name: 'pruneIntegrationEventDedupCron',\n id: 'projects-prune-integration-event-dedup',\n cronSchedule: '0 3 * * *',\n },\n ],\n },\n ],\n };\n}\n"],"names":["dirname","resolve","fileURLToPath","INTEGRATION_SOURCE_COMMIT_PUSHED","projectsEventSchemas","subscriberFactory","db","migrationsPath","projectsOutbox","registerProjectsServiceMetrics","projectsE2eRoutes","createProjectRoutes","createProjectsInterModulePresentation","onSourceCommitPushed","createProjectsMaintenanceActivities","PROJECTS_MAINTENANCE_TASK_QUEUE","packageRoot","url","maintenanceWorkflowsPath","subscriber","createProjectFromSource","ProjectAccessDeniedError","ProjectAlreadyExistsError","ProjectNotFoundError","createProject","getProjectById","getProjectBySource","getWorkspaceProjectCounts","listProjects","requireProjectForWorkspace","requireProjectAccess","createProjectsModule","integrations","auth","name","database","databaseNamespace","routes","e2eRoutes","metrics","publishers","table","eventSchemas","interModulePresentations","subscribers","workers","taskQueue","workflowsPath","activities","workflows","id","cronSchedule"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAEvC,SACEC,gCAAgC,QAE3B,oCAAoC;AAE3C,SAAQC,oBAAoB,QAAO,4BAA4B;AAC/D,SAA4BC,iBAAiB,QAAO,uBAAuB;AAC3E,SAAQC,EAAE,EAAEC,cAAc,EAAEC,cAAc,QAAO,eAAe;AAChE,SAAQC,8BAA8B,QAAO,oBAAoB;AACjE,SAAQC,iBAAiB,QAAO,mCAAmC;AACnE,SAAQC,mBAAmB,QAAO,yBAAyB;AAC3D,SAAQC,qCAAqC,QAAO,gCAAgC;AACpF,SAAQC,oBAAoB,QAAO,qCAAqC;AACxE,SAAQC,mCAAmC,QAAO,gCAAgC;AAClF,SAAQC,+BAA+B,QAAO,yBAAyB;AAEvE,MAAMC,cAAcf,QAAQD,QAAQE,cAAc,YAAYe,GAAG,IAAI;AACrE,MAAMC,2BAA2BjB,QAAQe,aAAa;AAEtD,MAAMG,aAAad;AAGnB,SACEe,uBAAuB,EACvBC,wBAAwB,EACxBC,yBAAyB,EACzBC,oBAAoB,QACf,iBAAiB;AAExB,SACEC,aAAa,EACblB,EAAE,EACFmB,cAAc,EACdC,kBAAkB,EAClBC,yBAAyB,EACzBC,YAAY,EACZrB,cAAc,EACdC,cAAc,EACdqB,0BAA0B,QACrB,eAAe;AACtB,SAAQlB,mBAAmB,EAAEmB,oBAAoB,QAAO,yBAAyB;AAOjF,OAAO,SAASC,qBAAqB,EACnCC,YAAY,EACZC,IAAI,EACwB;IAC5B,OAAO;QACLC,MAAM;QACNC,UAAU;YAAC7B;YAAIC;YAAgB6B,mBAAmB;QAAU;QAC5DC,QAAQ1B,oBAAoBqB,cAAcC;QAC1CK,WAAW;YAAC5B;SAAkB;QAC9B6B,SAAS9B;QACT+B,YAAY;YAAC;gBAACN,MAAM;gBAAYO,OAAOjC;gBAAgBF;gBAAIoC,cAActC;YAAoB;SAAE;QAC/FuC,0BAA0B;YAAC/B;SAAwC;QACnEgC,aAAa;YAACzB,WAAWhB,kCAAkCU;SAAsB;QACjFgC,SAAS;YACP;gBACEC,WAAW/B;gBACXgC,eAAe7B;gBACf8B,YAAYlC;gBACZmC,WAAW;oBACT;wBACEf,MAAM;wBACNgB,IAAI;wBACJC,cAAc;oBAChB;iBACD;YACH;SACD;IACH;AACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { toProjectDto } from './project.js';
|
|
1
|
+
export { toAdminProjectSummaryDto, toProjectDto } from './project.js';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,wBAAwB,EAAE,YAAY,EAAC,MAAM,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/dto/index.ts"],"sourcesContent":["export {toProjectDto} from './project.js';\n"],"names":["toProjectDto"],"mappings":"AAAA,SAAQA,YAAY,QAAO,eAAe"}
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/dto/index.ts"],"sourcesContent":["export {toAdminProjectSummaryDto, toProjectDto} from './project.js';\n"],"names":["toAdminProjectSummaryDto","toProjectDto"],"mappings":"AAAA,SAAQA,wBAAwB,EAAEC,YAAY,QAAO,eAAe"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Project } from '#core/entities/index.js';
|
|
2
|
+
import type { AdminProjectSummary } from '#db/projects.js';
|
|
2
3
|
export declare function toProjectDto(project: Project): {
|
|
3
4
|
id: string;
|
|
4
5
|
workspace_id: string;
|
|
@@ -10,4 +11,12 @@ export declare function toProjectDto(project: Project): {
|
|
|
10
11
|
created_at: string;
|
|
11
12
|
updated_at: string;
|
|
12
13
|
};
|
|
14
|
+
export declare function toAdminProjectSummaryDto(project: AdminProjectSummary): {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
status: "active";
|
|
18
|
+
workspace_id: string;
|
|
19
|
+
created_at: string;
|
|
20
|
+
updated_at: string;
|
|
21
|
+
};
|
|
13
22
|
//# sourceMappingURL=project.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/project.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/project.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,yBAAyB,CAAC;AACrD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,iBAAiB,CAAC;AAEzD,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO;;;;;;;;;;EAY5C;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,mBAAmB;;;;;;;EASpE"}
|
|
@@ -11,5 +11,15 @@ export function toProjectDto(project) {
|
|
|
11
11
|
updated_at: project.updatedAt.toISOString()
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
+
export function toAdminProjectSummaryDto(project) {
|
|
15
|
+
return {
|
|
16
|
+
id: project.id,
|
|
17
|
+
name: project.name,
|
|
18
|
+
status: 'active',
|
|
19
|
+
workspace_id: project.workspaceId,
|
|
20
|
+
created_at: project.createdAt.toISOString(),
|
|
21
|
+
updated_at: project.updatedAt.toISOString()
|
|
22
|
+
};
|
|
23
|
+
}
|
|
14
24
|
|
|
15
25
|
//# sourceMappingURL=project.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/dto/project.ts"],"sourcesContent":["import type {Project} from '#core/entities/index.js';\n\nexport function toProjectDto(project: Project) {\n return {\n id: project.id,\n workspace_id: project.workspaceId,\n name: project.name,\n source: {\n connection_id: project.sourceConnectionId,\n external_repository_id: project.sourceExternalRepositoryId,\n },\n created_at: project.createdAt.toISOString(),\n updated_at: project.updatedAt.toISOString(),\n };\n}\n"],"names":["toProjectDto","project","id","workspace_id","workspaceId","name","source","connection_id","sourceConnectionId","external_repository_id","sourceExternalRepositoryId","created_at","createdAt","toISOString","updated_at","updatedAt"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/dto/project.ts"],"sourcesContent":["import type {Project} from '#core/entities/index.js';\nimport type {AdminProjectSummary} from '#db/projects.js';\n\nexport function toProjectDto(project: Project) {\n return {\n id: project.id,\n workspace_id: project.workspaceId,\n name: project.name,\n source: {\n connection_id: project.sourceConnectionId,\n external_repository_id: project.sourceExternalRepositoryId,\n },\n created_at: project.createdAt.toISOString(),\n updated_at: project.updatedAt.toISOString(),\n };\n}\n\nexport function toAdminProjectSummaryDto(project: AdminProjectSummary) {\n return {\n id: project.id,\n name: project.name,\n status: 'active' as const,\n workspace_id: project.workspaceId,\n created_at: project.createdAt.toISOString(),\n updated_at: project.updatedAt.toISOString(),\n };\n}\n"],"names":["toProjectDto","project","id","workspace_id","workspaceId","name","source","connection_id","sourceConnectionId","external_repository_id","sourceExternalRepositoryId","created_at","createdAt","toISOString","updated_at","updatedAt","toAdminProjectSummaryDto","status"],"mappings":"AAGA,OAAO,SAASA,aAAaC,OAAgB;IAC3C,OAAO;QACLC,IAAID,QAAQC,EAAE;QACdC,cAAcF,QAAQG,WAAW;QACjCC,MAAMJ,QAAQI,IAAI;QAClBC,QAAQ;YACNC,eAAeN,QAAQO,kBAAkB;YACzCC,wBAAwBR,QAAQS,0BAA0B;QAC5D;QACAC,YAAYV,QAAQW,SAAS,CAACC,WAAW;QACzCC,YAAYb,QAAQc,SAAS,CAACF,WAAW;IAC3C;AACF;AAEA,OAAO,SAASG,yBAAyBf,OAA4B;IACnE,OAAO;QACLC,IAAID,QAAQC,EAAE;QACdG,MAAMJ,QAAQI,IAAI;QAClBY,QAAQ;QACRd,cAAcF,QAAQG,WAAW;QACjCO,YAAYV,QAAQW,SAAS,CAACC,WAAW;QACzCC,YAAYb,QAAQc,SAAS,CAACF,WAAW;IAC3C;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inter-module.d.ts","sourceRoot":"","sources":["../../src/presentation/inter-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,2BAA2B,EAAC,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAC;AAG/B,wBAAgB,qCAAqC,IAAI,uBAAuB,CAC9E,OAAO,2BAA2B,CACnC,
|
|
1
|
+
{"version":3,"file":"inter-module.d.ts","sourceRoot":"","sources":["../../src/presentation/inter-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,2BAA2B,EAAC,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAC;AAG/B,wBAAgB,qCAAqC,IAAI,uBAAuB,CAC9E,OAAO,2BAA2B,CACnC,CAyBA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { projectsInterModuleContract } from '@shipfox/api-projects-dto/inter-module';
|
|
2
2
|
import { createInterModuleKnownError, defineInterModulePresentation } from '@shipfox/inter-module';
|
|
3
|
-
import { getProjectById } from '#db/projects.js';
|
|
3
|
+
import { getProjectById, getWorkspaceProjectCounts } from '#db/projects.js';
|
|
4
4
|
export function createProjectsInterModulePresentation() {
|
|
5
5
|
return defineInterModulePresentation(projectsInterModuleContract, {
|
|
6
6
|
getProjectById: async ({ projectId })=>({
|
|
@@ -22,7 +22,12 @@ export function createProjectsInterModulePresentation() {
|
|
|
22
22
|
return {
|
|
23
23
|
project
|
|
24
24
|
};
|
|
25
|
-
}
|
|
25
|
+
},
|
|
26
|
+
getWorkspaceProjectCounts: async ({ workspaceIds })=>({
|
|
27
|
+
counts: await getWorkspaceProjectCounts({
|
|
28
|
+
workspaceIds
|
|
29
|
+
})
|
|
30
|
+
})
|
|
26
31
|
});
|
|
27
32
|
}
|
|
28
33
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/presentation/inter-module.ts"],"sourcesContent":["import {projectsInterModuleContract} from '@shipfox/api-projects-dto/inter-module';\nimport {\n createInterModuleKnownError,\n defineInterModulePresentation,\n type InterModulePresentation,\n} from '@shipfox/inter-module';\nimport {getProjectById} from '#db/projects.js';\n\nexport function createProjectsInterModulePresentation(): InterModulePresentation<\n typeof projectsInterModuleContract\n> {\n return defineInterModulePresentation(projectsInterModuleContract, {\n getProjectById: async ({projectId}) => ({project: (await getProjectById(projectId)) ?? null}),\n requireProjectForWorkspace: async ({projectId, workspaceId}) => {\n const project = await getProjectById(projectId);\n if (project === undefined) {\n throw createInterModuleKnownError(\n projectsInterModuleContract.methods.requireProjectForWorkspace,\n 'project-not-found',\n {projectId},\n );\n }\n if (project.workspaceId !== workspaceId) {\n throw createInterModuleKnownError(\n projectsInterModuleContract.methods.requireProjectForWorkspace,\n 'project-workspace-mismatch',\n {projectId, workspaceId},\n );\n }\n return {project};\n },\n });\n}\n"],"names":["projectsInterModuleContract","createInterModuleKnownError","defineInterModulePresentation","getProjectById","createProjectsInterModulePresentation","projectId","project","requireProjectForWorkspace","workspaceId","undefined","methods"],"mappings":"AAAA,SAAQA,2BAA2B,QAAO,yCAAyC;AACnF,SACEC,2BAA2B,EAC3BC,6BAA6B,QAExB,wBAAwB;AAC/B,SAAQC,cAAc,QAAO,kBAAkB;
|
|
1
|
+
{"version":3,"sources":["../../src/presentation/inter-module.ts"],"sourcesContent":["import {projectsInterModuleContract} from '@shipfox/api-projects-dto/inter-module';\nimport {\n createInterModuleKnownError,\n defineInterModulePresentation,\n type InterModulePresentation,\n} from '@shipfox/inter-module';\nimport {getProjectById, getWorkspaceProjectCounts} from '#db/projects.js';\n\nexport function createProjectsInterModulePresentation(): InterModulePresentation<\n typeof projectsInterModuleContract\n> {\n return defineInterModulePresentation(projectsInterModuleContract, {\n getProjectById: async ({projectId}) => ({project: (await getProjectById(projectId)) ?? null}),\n requireProjectForWorkspace: async ({projectId, workspaceId}) => {\n const project = await getProjectById(projectId);\n if (project === undefined) {\n throw createInterModuleKnownError(\n projectsInterModuleContract.methods.requireProjectForWorkspace,\n 'project-not-found',\n {projectId},\n );\n }\n if (project.workspaceId !== workspaceId) {\n throw createInterModuleKnownError(\n projectsInterModuleContract.methods.requireProjectForWorkspace,\n 'project-workspace-mismatch',\n {projectId, workspaceId},\n );\n }\n return {project};\n },\n getWorkspaceProjectCounts: async ({workspaceIds}) => ({\n counts: await getWorkspaceProjectCounts({workspaceIds}),\n }),\n });\n}\n"],"names":["projectsInterModuleContract","createInterModuleKnownError","defineInterModulePresentation","getProjectById","getWorkspaceProjectCounts","createProjectsInterModulePresentation","projectId","project","requireProjectForWorkspace","workspaceId","undefined","methods","workspaceIds","counts"],"mappings":"AAAA,SAAQA,2BAA2B,QAAO,yCAAyC;AACnF,SACEC,2BAA2B,EAC3BC,6BAA6B,QAExB,wBAAwB;AAC/B,SAAQC,cAAc,EAAEC,yBAAyB,QAAO,kBAAkB;AAE1E,OAAO,SAASC;IAGd,OAAOH,8BAA8BF,6BAA6B;QAChEG,gBAAgB,OAAO,EAACG,SAAS,EAAC,GAAM,CAAA;gBAACC,SAAS,AAAC,MAAMJ,eAAeG,cAAe;YAAI,CAAA;QAC3FE,4BAA4B,OAAO,EAACF,SAAS,EAAEG,WAAW,EAAC;YACzD,MAAMF,UAAU,MAAMJ,eAAeG;YACrC,IAAIC,YAAYG,WAAW;gBACzB,MAAMT,4BACJD,4BAA4BW,OAAO,CAACH,0BAA0B,EAC9D,qBACA;oBAACF;gBAAS;YAEd;YACA,IAAIC,QAAQE,WAAW,KAAKA,aAAa;gBACvC,MAAMR,4BACJD,4BAA4BW,OAAO,CAACH,0BAA0B,EAC9D,8BACA;oBAACF;oBAAWG;gBAAW;YAE3B;YACA,OAAO;gBAACF;YAAO;QACjB;QACAH,2BAA2B,OAAO,EAACQ,YAAY,EAAC,GAAM,CAAA;gBACpDC,QAAQ,MAAMT,0BAA0B;oBAACQ;gBAAY;YACvD,CAAA;IACF;AACF"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type AuthInterModuleClient } from '@shipfox/api-auth-dto/inter-module';
|
|
2
|
+
export declare function createAdminProjectsRoute(auth: Pick<AuthInterModuleClient, 'requireAdminRole'>): import("@shipfox/node-fastify").RouteDefinition;
|
|
3
|
+
//# sourceMappingURL=admin-projects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-projects.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/admin-projects.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,qBAAqB,EAE3B,MAAM,oCAAoC,CAAC;AA2B5C,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,kBAAkB,CAAC,mDAkC7F"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { AUTH_USER, requireUserContext } from '@shipfox/api-auth-context';
|
|
2
|
+
import { authInterModuleContract } from '@shipfox/api-auth-dto/inter-module';
|
|
3
|
+
import { listAdminProjectsQuerySchema, listAdminProjectsResponseSchema } from '@shipfox/api-projects-dto';
|
|
4
|
+
import { isInterModuleKnownError } from '@shipfox/inter-module';
|
|
5
|
+
import { ClientError, defineRoute } from '@shipfox/node-fastify';
|
|
6
|
+
import { listAdminProjects } from '#db/index.js';
|
|
7
|
+
import { toAdminProjectSummaryDto } from '#presentation/dto/index.js';
|
|
8
|
+
import { decodeProjectCursor, encodeProjectCursor } from './cursor.js';
|
|
9
|
+
const minimumRole = 'admin-observer';
|
|
10
|
+
function translateAdminProjectRouteError(error) {
|
|
11
|
+
if (isInterModuleKnownError(authInterModuleContract.methods.requireAdminRole, error) && error.code === 'admin-role-required') {
|
|
12
|
+
throw new ClientError('Administrator observer role required', 'forbidden', {
|
|
13
|
+
status: 403,
|
|
14
|
+
details: {
|
|
15
|
+
required_role: error.details.requiredRole
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
export function createAdminProjectsRoute(auth) {
|
|
22
|
+
return defineRoute({
|
|
23
|
+
method: 'GET',
|
|
24
|
+
path: '/',
|
|
25
|
+
auth: AUTH_USER,
|
|
26
|
+
description: 'List a bounded safe project summary for administrators.',
|
|
27
|
+
schema: {
|
|
28
|
+
querystring: listAdminProjectsQuerySchema,
|
|
29
|
+
response: {
|
|
30
|
+
200: listAdminProjectsResponseSchema
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
errorHandler: translateAdminProjectRouteError,
|
|
34
|
+
handler: async (request)=>{
|
|
35
|
+
const actor = requireUserContext(request);
|
|
36
|
+
await auth.requireAdminRole({
|
|
37
|
+
userId: actor.userId,
|
|
38
|
+
minimumRole
|
|
39
|
+
});
|
|
40
|
+
const { project_id: projectId, limit, cursor, search } = request.query;
|
|
41
|
+
const decodedCursor = decodeProjectCursor(cursor);
|
|
42
|
+
if (cursor && !decodedCursor) {
|
|
43
|
+
throw new ClientError('Invalid cursor', 'invalid-cursor', {
|
|
44
|
+
status: 400
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const result = await listAdminProjects({
|
|
48
|
+
projectId,
|
|
49
|
+
limit,
|
|
50
|
+
cursor: decodedCursor,
|
|
51
|
+
search
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
projects: result.projects.map(toAdminProjectSummaryDto),
|
|
55
|
+
next_cursor: result.nextCursor ? encodeProjectCursor(result.nextCursor) : null
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=admin-projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/admin-projects.ts"],"sourcesContent":["import {AUTH_USER, requireUserContext} from '@shipfox/api-auth-context';\nimport {\n type AuthInterModuleClient,\n authInterModuleContract,\n} from '@shipfox/api-auth-dto/inter-module';\nimport {\n listAdminProjectsQuerySchema,\n listAdminProjectsResponseSchema,\n} from '@shipfox/api-projects-dto';\nimport {isInterModuleKnownError} from '@shipfox/inter-module';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {listAdminProjects} from '#db/index.js';\nimport {toAdminProjectSummaryDto} from '#presentation/dto/index.js';\nimport {decodeProjectCursor, encodeProjectCursor} from './cursor.js';\n\nconst minimumRole = 'admin-observer' as const;\n\nfunction translateAdminProjectRouteError(error: unknown): never {\n if (\n isInterModuleKnownError(authInterModuleContract.methods.requireAdminRole, error) &&\n error.code === 'admin-role-required'\n ) {\n throw new ClientError('Administrator observer role required', 'forbidden', {\n status: 403,\n details: {required_role: error.details.requiredRole},\n });\n }\n\n throw error;\n}\n\nexport function createAdminProjectsRoute(auth: Pick<AuthInterModuleClient, 'requireAdminRole'>) {\n return defineRoute({\n method: 'GET',\n path: '/',\n auth: AUTH_USER,\n description: 'List a bounded safe project summary for administrators.',\n schema: {\n querystring: listAdminProjectsQuerySchema,\n response: {200: listAdminProjectsResponseSchema},\n },\n errorHandler: translateAdminProjectRouteError,\n handler: async (request) => {\n const actor = requireUserContext(request);\n await auth.requireAdminRole({userId: actor.userId, minimumRole});\n\n const {project_id: projectId, limit, cursor, search} = request.query;\n const decodedCursor = decodeProjectCursor(cursor);\n if (cursor && !decodedCursor) {\n throw new ClientError('Invalid cursor', 'invalid-cursor', {status: 400});\n }\n\n const result = await listAdminProjects({\n projectId,\n limit,\n cursor: decodedCursor,\n search,\n });\n\n return {\n projects: result.projects.map(toAdminProjectSummaryDto),\n next_cursor: result.nextCursor ? encodeProjectCursor(result.nextCursor) : null,\n };\n },\n });\n}\n"],"names":["AUTH_USER","requireUserContext","authInterModuleContract","listAdminProjectsQuerySchema","listAdminProjectsResponseSchema","isInterModuleKnownError","ClientError","defineRoute","listAdminProjects","toAdminProjectSummaryDto","decodeProjectCursor","encodeProjectCursor","minimumRole","translateAdminProjectRouteError","error","methods","requireAdminRole","code","status","details","required_role","requiredRole","createAdminProjectsRoute","auth","method","path","description","schema","querystring","response","errorHandler","handler","request","actor","userId","project_id","projectId","limit","cursor","search","query","decodedCursor","result","projects","map","next_cursor","nextCursor"],"mappings":"AAAA,SAAQA,SAAS,EAAEC,kBAAkB,QAAO,4BAA4B;AACxE,SAEEC,uBAAuB,QAClB,qCAAqC;AAC5C,SACEC,4BAA4B,EAC5BC,+BAA+B,QAC1B,4BAA4B;AACnC,SAAQC,uBAAuB,QAAO,wBAAwB;AAC9D,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,iBAAiB,QAAO,eAAe;AAC/C,SAAQC,wBAAwB,QAAO,6BAA6B;AACpE,SAAQC,mBAAmB,EAAEC,mBAAmB,QAAO,cAAc;AAErE,MAAMC,cAAc;AAEpB,SAASC,gCAAgCC,KAAc;IACrD,IACET,wBAAwBH,wBAAwBa,OAAO,CAACC,gBAAgB,EAAEF,UAC1EA,MAAMG,IAAI,KAAK,uBACf;QACA,MAAM,IAAIX,YAAY,wCAAwC,aAAa;YACzEY,QAAQ;YACRC,SAAS;gBAACC,eAAeN,MAAMK,OAAO,CAACE,YAAY;YAAA;QACrD;IACF;IAEA,MAAMP;AACR;AAEA,OAAO,SAASQ,yBAAyBC,IAAqD;IAC5F,OAAOhB,YAAY;QACjBiB,QAAQ;QACRC,MAAM;QACNF,MAAMvB;QACN0B,aAAa;QACbC,QAAQ;YACNC,aAAazB;YACb0B,UAAU;gBAAC,KAAKzB;YAA+B;QACjD;QACA0B,cAAcjB;QACdkB,SAAS,OAAOC;YACd,MAAMC,QAAQhC,mBAAmB+B;YACjC,MAAMT,KAAKP,gBAAgB,CAAC;gBAACkB,QAAQD,MAAMC,MAAM;gBAAEtB;YAAW;YAE9D,MAAM,EAACuB,YAAYC,SAAS,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAC,GAAGP,QAAQQ,KAAK;YACpE,MAAMC,gBAAgB/B,oBAAoB4B;YAC1C,IAAIA,UAAU,CAACG,eAAe;gBAC5B,MAAM,IAAInC,YAAY,kBAAkB,kBAAkB;oBAACY,QAAQ;gBAAG;YACxE;YAEA,MAAMwB,SAAS,MAAMlC,kBAAkB;gBACrC4B;gBACAC;gBACAC,QAAQG;gBACRF;YACF;YAEA,OAAO;gBACLI,UAAUD,OAAOC,QAAQ,CAACC,GAAG,CAACnC;gBAC9BoC,aAAaH,OAAOI,UAAU,GAAGnC,oBAAoB+B,OAAOI,UAAU,IAAI;YAC5E;QACF;IACF;AACF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
import type { AuthInterModuleClient } from '@shipfox/api-auth-dto/inter-module';
|
|
1
2
|
import type { IntegrationsModuleClient } from '@shipfox/api-integration-core-dto/inter-module';
|
|
2
3
|
import type { RouteGroup } from '@shipfox/node-fastify';
|
|
3
|
-
export declare function createProjectRoutes(integrations: IntegrationsModuleClient): RouteGroup[];
|
|
4
|
+
export declare function createProjectRoutes(integrations: IntegrationsModuleClient, auth: Pick<AuthInterModuleClient, 'requireAdminRole'>): RouteGroup[];
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/index.ts"],"names":[],"mappings":"AAAA,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;AAMtD,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,wBAAwB,EACtC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,kBAAkB,CAAC,GACpD,UAAU,EAAE,CAWd"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { createAdminProjectsRoute } from './admin-projects.js';
|
|
1
2
|
import { createProjectRoute } from './create-project.js';
|
|
2
3
|
import { getProjectRoute } from './get-project.js';
|
|
3
4
|
import { listProjectsRoute } from './list-projects.js';
|
|
4
|
-
export function createProjectRoutes(integrations) {
|
|
5
|
+
export function createProjectRoutes(integrations, auth) {
|
|
5
6
|
return [
|
|
6
7
|
{
|
|
7
8
|
prefix: '/projects',
|
|
@@ -10,6 +11,12 @@ export function createProjectRoutes(integrations) {
|
|
|
10
11
|
listProjectsRoute,
|
|
11
12
|
getProjectRoute
|
|
12
13
|
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
prefix: '/admin/projects',
|
|
17
|
+
routes: [
|
|
18
|
+
createAdminProjectsRoute(auth)
|
|
19
|
+
]
|
|
13
20
|
}
|
|
14
21
|
];
|
|
15
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/routes/index.ts"],"sourcesContent":["import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport type {RouteGroup} from '@shipfox/node-fastify';\nimport {createProjectRoute} from './create-project.js';\nimport {getProjectRoute} from './get-project.js';\nimport {listProjectsRoute} from './list-projects.js';\n\nexport function createProjectRoutes(integrations: IntegrationsModuleClient): RouteGroup[] {\n return [\n {\n prefix: '/projects',\n routes: [createProjectRoute(integrations), listProjectsRoute, getProjectRoute],\n },\n ];\n}\n"],"names":["createProjectRoute","getProjectRoute","listProjectsRoute","createProjectRoutes","integrations","prefix","routes"],"mappings":"
|
|
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), listProjectsRoute, getProjectRoute],\n },\n {\n prefix: '/admin/projects',\n routes: [createAdminProjectsRoute(auth)],\n },\n ];\n}\n"],"names":["createAdminProjectsRoute","createProjectRoute","getProjectRoute","listProjectsRoute","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;AAErD,OAAO,SAASC,oBACdC,YAAsC,EACtCC,IAAqD;IAErD,OAAO;QACL;YACEC,QAAQ;YACRC,QAAQ;gBAACP,mBAAmBI;gBAAeF;gBAAmBD;aAAgB;QAChF;QACA;YACEK,QAAQ;YACRC,QAAQ;gBAACR,yBAAyBM;aAAM;QAC1C;KACD;AACH"}
|