@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
|
@@ -71,6 +71,57 @@ export declare const projects: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
71
71
|
identity: undefined;
|
|
72
72
|
generated: undefined;
|
|
73
73
|
}, {}, {}>;
|
|
74
|
+
sourceRepositoryOwner: import("drizzle-orm/pg-core").PgColumn<{
|
|
75
|
+
name: "source_repository_owner";
|
|
76
|
+
tableName: "projects";
|
|
77
|
+
dataType: "string";
|
|
78
|
+
columnType: "PgText";
|
|
79
|
+
data: string;
|
|
80
|
+
driverParam: string;
|
|
81
|
+
notNull: false;
|
|
82
|
+
hasDefault: false;
|
|
83
|
+
isPrimaryKey: false;
|
|
84
|
+
isAutoincrement: false;
|
|
85
|
+
hasRuntimeDefault: false;
|
|
86
|
+
enumValues: [string, ...string[]];
|
|
87
|
+
baseColumn: never;
|
|
88
|
+
identity: undefined;
|
|
89
|
+
generated: undefined;
|
|
90
|
+
}, {}, {}>;
|
|
91
|
+
sourceRepositoryName: import("drizzle-orm/pg-core").PgColumn<{
|
|
92
|
+
name: "source_repository_name";
|
|
93
|
+
tableName: "projects";
|
|
94
|
+
dataType: "string";
|
|
95
|
+
columnType: "PgText";
|
|
96
|
+
data: string;
|
|
97
|
+
driverParam: string;
|
|
98
|
+
notNull: false;
|
|
99
|
+
hasDefault: false;
|
|
100
|
+
isPrimaryKey: false;
|
|
101
|
+
isAutoincrement: false;
|
|
102
|
+
hasRuntimeDefault: false;
|
|
103
|
+
enumValues: [string, ...string[]];
|
|
104
|
+
baseColumn: never;
|
|
105
|
+
identity: undefined;
|
|
106
|
+
generated: undefined;
|
|
107
|
+
}, {}, {}>;
|
|
108
|
+
sourceDefaultBranch: import("drizzle-orm/pg-core").PgColumn<{
|
|
109
|
+
name: "source_default_branch";
|
|
110
|
+
tableName: "projects";
|
|
111
|
+
dataType: "string";
|
|
112
|
+
columnType: "PgText";
|
|
113
|
+
data: string;
|
|
114
|
+
driverParam: string;
|
|
115
|
+
notNull: false;
|
|
116
|
+
hasDefault: false;
|
|
117
|
+
isPrimaryKey: false;
|
|
118
|
+
isAutoincrement: false;
|
|
119
|
+
hasRuntimeDefault: false;
|
|
120
|
+
enumValues: [string, ...string[]];
|
|
121
|
+
baseColumn: never;
|
|
122
|
+
identity: undefined;
|
|
123
|
+
generated: undefined;
|
|
124
|
+
}, {}, {}>;
|
|
74
125
|
name: import("drizzle-orm/pg-core").PgColumn<{
|
|
75
126
|
name: "name";
|
|
76
127
|
tableName: "projects";
|
|
@@ -88,6 +139,23 @@ export declare const projects: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
88
139
|
identity: undefined;
|
|
89
140
|
generated: undefined;
|
|
90
141
|
}, {}, {}>;
|
|
142
|
+
slug: import("drizzle-orm/pg-core").PgColumn<{
|
|
143
|
+
name: "slug";
|
|
144
|
+
tableName: "projects";
|
|
145
|
+
dataType: "string";
|
|
146
|
+
columnType: "PgText";
|
|
147
|
+
data: string;
|
|
148
|
+
driverParam: string;
|
|
149
|
+
notNull: true;
|
|
150
|
+
hasDefault: false;
|
|
151
|
+
isPrimaryKey: false;
|
|
152
|
+
isAutoincrement: false;
|
|
153
|
+
hasRuntimeDefault: false;
|
|
154
|
+
enumValues: [string, ...string[]];
|
|
155
|
+
baseColumn: never;
|
|
156
|
+
identity: undefined;
|
|
157
|
+
generated: undefined;
|
|
158
|
+
}, {}, {}>;
|
|
91
159
|
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
92
160
|
name: "created_at";
|
|
93
161
|
tableName: "projects";
|
|
@@ -123,7 +191,7 @@ export declare const projects: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
123
191
|
generated: undefined;
|
|
124
192
|
}, {}, {}>;
|
|
125
193
|
};
|
|
126
|
-
dialect:
|
|
194
|
+
dialect: 'pg';
|
|
127
195
|
}>;
|
|
128
196
|
export type ProjectDb = typeof projects.$inferSelect;
|
|
129
197
|
export type ProjectCreateDb = typeof projects.$inferInsert;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../../src/db/schema/projects.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../../src/db/schema/projects.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,2BAA2B,CAAC;AAGvD,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BpB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,OAAO,QAAQ,CAAC,YAAY,CAAC;AACrD,MAAM,MAAM,eAAe,GAAG,OAAO,QAAQ,CAAC,YAAY,CAAC;AAE3D,wBAAgB,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAcjD"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { uuidv7PrimaryKey } from '@shipfox/node-drizzle';
|
|
2
|
+
import { sql } from 'drizzle-orm';
|
|
2
3
|
import { index, text, timestamp, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
|
|
3
4
|
import { pgTable } from './common.js';
|
|
4
5
|
export const projects = pgTable('projects', {
|
|
@@ -6,7 +7,11 @@ export const projects = pgTable('projects', {
|
|
|
6
7
|
workspaceId: uuid('workspace_id').notNull(),
|
|
7
8
|
sourceConnectionId: uuid('source_connection_id').notNull(),
|
|
8
9
|
sourceExternalRepositoryId: text('source_external_repository_id').notNull(),
|
|
10
|
+
sourceRepositoryOwner: text('source_repository_owner'),
|
|
11
|
+
sourceRepositoryName: text('source_repository_name'),
|
|
12
|
+
sourceDefaultBranch: text('source_default_branch'),
|
|
9
13
|
name: text('name').notNull(),
|
|
14
|
+
slug: text('slug').notNull(),
|
|
10
15
|
createdAt: timestamp('created_at', {
|
|
11
16
|
withTimezone: true
|
|
12
17
|
}).notNull().defaultNow(),
|
|
@@ -15,7 +20,9 @@ export const projects = pgTable('projects', {
|
|
|
15
20
|
}).notNull().defaultNow()
|
|
16
21
|
}, (table)=>[
|
|
17
22
|
uniqueIndex('projects_source_unique').on(table.sourceConnectionId, table.sourceExternalRepositoryId),
|
|
18
|
-
|
|
23
|
+
uniqueIndex('projects_workspace_slug_unique').on(table.workspaceId, table.slug),
|
|
24
|
+
index('projects_workspace_created_id_idx').on(table.workspaceId, table.createdAt, table.id),
|
|
25
|
+
index('projects_source_repository_lookup_idx').on(table.workspaceId, table.sourceConnectionId, sql`lower(${table.sourceRepositoryOwner})`, sql`lower(${table.sourceRepositoryName})`)
|
|
19
26
|
]);
|
|
20
27
|
export function toProject(row) {
|
|
21
28
|
return {
|
|
@@ -23,7 +30,11 @@ export function toProject(row) {
|
|
|
23
30
|
workspaceId: row.workspaceId,
|
|
24
31
|
sourceConnectionId: row.sourceConnectionId,
|
|
25
32
|
sourceExternalRepositoryId: row.sourceExternalRepositoryId,
|
|
33
|
+
sourceRepositoryOwner: row.sourceRepositoryOwner,
|
|
34
|
+
sourceRepositoryName: row.sourceRepositoryName,
|
|
35
|
+
sourceDefaultBranch: row.sourceDefaultBranch,
|
|
26
36
|
name: row.name,
|
|
37
|
+
slug: row.slug,
|
|
27
38
|
createdAt: row.createdAt,
|
|
28
39
|
updatedAt: row.updatedAt
|
|
29
40
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/db/schema/projects.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {index, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport type {Project} from '#core/entities/project.js';\nimport {pgTable} from './common.js';\n\nexport const projects = pgTable(\n 'projects',\n {\n id: uuidv7PrimaryKey(),\n workspaceId: uuid('workspace_id').notNull(),\n sourceConnectionId: uuid('source_connection_id').notNull(),\n sourceExternalRepositoryId: text('source_external_repository_id').notNull(),\n name: text('name').notNull(),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('projects_source_unique').on(\n table.sourceConnectionId,\n table.sourceExternalRepositoryId,\n ),\n index('projects_workspace_created_id_idx').on(table.workspaceId, table.createdAt, table.id),\n ],\n);\n\nexport type ProjectDb = typeof projects.$inferSelect;\nexport type ProjectCreateDb = typeof projects.$inferInsert;\n\nexport function toProject(row: ProjectDb): Project {\n return {\n id: row.id,\n workspaceId: row.workspaceId,\n sourceConnectionId: row.sourceConnectionId,\n sourceExternalRepositoryId: row.sourceExternalRepositoryId,\n name: row.name,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","index","text","timestamp","uniqueIndex","uuid","pgTable","projects","id","workspaceId","notNull","sourceConnectionId","sourceExternalRepositoryId","name","createdAt","withTimezone","defaultNow","updatedAt","table","on","toProject","row"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SAAQC,KAAK,EAAEC,IAAI,EAAEC,SAAS,EAAEC,WAAW,EAAEC,IAAI,QAAO,sBAAsB;AAE9E,SAAQC,OAAO,QAAO,cAAc;AAEpC,OAAO,MAAMC,WAAWD,QACtB,YACA;IACEE,
|
|
1
|
+
{"version":3,"sources":["../../../src/db/schema/projects.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {sql} from 'drizzle-orm';\nimport {index, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport type {Project} from '#core/entities/project.js';\nimport {pgTable} from './common.js';\n\nexport const projects = pgTable(\n 'projects',\n {\n id: uuidv7PrimaryKey(),\n workspaceId: uuid('workspace_id').notNull(),\n sourceConnectionId: uuid('source_connection_id').notNull(),\n sourceExternalRepositoryId: text('source_external_repository_id').notNull(),\n sourceRepositoryOwner: text('source_repository_owner'),\n sourceRepositoryName: text('source_repository_name'),\n sourceDefaultBranch: text('source_default_branch'),\n name: text('name').notNull(),\n slug: text('slug').notNull(),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('projects_source_unique').on(\n table.sourceConnectionId,\n table.sourceExternalRepositoryId,\n ),\n uniqueIndex('projects_workspace_slug_unique').on(table.workspaceId, table.slug),\n index('projects_workspace_created_id_idx').on(table.workspaceId, table.createdAt, table.id),\n index('projects_source_repository_lookup_idx').on(\n table.workspaceId,\n table.sourceConnectionId,\n sql`lower(${table.sourceRepositoryOwner})`,\n sql`lower(${table.sourceRepositoryName})`,\n ),\n ],\n);\n\nexport type ProjectDb = typeof projects.$inferSelect;\nexport type ProjectCreateDb = typeof projects.$inferInsert;\n\nexport function toProject(row: ProjectDb): Project {\n return {\n id: row.id,\n workspaceId: row.workspaceId,\n sourceConnectionId: row.sourceConnectionId,\n sourceExternalRepositoryId: row.sourceExternalRepositoryId,\n sourceRepositoryOwner: row.sourceRepositoryOwner,\n sourceRepositoryName: row.sourceRepositoryName,\n sourceDefaultBranch: row.sourceDefaultBranch,\n name: row.name,\n slug: row.slug,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","sql","index","text","timestamp","uniqueIndex","uuid","pgTable","projects","id","workspaceId","notNull","sourceConnectionId","sourceExternalRepositoryId","sourceRepositoryOwner","sourceRepositoryName","sourceDefaultBranch","name","slug","createdAt","withTimezone","defaultNow","updatedAt","table","on","toProject","row"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SAAQC,GAAG,QAAO,cAAc;AAChC,SAAQC,KAAK,EAAEC,IAAI,EAAEC,SAAS,EAAEC,WAAW,EAAEC,IAAI,QAAO,sBAAsB;AAE9E,SAAQC,OAAO,QAAO,cAAc;AAEpC,OAAO,MAAMC,WAAWD,QACtB,YACA;IACEE,IAAIT;IACJU,aAAaJ,KAAK,gBAAgBK,OAAO;IACzCC,oBAAoBN,KAAK,wBAAwBK,OAAO;IACxDE,4BAA4BV,KAAK,iCAAiCQ,OAAO;IACzEG,uBAAuBX,KAAK;IAC5BY,sBAAsBZ,KAAK;IAC3Ba,qBAAqBb,KAAK;IAC1Bc,MAAMd,KAAK,QAAQQ,OAAO;IAC1BO,MAAMf,KAAK,QAAQQ,OAAO;IAC1BQ,WAAWf,UAAU,cAAc;QAACgB,cAAc;IAAI,GAAGT,OAAO,GAAGU,UAAU;IAC7EC,WAAWlB,UAAU,cAAc;QAACgB,cAAc;IAAI,GAAGT,OAAO,GAAGU,UAAU;AAC/E,GACA,CAACE,QAAU;QACTlB,YAAY,0BAA0BmB,EAAE,CACtCD,MAAMX,kBAAkB,EACxBW,MAAMV,0BAA0B;QAElCR,YAAY,kCAAkCmB,EAAE,CAACD,MAAMb,WAAW,EAAEa,MAAML,IAAI;QAC9EhB,MAAM,qCAAqCsB,EAAE,CAACD,MAAMb,WAAW,EAAEa,MAAMJ,SAAS,EAAEI,MAAMd,EAAE;QAC1FP,MAAM,yCAAyCsB,EAAE,CAC/CD,MAAMb,WAAW,EACjBa,MAAMX,kBAAkB,EACxBX,GAAG,CAAC,MAAM,EAAEsB,MAAMT,qBAAqB,CAAC,CAAC,CAAC,EAC1Cb,GAAG,CAAC,MAAM,EAAEsB,MAAMR,oBAAoB,CAAC,CAAC,CAAC;KAE5C,EACD;AAKF,OAAO,SAASU,UAAUC,GAAc;IACtC,OAAO;QACLjB,IAAIiB,IAAIjB,EAAE;QACVC,aAAagB,IAAIhB,WAAW;QAC5BE,oBAAoBc,IAAId,kBAAkB;QAC1CC,4BAA4Ba,IAAIb,0BAA0B;QAC1DC,uBAAuBY,IAAIZ,qBAAqB;QAChDC,sBAAsBW,IAAIX,oBAAoB;QAC9CC,qBAAqBU,IAAIV,mBAAmB;QAC5CC,MAAMS,IAAIT,IAAI;QACdC,MAAMQ,IAAIR,IAAI;QACdC,WAAWO,IAAIP,SAAS;QACxBG,WAAWI,IAAIJ,SAAS;IAC1B;AACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { AuthInterModuleClient } from '@shipfox/api-auth-dto/inter-module';
|
|
|
2
2
|
import type { IntegrationsModuleClient } from '@shipfox/api-integration-core-dto/inter-module';
|
|
3
3
|
import { type ShipfoxModule } from '@shipfox/node-module';
|
|
4
4
|
export type { Project } from '#core/index.js';
|
|
5
|
-
export { createProjectFromSource, ProjectAccessDeniedError, ProjectAlreadyExistsError, ProjectNotFoundError, } from '#core/index.js';
|
|
5
|
+
export { createProjectFromSource, ProjectAccessDeniedError, ProjectAlreadyExistsError, ProjectNotFoundError, ProjectSlugConflictError, updateProjectDetails, } from '#core/index.js';
|
|
6
6
|
export type { GetProjectBySourceParams } from '#db/index.js';
|
|
7
7
|
export { createProject, db, getProjectById, getProjectBySource, getWorkspaceProjectCounts, listProjects, migrationsPath, projectsOutbox, requireProjectForWorkspace, } from '#db/index.js';
|
|
8
8
|
export { createProjectRoutes, requireProjectAccess } from '#presentation/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,oCAAoC,CAAC;AAM9E,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,EACpB,wBAAwB,EACxB,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,CA4B7C"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { dirname, resolve } from 'node:path';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import { INTEGRATION_SOURCE_COMMIT_PUSHED } from '@shipfox/api-integration-core-dto';
|
|
3
|
+
import { INTEGRATION_SOURCE_COMMIT_PUSHED, INTEGRATION_SOURCE_REPOSITORY_UPDATED } from '@shipfox/api-integration-core-dto';
|
|
4
4
|
import { projectsEventSchemas } from '@shipfox/api-projects-dto';
|
|
5
5
|
import { subscriberFactory } from '@shipfox/node-module';
|
|
6
6
|
import { db, migrationsPath, projectsOutbox } from '#db/index.js';
|
|
@@ -8,13 +8,13 @@ import { registerProjectsServiceMetrics } from '#metrics/index.js';
|
|
|
8
8
|
import { projectsE2eRoutes } from '#presentation/e2eRoutes/index.js';
|
|
9
9
|
import { createProjectRoutes } from '#presentation/index.js';
|
|
10
10
|
import { createProjectsInterModulePresentation } from '#presentation/inter-module.js';
|
|
11
|
-
import { onSourceCommitPushed } from '#presentation/subscribers/index.js';
|
|
11
|
+
import { onSourceCommitPushed, onSourceRepositoryUpdated } from '#presentation/subscribers/index.js';
|
|
12
12
|
import { createProjectsMaintenanceActivities } from '#temporal/activities/index.js';
|
|
13
13
|
import { PROJECTS_MAINTENANCE_TASK_QUEUE } from '#temporal/constants.js';
|
|
14
14
|
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
|
-
export { createProjectFromSource, ProjectAccessDeniedError, ProjectAlreadyExistsError, ProjectNotFoundError } from '#core/index.js';
|
|
17
|
+
export { createProjectFromSource, ProjectAccessDeniedError, ProjectAlreadyExistsError, ProjectNotFoundError, ProjectSlugConflictError, updateProjectDetails } from '#core/index.js';
|
|
18
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
20
|
export function createProjectsModule({ integrations, auth }) {
|
|
@@ -39,10 +39,13 @@ export function createProjectsModule({ integrations, auth }) {
|
|
|
39
39
|
}
|
|
40
40
|
],
|
|
41
41
|
interModulePresentations: [
|
|
42
|
-
createProjectsInterModulePresentation(
|
|
42
|
+
createProjectsInterModulePresentation({
|
|
43
|
+
integrations
|
|
44
|
+
})
|
|
43
45
|
],
|
|
44
46
|
subscribers: [
|
|
45
|
-
subscriber(INTEGRATION_SOURCE_COMMIT_PUSHED, onSourceCommitPushed)
|
|
47
|
+
subscriber(INTEGRATION_SOURCE_COMMIT_PUSHED, onSourceCommitPushed),
|
|
48
|
+
subscriber(INTEGRATION_SOURCE_REPOSITORY_UPDATED, onSourceRepositoryUpdated)
|
|
46
49
|
],
|
|
47
50
|
workers: [
|
|
48
51
|
{
|
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 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,
|
|
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 INTEGRATION_SOURCE_REPOSITORY_UPDATED,\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, onSourceRepositoryUpdated} 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 ProjectSlugConflictError,\n updateProjectDetails,\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({integrations})],\n subscribers: [\n subscriber(INTEGRATION_SOURCE_COMMIT_PUSHED, onSourceCommitPushed),\n subscriber(INTEGRATION_SOURCE_REPOSITORY_UPDATED, onSourceRepositoryUpdated),\n ],\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","INTEGRATION_SOURCE_REPOSITORY_UPDATED","projectsEventSchemas","subscriberFactory","db","migrationsPath","projectsOutbox","registerProjectsServiceMetrics","projectsE2eRoutes","createProjectRoutes","createProjectsInterModulePresentation","onSourceCommitPushed","onSourceRepositoryUpdated","createProjectsMaintenanceActivities","PROJECTS_MAINTENANCE_TASK_QUEUE","packageRoot","url","maintenanceWorkflowsPath","subscriber","createProjectFromSource","ProjectAccessDeniedError","ProjectAlreadyExistsError","ProjectNotFoundError","ProjectSlugConflictError","updateProjectDetails","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,EAChCC,qCAAqC,QAEhC,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,EAAEC,yBAAyB,QAAO,qCAAqC;AACnG,SAAQC,mCAAmC,QAAO,gCAAgC;AAClF,SAAQC,+BAA+B,QAAO,yBAAyB;AAEvE,MAAMC,cAAcjB,QAAQD,QAAQE,cAAc,YAAYiB,GAAG,IAAI;AACrE,MAAMC,2BAA2BnB,QAAQiB,aAAa;AAEtD,MAAMG,aAAaf;AAGnB,SACEgB,uBAAuB,EACvBC,wBAAwB,EACxBC,yBAAyB,EACzBC,oBAAoB,EACpBC,wBAAwB,EACxBC,oBAAoB,QACf,iBAAiB;AAExB,SACEC,aAAa,EACbrB,EAAE,EACFsB,cAAc,EACdC,kBAAkB,EAClBC,yBAAyB,EACzBC,YAAY,EACZxB,cAAc,EACdC,cAAc,EACdwB,0BAA0B,QACrB,eAAe;AACtB,SAAQrB,mBAAmB,EAAEsB,oBAAoB,QAAO,yBAAyB;AAOjF,OAAO,SAASC,qBAAqB,EACnCC,YAAY,EACZC,IAAI,EACwB;IAC5B,OAAO;QACLC,MAAM;QACNC,UAAU;YAAChC;YAAIC;YAAgBgC,mBAAmB;QAAU;QAC5DC,QAAQ7B,oBAAoBwB,cAAcC;QAC1CK,WAAW;YAAC/B;SAAkB;QAC9BgC,SAASjC;QACTkC,YAAY;YAAC;gBAACN,MAAM;gBAAYO,OAAOpC;gBAAgBF;gBAAIuC,cAAczC;YAAoB;SAAE;QAC/F0C,0BAA0B;YAAClC,sCAAsC;gBAACuB;YAAY;SAAG;QACjFY,aAAa;YACX3B,WAAWlB,kCAAkCW;YAC7CO,WAAWjB,uCAAuCW;SACnD;QACDkC,SAAS;YACP;gBACEC,WAAWjC;gBACXkC,eAAe/B;gBACfgC,YAAYpC;gBACZqC,WAAW;oBACT;wBACEf,MAAM;wBACNgB,IAAI;wBACJC,cAAc;oBAChB;iBACD;YACH;SACD;IACH;AACF"}
|
|
@@ -4,6 +4,7 @@ export declare function toProjectDto(project: Project): {
|
|
|
4
4
|
id: string;
|
|
5
5
|
workspace_id: string;
|
|
6
6
|
name: string;
|
|
7
|
+
slug: string;
|
|
7
8
|
source: {
|
|
8
9
|
connection_id: string;
|
|
9
10
|
external_repository_id: string;
|
|
@@ -14,7 +15,7 @@ export declare function toProjectDto(project: Project): {
|
|
|
14
15
|
export declare function toAdminProjectSummaryDto(project: AdminProjectSummary): {
|
|
15
16
|
id: string;
|
|
16
17
|
name: string;
|
|
17
|
-
status:
|
|
18
|
+
status: 'active';
|
|
18
19
|
workspace_id: string;
|
|
19
20
|
created_at: string;
|
|
20
21
|
updated_at: string;
|
|
@@ -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;AACrD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,iBAAiB,CAAC;AAEzD,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO
|
|
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;IAEzC,EAAE;IACF,YAAY;IACZ,IAAI;IACJ,IAAI;IACJ,MAAM;QACJ,aAAa;QACb,sBAAsB;;IAExB,UAAU;IACV,UAAU;EAEb;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,mBAAmB;IAEjE,EAAE;IACF,IAAI;IACJ,MAAM,EAAE,QAAQ;IAChB,YAAY;IACZ,UAAU;IACV,UAAU;EAEb"}
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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 slug: project.slug,\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","slug","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,MAAML,QAAQK,IAAI;QAClBC,QAAQ;YACNC,eAAeP,QAAQQ,kBAAkB;YACzCC,wBAAwBT,QAAQU,0BAA0B;QAC5D;QACAC,YAAYX,QAAQY,SAAS,CAACC,WAAW;QACzCC,YAAYd,QAAQe,SAAS,CAACF,WAAW;IAC3C;AACF;AAEA,OAAO,SAASG,yBAAyBhB,OAA4B;IACnE,OAAO;QACLC,IAAID,QAAQC,EAAE;QACdG,MAAMJ,QAAQI,IAAI;QAClBa,QAAQ;QACRf,cAAcF,QAAQG,WAAW;QACjCQ,YAAYX,QAAQY,SAAS,CAACC,WAAW;QACzCC,YAAYd,QAAQe,SAAS,CAACF,WAAW;IAC3C;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-project.d.ts","sourceRoot":"","sources":["../../../src/presentation/e2eRoutes/create-project.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create-project.d.ts","sourceRoot":"","sources":["../../../src/presentation/e2eRoutes/create-project.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,qBAAqB,iDAwDhC,CAAC"}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { slugifyName, withSlugSuffix } from '@shipfox/api-common-dto';
|
|
2
3
|
import { e2eCreateProjectBodySchema, e2eCreateProjectResponseSchema } from '@shipfox/api-projects-dto';
|
|
3
4
|
import { ClientError, defineRoute } from '@shipfox/node-fastify';
|
|
4
|
-
import { ProjectAlreadyExistsError } from '#core/index.js';
|
|
5
|
+
import { ProjectAlreadyExistsError, ProjectSlugConflictError } from '#core/index.js';
|
|
5
6
|
import { createProject } from '#db/index.js';
|
|
6
7
|
import { toProjectDto } from '#presentation/dto/index.js';
|
|
7
8
|
function syntheticExternalRepositoryId() {
|
|
8
9
|
return `e2e:${randomUUID()}`;
|
|
9
10
|
}
|
|
11
|
+
const MAX_GENERATED_SLUG_ATTEMPTS = 5;
|
|
12
|
+
function generatedProjectSlug(slugBase) {
|
|
13
|
+
const suffix = Number.parseInt(randomUUID().replaceAll('-', '').slice(0, 8), 16);
|
|
14
|
+
return withSlugSuffix(slugBase, suffix);
|
|
15
|
+
}
|
|
10
16
|
export const createE2eProjectRoute = defineRoute({
|
|
11
17
|
method: 'POST',
|
|
12
18
|
path: '/',
|
|
@@ -28,17 +34,37 @@ export const createE2eProjectRoute = defineRoute({
|
|
|
28
34
|
status: 409
|
|
29
35
|
});
|
|
30
36
|
}
|
|
37
|
+
if (error instanceof ProjectSlugConflictError) {
|
|
38
|
+
throw new ClientError('Project slug already exists', 'slug-conflict', {
|
|
39
|
+
status: 409
|
|
40
|
+
});
|
|
41
|
+
}
|
|
31
42
|
throw error;
|
|
32
43
|
},
|
|
33
44
|
handler: async (request, reply)=>{
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
sourceConnectionId: request.body.source_connection_id ?? randomUUID(),
|
|
38
|
-
sourceExternalRepositoryId: request.body.source_external_repository_id ?? syntheticExternalRepositoryId()
|
|
45
|
+
const requestedSlug = request.body.slug;
|
|
46
|
+
const slugBase = slugifyName(request.body.name, {
|
|
47
|
+
fallback: 'project'
|
|
39
48
|
});
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
let slug = requestedSlug ?? generatedProjectSlug(slugBase);
|
|
50
|
+
for(let attempt = 0; attempt < MAX_GENERATED_SLUG_ATTEMPTS; attempt += 1){
|
|
51
|
+
try {
|
|
52
|
+
const project = await createProject({
|
|
53
|
+
workspaceId: request.body.workspace_id,
|
|
54
|
+
name: request.body.name,
|
|
55
|
+
slug,
|
|
56
|
+
sourceConnectionId: request.body.source_connection_id ?? randomUUID(),
|
|
57
|
+
sourceExternalRepositoryId: request.body.source_external_repository_id ?? syntheticExternalRepositoryId()
|
|
58
|
+
});
|
|
59
|
+
reply.code(201);
|
|
60
|
+
return toProjectDto(project);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
const shouldRetrySlug = requestedSlug === undefined && error instanceof ProjectSlugConflictError && attempt < MAX_GENERATED_SLUG_ATTEMPTS - 1;
|
|
63
|
+
if (!shouldRetrySlug) throw error;
|
|
64
|
+
slug = generatedProjectSlug(slugBase);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
throw new Error('Unable to generate a unique project slug');
|
|
42
68
|
}
|
|
43
69
|
});
|
|
44
70
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/e2eRoutes/create-project.ts"],"sourcesContent":["import {randomUUID} from 'node:crypto';\nimport {\n e2eCreateProjectBodySchema,\n e2eCreateProjectResponseSchema,\n} from '@shipfox/api-projects-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {ProjectAlreadyExistsError} from '#core/index.js';\nimport {createProject} from '#db/index.js';\nimport {toProjectDto} from '#presentation/dto/index.js';\n\nfunction syntheticExternalRepositoryId(): string {\n return `e2e:${randomUUID()}`;\n}\n\nexport const createE2eProjectRoute = defineRoute({\n method: 'POST',\n path: '/',\n description: 'Create a synthetic project for E2E tests.',\n schema: {\n body: e2eCreateProjectBodySchema,\n response: {\n 201: e2eCreateProjectResponseSchema,\n },\n },\n errorHandler: (error) => {\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 throw error;\n },\n handler: async (request, reply) => {\n const project = await createProject({\n
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/e2eRoutes/create-project.ts"],"sourcesContent":["import {randomUUID} from 'node:crypto';\nimport {slugifyName, withSlugSuffix} from '@shipfox/api-common-dto';\nimport {\n e2eCreateProjectBodySchema,\n e2eCreateProjectResponseSchema,\n} from '@shipfox/api-projects-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {ProjectAlreadyExistsError, ProjectSlugConflictError} from '#core/index.js';\nimport {createProject} from '#db/index.js';\nimport {toProjectDto} from '#presentation/dto/index.js';\n\nfunction syntheticExternalRepositoryId(): string {\n return `e2e:${randomUUID()}`;\n}\n\nconst MAX_GENERATED_SLUG_ATTEMPTS = 5;\n\nfunction generatedProjectSlug(slugBase: string): string {\n const suffix = Number.parseInt(randomUUID().replaceAll('-', '').slice(0, 8), 16);\n return withSlugSuffix(slugBase, suffix);\n}\n\nexport const createE2eProjectRoute = defineRoute({\n method: 'POST',\n path: '/',\n description: 'Create a synthetic project for E2E tests.',\n schema: {\n body: e2eCreateProjectBodySchema,\n response: {\n 201: e2eCreateProjectResponseSchema,\n },\n },\n errorHandler: (error) => {\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 throw error;\n },\n handler: async (request, reply) => {\n const requestedSlug = request.body.slug;\n const slugBase = slugifyName(request.body.name, {fallback: 'project'});\n let slug = requestedSlug ?? generatedProjectSlug(slugBase);\n\n for (let attempt = 0; attempt < MAX_GENERATED_SLUG_ATTEMPTS; attempt += 1) {\n try {\n const project = await createProject({\n workspaceId: request.body.workspace_id,\n name: request.body.name,\n slug,\n sourceConnectionId: request.body.source_connection_id ?? randomUUID(),\n sourceExternalRepositoryId:\n request.body.source_external_repository_id ?? syntheticExternalRepositoryId(),\n });\n\n reply.code(201);\n return toProjectDto(project);\n } catch (error) {\n const shouldRetrySlug =\n requestedSlug === undefined &&\n error instanceof ProjectSlugConflictError &&\n attempt < MAX_GENERATED_SLUG_ATTEMPTS - 1;\n if (!shouldRetrySlug) throw error;\n slug = generatedProjectSlug(slugBase);\n }\n }\n\n throw new Error('Unable to generate a unique project slug');\n },\n});\n"],"names":["randomUUID","slugifyName","withSlugSuffix","e2eCreateProjectBodySchema","e2eCreateProjectResponseSchema","ClientError","defineRoute","ProjectAlreadyExistsError","ProjectSlugConflictError","createProject","toProjectDto","syntheticExternalRepositoryId","MAX_GENERATED_SLUG_ATTEMPTS","generatedProjectSlug","slugBase","suffix","Number","parseInt","replaceAll","slice","createE2eProjectRoute","method","path","description","schema","body","response","errorHandler","error","message","details","existing_project_id","existingProjectId","source_connection_id","sourceConnectionId","source_external_repository_id","sourceExternalRepositoryId","status","handler","request","reply","requestedSlug","slug","name","fallback","attempt","project","workspaceId","workspace_id","code","shouldRetrySlug","undefined","Error"],"mappings":"AAAA,SAAQA,UAAU,QAAO,cAAc;AACvC,SAAQC,WAAW,EAAEC,cAAc,QAAO,0BAA0B;AACpE,SACEC,0BAA0B,EAC1BC,8BAA8B,QACzB,4BAA4B;AACnC,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,yBAAyB,EAAEC,wBAAwB,QAAO,iBAAiB;AACnF,SAAQC,aAAa,QAAO,eAAe;AAC3C,SAAQC,YAAY,QAAO,6BAA6B;AAExD,SAASC;IACP,OAAO,CAAC,IAAI,EAAEX,cAAc;AAC9B;AAEA,MAAMY,8BAA8B;AAEpC,SAASC,qBAAqBC,QAAgB;IAC5C,MAAMC,SAASC,OAAOC,QAAQ,CAACjB,aAAakB,UAAU,CAAC,KAAK,IAAIC,KAAK,CAAC,GAAG,IAAI;IAC7E,OAAOjB,eAAeY,UAAUC;AAClC;AAEA,OAAO,MAAMK,wBAAwBd,YAAY;IAC/Ce,QAAQ;IACRC,MAAM;IACNC,aAAa;IACbC,QAAQ;QACNC,MAAMtB;QACNuB,UAAU;YACR,KAAKtB;QACP;IACF;IACAuB,cAAc,CAACC;QACb,IAAIA,iBAAiBrB,2BAA2B;YAC9C,MAAM,IAAIF,YAAYuB,MAAMC,OAAO,EAAE,0BAA0B;gBAC7DC,SAAS;oBACPC,qBAAqBH,MAAMI,iBAAiB;oBAC5CC,sBAAsBL,MAAMM,kBAAkB;oBAC9CC,+BAA+BP,MAAMQ,0BAA0B;gBACjE;gBACAC,QAAQ;YACV;QACF;QACA,IAAIT,iBAAiBpB,0BAA0B;YAC7C,MAAM,IAAIH,YAAY,+BAA+B,iBAAiB;gBAACgC,QAAQ;YAAG;QACpF;QACA,MAAMT;IACR;IACAU,SAAS,OAAOC,SAASC;QACvB,MAAMC,gBAAgBF,QAAQd,IAAI,CAACiB,IAAI;QACvC,MAAM5B,WAAWb,YAAYsC,QAAQd,IAAI,CAACkB,IAAI,EAAE;YAACC,UAAU;QAAS;QACpE,IAAIF,OAAOD,iBAAiB5B,qBAAqBC;QAEjD,IAAK,IAAI+B,UAAU,GAAGA,UAAUjC,6BAA6BiC,WAAW,EAAG;YACzE,IAAI;gBACF,MAAMC,UAAU,MAAMrC,cAAc;oBAClCsC,aAAaR,QAAQd,IAAI,CAACuB,YAAY;oBACtCL,MAAMJ,QAAQd,IAAI,CAACkB,IAAI;oBACvBD;oBACAR,oBAAoBK,QAAQd,IAAI,CAACQ,oBAAoB,IAAIjC;oBACzDoC,4BACEG,QAAQd,IAAI,CAACU,6BAA6B,IAAIxB;gBAClD;gBAEA6B,MAAMS,IAAI,CAAC;gBACX,OAAOvC,aAAaoC;YACtB,EAAE,OAAOlB,OAAO;gBACd,MAAMsB,kBACJT,kBAAkBU,aAClBvB,iBAAiBpB,4BACjBqC,UAAUjC,8BAA8B;gBAC1C,IAAI,CAACsC,iBAAiB,MAAMtB;gBAC5Bc,OAAO7B,qBAAqBC;YAC9B;QACF;QAEA,MAAM,IAAIsC,MAAM;IAClB;AACF,GAAG"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import type { IntegrationsModuleClient } from '@shipfox/api-integration-core-dto/inter-module';
|
|
1
2
|
import { projectsInterModuleContract } from '@shipfox/api-projects-dto/inter-module';
|
|
2
3
|
import { type InterModulePresentation } from '@shipfox/inter-module';
|
|
3
|
-
export declare function createProjectsInterModulePresentation(
|
|
4
|
+
export declare function createProjectsInterModulePresentation(params: {
|
|
5
|
+
integrations: Pick<IntegrationsModuleClient, 'resolveSourceRepository'>;
|
|
6
|
+
}): InterModulePresentation<typeof projectsInterModuleContract>;
|
|
4
7
|
//# sourceMappingURL=inter-module.d.ts.map
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"inter-module.d.ts","sourceRoot":"","sources":["../../src/presentation/inter-module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,gDAAgD,CAAC;AAC7F,OAAO,EAAC,2BAA2B,EAAC,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAC;AAU/B,wBAAgB,qCAAqC,CAAC,MAAM,EAAE;IAC5D,YAAY,EAAE,IAAI,CAAC,wBAAwB,EAAE,yBAAyB,CAAC,CAAC;CACzE,GAAG,uBAAuB,CAAC,OAAO,2BAA2B,CAAC,CAuG9D"}
|
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
import { projectsInterModuleContract } from '@shipfox/api-projects-dto/inter-module';
|
|
2
2
|
import { createInterModuleKnownError, defineInterModulePresentation } from '@shipfox/inter-module';
|
|
3
|
-
import { getProjectById, getWorkspaceProjectCounts } from '#db/projects.js';
|
|
4
|
-
export function createProjectsInterModulePresentation() {
|
|
3
|
+
import { getProjectById, getProjectBySource, getWorkspaceProjectCounts, listProjects, resolveCheckoutTarget, updateProjectSourceMetadata } from '#db/projects.js';
|
|
4
|
+
export function createProjectsInterModulePresentation(params) {
|
|
5
5
|
return defineInterModulePresentation(projectsInterModuleContract, {
|
|
6
6
|
getProjectById: async ({ projectId })=>({
|
|
7
7
|
project: await getProjectById(projectId) ?? null
|
|
8
8
|
}),
|
|
9
|
+
getProjectBySource: async (input)=>({
|
|
10
|
+
project: await getProjectBySource(input) ?? null
|
|
11
|
+
}),
|
|
12
|
+
listProjectsByWorkspace: async ({ workspaceId, limit, cursor })=>{
|
|
13
|
+
const result = await listProjects({
|
|
14
|
+
workspaceId,
|
|
15
|
+
limit,
|
|
16
|
+
...cursor ? {
|
|
17
|
+
cursor: {
|
|
18
|
+
createdAt: new Date(cursor.createdAt),
|
|
19
|
+
id: cursor.id
|
|
20
|
+
}
|
|
21
|
+
} : {}
|
|
22
|
+
});
|
|
23
|
+
return {
|
|
24
|
+
projects: result.projects,
|
|
25
|
+
nextCursor: result.nextCursor ? {
|
|
26
|
+
createdAt: result.nextCursor.createdAt.toISOString(),
|
|
27
|
+
id: result.nextCursor.id
|
|
28
|
+
} : null
|
|
29
|
+
};
|
|
30
|
+
},
|
|
9
31
|
requireProjectForWorkspace: async ({ projectId, workspaceId })=>{
|
|
10
32
|
const project = await getProjectById(projectId);
|
|
11
33
|
if (project === undefined) {
|
|
@@ -27,7 +49,45 @@ export function createProjectsInterModulePresentation() {
|
|
|
27
49
|
counts: await getWorkspaceProjectCounts({
|
|
28
50
|
workspaceIds
|
|
29
51
|
})
|
|
30
|
-
})
|
|
52
|
+
}),
|
|
53
|
+
resolveCheckoutTarget: async (input)=>{
|
|
54
|
+
const target = await resolveCheckoutTarget(input);
|
|
55
|
+
if (target === undefined) {
|
|
56
|
+
throw createInterModuleKnownError(projectsInterModuleContract.methods.resolveCheckoutTarget, 'checkout-repository-not-authorized', {});
|
|
57
|
+
}
|
|
58
|
+
if ('repository' in input.target) {
|
|
59
|
+
const source = await params.integrations.resolveSourceRepository({
|
|
60
|
+
workspaceId: input.workspaceId,
|
|
61
|
+
connectionId: target.connectionId,
|
|
62
|
+
externalRepositoryId: target.externalRepositoryId
|
|
63
|
+
}).catch(()=>undefined);
|
|
64
|
+
if (source === undefined) {
|
|
65
|
+
throw createInterModuleKnownError(projectsInterModuleContract.methods.resolveCheckoutTarget, 'checkout-repository-not-authorized', {});
|
|
66
|
+
}
|
|
67
|
+
const separator = input.target.repository.indexOf('/');
|
|
68
|
+
const requestedOwner = separator === -1 ? input.defaults.owner : input.target.repository.slice(0, separator);
|
|
69
|
+
const requestedName = separator === -1 ? input.target.repository : input.target.repository.slice(separator + 1);
|
|
70
|
+
const repositoryMatches = source.repository.owner.toLowerCase() === requestedOwner.toLowerCase() && source.repository.name.toLowerCase() === requestedName.toLowerCase();
|
|
71
|
+
await updateProjectSourceMetadata({
|
|
72
|
+
workspaceId: input.workspaceId,
|
|
73
|
+
projectId: target.projectId,
|
|
74
|
+
sourceConnectionId: source.connection.id,
|
|
75
|
+
sourceExternalRepositoryId: source.repository.externalRepositoryId,
|
|
76
|
+
sourceRepositoryOwner: source.repository.owner,
|
|
77
|
+
sourceRepositoryName: source.repository.name,
|
|
78
|
+
sourceDefaultBranch: source.repository.defaultBranch
|
|
79
|
+
});
|
|
80
|
+
if (!repositoryMatches) {
|
|
81
|
+
throw createInterModuleKnownError(projectsInterModuleContract.methods.resolveCheckoutTarget, 'checkout-repository-not-authorized', {});
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
...target,
|
|
85
|
+
connectionId: source.connection.id,
|
|
86
|
+
externalRepositoryId: source.repository.externalRepositoryId
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return target;
|
|
90
|
+
}
|
|
31
91
|
});
|
|
32
92
|
}
|
|
33
93
|
|
|
@@ -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
|
|
1
|
+
{"version":3,"sources":["../../src/presentation/inter-module.ts"],"sourcesContent":["import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';\nimport {projectsInterModuleContract} from '@shipfox/api-projects-dto/inter-module';\nimport {\n createInterModuleKnownError,\n defineInterModulePresentation,\n type InterModulePresentation,\n} from '@shipfox/inter-module';\nimport {\n getProjectById,\n getProjectBySource,\n getWorkspaceProjectCounts,\n listProjects,\n resolveCheckoutTarget,\n updateProjectSourceMetadata,\n} from '#db/projects.js';\n\nexport function createProjectsInterModulePresentation(params: {\n integrations: Pick<IntegrationsModuleClient, 'resolveSourceRepository'>;\n}): InterModulePresentation<typeof projectsInterModuleContract> {\n return defineInterModulePresentation(projectsInterModuleContract, {\n getProjectById: async ({projectId}) => ({project: (await getProjectById(projectId)) ?? null}),\n getProjectBySource: async (input) => ({\n project: (await getProjectBySource(input)) ?? null,\n }),\n listProjectsByWorkspace: async ({workspaceId, limit, cursor}) => {\n const result = await listProjects({\n workspaceId,\n limit,\n ...(cursor ? {cursor: {createdAt: new Date(cursor.createdAt), id: cursor.id}} : {}),\n });\n return {\n projects: result.projects,\n nextCursor: result.nextCursor\n ? {createdAt: result.nextCursor.createdAt.toISOString(), id: result.nextCursor.id}\n : null,\n };\n },\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 resolveCheckoutTarget: async (input) => {\n const target = await resolveCheckoutTarget(input);\n if (target === undefined) {\n throw createInterModuleKnownError(\n projectsInterModuleContract.methods.resolveCheckoutTarget,\n 'checkout-repository-not-authorized',\n {},\n );\n }\n\n if ('repository' in input.target) {\n const source = await params.integrations\n .resolveSourceRepository({\n workspaceId: input.workspaceId,\n connectionId: target.connectionId,\n externalRepositoryId: target.externalRepositoryId,\n })\n .catch(() => undefined);\n if (source === undefined) {\n throw createInterModuleKnownError(\n projectsInterModuleContract.methods.resolveCheckoutTarget,\n 'checkout-repository-not-authorized',\n {},\n );\n }\n\n const separator = input.target.repository.indexOf('/');\n const requestedOwner =\n separator === -1 ? input.defaults.owner : input.target.repository.slice(0, separator);\n const requestedName =\n separator === -1 ? input.target.repository : input.target.repository.slice(separator + 1);\n const repositoryMatches =\n source.repository.owner.toLowerCase() === requestedOwner.toLowerCase() &&\n source.repository.name.toLowerCase() === requestedName.toLowerCase();\n\n await updateProjectSourceMetadata({\n workspaceId: input.workspaceId,\n projectId: target.projectId,\n sourceConnectionId: source.connection.id,\n sourceExternalRepositoryId: source.repository.externalRepositoryId,\n sourceRepositoryOwner: source.repository.owner,\n sourceRepositoryName: source.repository.name,\n sourceDefaultBranch: source.repository.defaultBranch,\n });\n\n if (!repositoryMatches) {\n throw createInterModuleKnownError(\n projectsInterModuleContract.methods.resolveCheckoutTarget,\n 'checkout-repository-not-authorized',\n {},\n );\n }\n\n return {\n ...target,\n connectionId: source.connection.id,\n externalRepositoryId: source.repository.externalRepositoryId,\n };\n }\n\n return target;\n },\n });\n}\n"],"names":["projectsInterModuleContract","createInterModuleKnownError","defineInterModulePresentation","getProjectById","getProjectBySource","getWorkspaceProjectCounts","listProjects","resolveCheckoutTarget","updateProjectSourceMetadata","createProjectsInterModulePresentation","params","projectId","project","input","listProjectsByWorkspace","workspaceId","limit","cursor","result","createdAt","Date","id","projects","nextCursor","toISOString","requireProjectForWorkspace","undefined","methods","workspaceIds","counts","target","source","integrations","resolveSourceRepository","connectionId","externalRepositoryId","catch","separator","repository","indexOf","requestedOwner","defaults","owner","slice","requestedName","repositoryMatches","toLowerCase","name","sourceConnectionId","connection","sourceExternalRepositoryId","sourceRepositoryOwner","sourceRepositoryName","sourceDefaultBranch","defaultBranch"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-project.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/create-project.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,wBAAwB,EAE9B,MAAM,gDAAgD,CAAC;
|
|
1
|
+
{"version":3,"file":"create-project.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/create-project.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,wBAAwB,EAE9B,MAAM,gDAAgD,CAAC;AAiBxD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,wBAAwB,mDAwFxE"}
|
|
@@ -3,7 +3,7 @@ import { integrationsInterModuleContract } from '@shipfox/api-integration-core-d
|
|
|
3
3
|
import { createProjectBodySchema, projectResponseSchema } from '@shipfox/api-projects-dto';
|
|
4
4
|
import { isInterModuleKnownError } from '@shipfox/inter-module';
|
|
5
5
|
import { ClientError, defineRoute } from '@shipfox/node-fastify';
|
|
6
|
-
import { createProjectFromSource, ProjectAlreadyExistsError } from '#core/index.js';
|
|
6
|
+
import { createProjectFromSource, ProjectAlreadyExistsError, ProjectSlugConflictError } from '#core/index.js';
|
|
7
7
|
import { toProjectDto } from '#presentation/dto/index.js';
|
|
8
8
|
function providerStatus(reason) {
|
|
9
9
|
if (reason === 'rate-limited') return 429;
|
|
@@ -59,6 +59,11 @@ export function createProjectRoute(integrations) {
|
|
|
59
59
|
status: 409
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
|
+
if (error instanceof ProjectSlugConflictError) {
|
|
63
|
+
throw new ClientError('Project slug already exists', 'slug-conflict', {
|
|
64
|
+
status: 409
|
|
65
|
+
});
|
|
66
|
+
}
|
|
62
67
|
if (known?.code === 'provider-failure') {
|
|
63
68
|
throw new ClientError('Integration provider request failed', known.details.reason, {
|
|
64
69
|
details: {
|
|
@@ -70,7 +75,7 @@ export function createProjectRoute(integrations) {
|
|
|
70
75
|
throw error;
|
|
71
76
|
},
|
|
72
77
|
handler: async (request, reply)=>{
|
|
73
|
-
const { workspace_id: workspaceId, name, source } = request.body;
|
|
78
|
+
const { workspace_id: workspaceId, name, slug, source } = request.body;
|
|
74
79
|
const actor = requireUserContext(request);
|
|
75
80
|
requireWorkspaceAccess({
|
|
76
81
|
request,
|
|
@@ -80,6 +85,7 @@ export function createProjectRoute(integrations) {
|
|
|
80
85
|
actorId: actor.userId,
|
|
81
86
|
workspaceId,
|
|
82
87
|
name,
|
|
88
|
+
slug,
|
|
83
89
|
sourceConnectionId: source.connection_id,
|
|
84
90
|
sourceExternalRepositoryId: source.external_repository_id,
|
|
85
91
|
integrations
|