2
0

project_integration.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. package router
  2. import (
  3. "fmt"
  4. "github.com/go-chi/chi/v5"
  5. project_integration "github.com/porter-dev/porter/api/server/handlers/project_integration"
  6. "github.com/porter-dev/porter/api/server/shared"
  7. "github.com/porter-dev/porter/api/server/shared/config"
  8. "github.com/porter-dev/porter/api/server/shared/router"
  9. "github.com/porter-dev/porter/api/types"
  10. )
  11. func NewProjectIntegrationScopedRegisterer(children ...*router.Registerer) *router.Registerer {
  12. return &router.Registerer{
  13. GetRoutes: GetProjectIntegrationScopedRoutes,
  14. Children: children,
  15. }
  16. }
  17. func GetProjectIntegrationScopedRoutes(
  18. r chi.Router,
  19. config *config.Config,
  20. basePath *types.Path,
  21. factory shared.APIEndpointFactory,
  22. children ...*router.Registerer,
  23. ) []*router.Route {
  24. routes, projPath := getProjectIntegrationRoutes(r, config, basePath, factory)
  25. if len(children) > 0 {
  26. r.Route(projPath.RelativePath, func(r chi.Router) {
  27. for _, child := range children {
  28. childRoutes := child.GetRoutes(r, config, basePath, factory, child.Children...)
  29. routes = append(routes, childRoutes...)
  30. }
  31. })
  32. }
  33. return routes
  34. }
  35. func getProjectIntegrationRoutes(
  36. r chi.Router,
  37. config *config.Config,
  38. basePath *types.Path,
  39. factory shared.APIEndpointFactory,
  40. ) ([]*router.Route, *types.Path) {
  41. relPath := "/integrations"
  42. newPath := &types.Path{
  43. Parent: basePath,
  44. RelativePath: relPath,
  45. }
  46. routes := make([]*router.Route, 0)
  47. // GET /api/projects/{project_id}/integrations/oauth -> project_integration.NewListOAuthHandler
  48. listOAuthEndpoint := factory.NewAPIEndpoint(
  49. &types.APIRequestMetadata{
  50. Verb: types.APIVerbGet,
  51. Method: types.HTTPVerbGet,
  52. Path: &types.Path{
  53. Parent: basePath,
  54. RelativePath: relPath + "/oauth",
  55. },
  56. Scopes: []types.PermissionScope{
  57. types.UserScope,
  58. types.ProjectScope,
  59. },
  60. },
  61. )
  62. listOAuthHandler := project_integration.NewListOAuthHandler(
  63. config,
  64. factory.GetResultWriter(),
  65. )
  66. routes = append(routes, &router.Route{
  67. Endpoint: listOAuthEndpoint,
  68. Handler: listOAuthHandler,
  69. Router: r,
  70. })
  71. // GET /api/projects/{project_id}/integrations/do -> project_integration.NewListDOHandler
  72. listDOEndpoint := factory.NewAPIEndpoint(
  73. &types.APIRequestMetadata{
  74. Verb: types.APIVerbGet,
  75. Method: types.HTTPVerbGet,
  76. Path: &types.Path{
  77. Parent: basePath,
  78. RelativePath: relPath + "/do",
  79. },
  80. Scopes: []types.PermissionScope{
  81. types.UserScope,
  82. types.ProjectScope,
  83. },
  84. },
  85. )
  86. listDOHandler := project_integration.NewListDOHandler(
  87. config,
  88. factory.GetResultWriter(),
  89. )
  90. routes = append(routes, &router.Route{
  91. Endpoint: listDOEndpoint,
  92. Handler: listDOHandler,
  93. Router: r,
  94. })
  95. // POST /api/projects/{project_id}/integrations/basic -> project_integration.NewCreateBasicHandler
  96. createBasicEndpoint := factory.NewAPIEndpoint(
  97. &types.APIRequestMetadata{
  98. Verb: types.APIVerbCreate,
  99. Method: types.HTTPVerbPost,
  100. Path: &types.Path{
  101. Parent: basePath,
  102. RelativePath: relPath + "/basic",
  103. },
  104. Scopes: []types.PermissionScope{
  105. types.UserScope,
  106. types.ProjectScope,
  107. },
  108. },
  109. )
  110. createBasicHandler := project_integration.NewCreateBasicHandler(
  111. config,
  112. factory.GetDecoderValidator(),
  113. factory.GetResultWriter(),
  114. )
  115. routes = append(routes, &router.Route{
  116. Endpoint: createBasicEndpoint,
  117. Handler: createBasicHandler,
  118. Router: r,
  119. })
  120. // POST /api/projects/{project_id}/integrations/aws -> project_integration.NewCreateAWSHandler
  121. createAWSEndpoint := factory.NewAPIEndpoint(
  122. &types.APIRequestMetadata{
  123. Verb: types.APIVerbCreate,
  124. Method: types.HTTPVerbPost,
  125. Path: &types.Path{
  126. Parent: basePath,
  127. RelativePath: relPath + "/aws",
  128. },
  129. Scopes: []types.PermissionScope{
  130. types.UserScope,
  131. types.ProjectScope,
  132. },
  133. },
  134. )
  135. createAWSHandler := project_integration.NewCreateAWSHandler(
  136. config,
  137. factory.GetDecoderValidator(),
  138. factory.GetResultWriter(),
  139. )
  140. routes = append(routes, &router.Route{
  141. Endpoint: createAWSEndpoint,
  142. Handler: createAWSHandler,
  143. Router: r,
  144. })
  145. // GET /api/projects/{project_id}/integrations/aws -> project_integration.NewListAWSHandler
  146. listAWSEndpoint := factory.NewAPIEndpoint(
  147. &types.APIRequestMetadata{
  148. Verb: types.APIVerbGet,
  149. Method: types.HTTPVerbGet,
  150. Path: &types.Path{
  151. Parent: basePath,
  152. RelativePath: relPath + "/aws",
  153. },
  154. Scopes: []types.PermissionScope{
  155. types.UserScope,
  156. types.ProjectScope,
  157. },
  158. },
  159. )
  160. listAWSHandler := project_integration.NewListAWSHandler(
  161. config,
  162. factory.GetResultWriter(),
  163. )
  164. routes = append(routes, &router.Route{
  165. Endpoint: listAWSEndpoint,
  166. Handler: listAWSHandler,
  167. Router: r,
  168. })
  169. // POST /api/projects/{project_id}/integrations/aws/overwrite -> project_integration.NewOverwriteAWSHandler
  170. overwriteAWSEndpoint := factory.NewAPIEndpoint(
  171. &types.APIRequestMetadata{
  172. Verb: types.APIVerbCreate,
  173. Method: types.HTTPVerbPost,
  174. Path: &types.Path{
  175. Parent: basePath,
  176. RelativePath: relPath + "/aws/overwrite",
  177. },
  178. Scopes: []types.PermissionScope{
  179. types.UserScope,
  180. types.ProjectScope,
  181. },
  182. },
  183. )
  184. overwriteAWSHandler := project_integration.NewOverwriteAWSHandler(
  185. config,
  186. factory.GetDecoderValidator(),
  187. factory.GetResultWriter(),
  188. )
  189. routes = append(routes, &router.Route{
  190. Endpoint: overwriteAWSEndpoint,
  191. Handler: overwriteAWSHandler,
  192. Router: r,
  193. })
  194. // POST /api/projects/{project_id}/integrations/preflightcheck -> project_integration.NewCreatePreflightCheckHandler
  195. preflightCheckEndpoint := factory.NewAPIEndpoint(
  196. &types.APIRequestMetadata{
  197. Verb: types.APIVerbCreate,
  198. Method: types.HTTPVerbPost,
  199. Path: &types.Path{
  200. Parent: basePath,
  201. RelativePath: relPath + "/preflightcheck",
  202. },
  203. Scopes: []types.PermissionScope{
  204. types.UserScope,
  205. types.ProjectScope,
  206. },
  207. },
  208. )
  209. preflightCheckHandler := project_integration.NewCreatePreflightCheckHandler(
  210. config,
  211. factory.GetDecoderValidator(),
  212. factory.GetResultWriter(),
  213. )
  214. routes = append(routes, &router.Route{
  215. Endpoint: preflightCheckEndpoint,
  216. Handler: preflightCheckHandler,
  217. Router: r,
  218. })
  219. // POST /api/projects/{project_id}/integrations/quotaincrease -> project_integration.NewCreatePreflightCheckHandler
  220. requestQuotaIncreaseEndpoint := factory.NewAPIEndpoint(
  221. &types.APIRequestMetadata{
  222. Verb: types.APIVerbCreate,
  223. Method: types.HTTPVerbPost,
  224. Path: &types.Path{
  225. Parent: basePath,
  226. RelativePath: relPath + "/quotaincrease",
  227. },
  228. Scopes: []types.PermissionScope{
  229. types.UserScope,
  230. types.ProjectScope,
  231. },
  232. },
  233. )
  234. requestQuotaIncreaseHandler := project_integration.NewRequestQuotaIncreaseHandler(
  235. config,
  236. factory.GetDecoderValidator(),
  237. factory.GetResultWriter(),
  238. )
  239. routes = append(routes, &router.Route{
  240. Endpoint: requestQuotaIncreaseEndpoint,
  241. Handler: requestQuotaIncreaseHandler,
  242. Router: r,
  243. })
  244. // GET /api/projects/{project_id}/integrations/azure -> project_integration.NewListAzureHandler
  245. listAzureEndpoint := factory.NewAPIEndpoint(
  246. &types.APIRequestMetadata{
  247. Verb: types.APIVerbGet,
  248. Method: types.HTTPVerbGet,
  249. Path: &types.Path{
  250. Parent: basePath,
  251. RelativePath: relPath + "/azure",
  252. },
  253. Scopes: []types.PermissionScope{
  254. types.UserScope,
  255. types.ProjectScope,
  256. },
  257. },
  258. )
  259. listAzureHandler := project_integration.NewListAzureHandler(
  260. config,
  261. factory.GetResultWriter(),
  262. )
  263. routes = append(routes, &router.Route{
  264. Endpoint: listAzureEndpoint,
  265. Handler: listAzureHandler,
  266. Router: r,
  267. })
  268. // POST /api/projects/{project_id}/integrations/gcp -> project_integration.NewCreateGCPHandler
  269. createGCPEndpoint := factory.NewAPIEndpoint(
  270. &types.APIRequestMetadata{
  271. Verb: types.APIVerbCreate,
  272. Method: types.HTTPVerbPost,
  273. Path: &types.Path{
  274. Parent: basePath,
  275. RelativePath: relPath + "/gcp",
  276. },
  277. Scopes: []types.PermissionScope{
  278. types.UserScope,
  279. types.ProjectScope,
  280. },
  281. },
  282. )
  283. createGCPHandler := project_integration.NewCreateGCPHandler(
  284. config,
  285. factory.GetDecoderValidator(),
  286. factory.GetResultWriter(),
  287. )
  288. routes = append(routes, &router.Route{
  289. Endpoint: createGCPEndpoint,
  290. Handler: createGCPHandler,
  291. Router: r,
  292. })
  293. // GET /api/projects/{project_id}/integrations/gcp -> project_integration.NewListGCPHandler
  294. listGCPEndpoint := factory.NewAPIEndpoint(
  295. &types.APIRequestMetadata{
  296. Verb: types.APIVerbGet,
  297. Method: types.HTTPVerbGet,
  298. Path: &types.Path{
  299. Parent: basePath,
  300. RelativePath: relPath + "/gcp",
  301. },
  302. Scopes: []types.PermissionScope{
  303. types.UserScope,
  304. types.ProjectScope,
  305. },
  306. },
  307. )
  308. listGCPHandler := project_integration.NewListGCPHandler(
  309. config,
  310. factory.GetResultWriter(),
  311. )
  312. routes = append(routes, &router.Route{
  313. Endpoint: listGCPEndpoint,
  314. Handler: listGCPHandler,
  315. Router: r,
  316. })
  317. // POST /api/projects/{project_id}/integrations/azure -> project_integration.NewCreateAzureHandler
  318. createAzureEndpoint := factory.NewAPIEndpoint(
  319. &types.APIRequestMetadata{
  320. Verb: types.APIVerbCreate,
  321. Method: types.HTTPVerbPost,
  322. Path: &types.Path{
  323. Parent: basePath,
  324. RelativePath: relPath + "/azure",
  325. },
  326. Scopes: []types.PermissionScope{
  327. types.UserScope,
  328. types.ProjectScope,
  329. },
  330. },
  331. )
  332. createAzureHandler := project_integration.NewCreateAzureHandler(
  333. config,
  334. factory.GetDecoderValidator(),
  335. factory.GetResultWriter(),
  336. )
  337. routes = append(routes, &router.Route{
  338. Endpoint: createAzureEndpoint,
  339. Handler: createAzureHandler,
  340. Router: r,
  341. })
  342. // GET /api/projects/{project_id}/integrations/gitlab
  343. listGitlabEndpoint := factory.NewAPIEndpoint(
  344. &types.APIRequestMetadata{
  345. Verb: types.APIVerbGet,
  346. Method: types.HTTPVerbGet,
  347. Path: &types.Path{
  348. Parent: basePath,
  349. RelativePath: relPath + "/gitlab",
  350. },
  351. Scopes: []types.PermissionScope{
  352. types.UserScope,
  353. types.ProjectScope,
  354. },
  355. },
  356. )
  357. listGitlabHandler := project_integration.NewListGitlabHandler(
  358. config,
  359. factory.GetResultWriter(),
  360. )
  361. routes = append(routes, &router.Route{
  362. Endpoint: listGitlabEndpoint,
  363. Handler: listGitlabHandler,
  364. Router: r,
  365. })
  366. // POST /api/projects/{project_id}/integrations/gitlab
  367. createGitlabEndpoint := factory.NewAPIEndpoint(
  368. &types.APIRequestMetadata{
  369. Verb: types.APIVerbCreate,
  370. Method: types.HTTPVerbPost,
  371. Path: &types.Path{
  372. Parent: basePath,
  373. RelativePath: relPath + "/gitlab",
  374. },
  375. Scopes: []types.PermissionScope{
  376. types.UserScope,
  377. types.ProjectScope,
  378. },
  379. },
  380. )
  381. createGitlabHandler := project_integration.NewCreateGitlabIntegration(
  382. config,
  383. factory.GetDecoderValidator(),
  384. factory.GetResultWriter(),
  385. )
  386. routes = append(routes, &router.Route{
  387. Endpoint: createGitlabEndpoint,
  388. Handler: createGitlabHandler,
  389. Router: r,
  390. })
  391. // PATCH /api/projects/{project_id}/integrations/gitlab/{integration_id}
  392. // DELETE /api/projects/{project_id}/integrations/gitlab/{integration_id}
  393. deleteGitlabEndpoint := factory.NewAPIEndpoint(
  394. &types.APIRequestMetadata{
  395. Verb: types.APIVerbDelete,
  396. Method: types.HTTPVerbDelete,
  397. Path: &types.Path{
  398. Parent: basePath,
  399. RelativePath: relPath + "/gitlab/{integration_id}",
  400. },
  401. Scopes: []types.PermissionScope{
  402. types.UserScope,
  403. types.ProjectScope,
  404. types.GitlabIntegrationScope,
  405. },
  406. },
  407. )
  408. deleteGitlabHandler := project_integration.NewDeleteGitlabIntegrationHandler(
  409. config,
  410. factory.GetDecoderValidator(),
  411. factory.GetResultWriter(),
  412. )
  413. routes = append(routes, &router.Route{
  414. Endpoint: deleteGitlabEndpoint,
  415. Handler: deleteGitlabHandler,
  416. Router: r,
  417. })
  418. // GET /api/projects/{project_id}/integrations/git
  419. listGitIntegrationsEndpoint := factory.NewAPIEndpoint(
  420. &types.APIRequestMetadata{
  421. Verb: types.APIVerbGet,
  422. Method: types.HTTPVerbGet,
  423. Path: &types.Path{
  424. Parent: basePath,
  425. RelativePath: relPath + "/git",
  426. },
  427. Scopes: []types.PermissionScope{
  428. types.UserScope,
  429. types.ProjectScope,
  430. },
  431. },
  432. )
  433. listGitIntegrationsHandler := project_integration.NewListGitIntegrationHandler(
  434. config,
  435. factory.GetDecoderValidator(),
  436. factory.GetResultWriter(),
  437. )
  438. routes = append(routes, &router.Route{
  439. Endpoint: listGitIntegrationsEndpoint,
  440. Handler: listGitIntegrationsHandler,
  441. Router: r,
  442. })
  443. // GET /api/projects/{project_id}/integrations/gitlab/{integration_id}/repos
  444. listGitlabReposEndpoint := factory.NewAPIEndpoint(
  445. &types.APIRequestMetadata{
  446. Verb: types.APIVerbGet,
  447. Method: types.HTTPVerbGet,
  448. Path: &types.Path{
  449. Parent: basePath,
  450. RelativePath: fmt.Sprintf("%s/gitlab/{%s}/repos", relPath, types.URLParamIntegrationID),
  451. },
  452. Scopes: []types.PermissionScope{
  453. types.UserScope,
  454. types.ProjectScope,
  455. types.GitlabIntegrationScope,
  456. },
  457. },
  458. )
  459. listGitlabReposHandler := project_integration.NewListGitlabReposHandler(
  460. config,
  461. factory.GetDecoderValidator(),
  462. factory.GetResultWriter(),
  463. )
  464. routes = append(routes, &router.Route{
  465. Endpoint: listGitlabReposEndpoint,
  466. Handler: listGitlabReposHandler,
  467. Router: r,
  468. })
  469. // GET /api/projects/{project_id}/integrations/gitlab/{integration_id}/repos/branches
  470. listGitlabRepoBranchesEndpoint := factory.NewAPIEndpoint(
  471. &types.APIRequestMetadata{
  472. Verb: types.APIVerbGet,
  473. Method: types.HTTPVerbGet,
  474. Path: &types.Path{
  475. Parent: basePath,
  476. RelativePath: fmt.Sprintf("%s/gitlab/{%s}/repos/branches",
  477. relPath, types.URLParamIntegrationID),
  478. },
  479. Scopes: []types.PermissionScope{
  480. types.UserScope,
  481. types.ProjectScope,
  482. types.GitlabIntegrationScope,
  483. },
  484. },
  485. )
  486. listGitlabRepoBranchesHandler := project_integration.NewListGitlabRepoBranchesHandler(
  487. config,
  488. factory.GetDecoderValidator(),
  489. factory.GetResultWriter(),
  490. )
  491. routes = append(routes, &router.Route{
  492. Endpoint: listGitlabRepoBranchesEndpoint,
  493. Handler: listGitlabRepoBranchesHandler,
  494. Router: r,
  495. })
  496. // GET /api/projects/{project_id}/integrations/gitlab/{integration_id}/repos/contents
  497. getGitlabRepoContentsEndpoint := factory.NewAPIEndpoint(
  498. &types.APIRequestMetadata{
  499. Verb: types.APIVerbGet,
  500. Method: types.HTTPVerbGet,
  501. Path: &types.Path{
  502. Parent: basePath,
  503. RelativePath: fmt.Sprintf("%s/gitlab/{%s}/repos/contents", relPath,
  504. types.URLParamIntegrationID),
  505. },
  506. Scopes: []types.PermissionScope{
  507. types.UserScope,
  508. types.ProjectScope,
  509. types.GitlabIntegrationScope,
  510. },
  511. },
  512. )
  513. getGitlabRepoContentsHandler := project_integration.NewGetGitlabRepoContentsHandler(
  514. config,
  515. factory.GetDecoderValidator(),
  516. factory.GetResultWriter(),
  517. )
  518. routes = append(routes, &router.Route{
  519. Endpoint: getGitlabRepoContentsEndpoint,
  520. Handler: getGitlabRepoContentsHandler,
  521. Router: r,
  522. })
  523. // GET /api/projects/{project_id}/integrations/gitlab/{integration_id}/repos/buildpack/detect
  524. getGitlabRepoBuildpackEndpoint := factory.NewAPIEndpoint(
  525. &types.APIRequestMetadata{
  526. Verb: types.APIVerbGet,
  527. Method: types.HTTPVerbGet,
  528. Path: &types.Path{
  529. Parent: basePath,
  530. RelativePath: fmt.Sprintf("%s/gitlab/{%s}/repos/buildpack/detect", relPath,
  531. types.URLParamIntegrationID),
  532. },
  533. Scopes: []types.PermissionScope{
  534. types.UserScope,
  535. types.ProjectScope,
  536. types.GitlabIntegrationScope,
  537. },
  538. },
  539. )
  540. getGitlabRepoBuildpackHandler := project_integration.NewGetGitlabRepoBuildpackHandler(
  541. config,
  542. factory.GetDecoderValidator(),
  543. factory.GetResultWriter(),
  544. )
  545. routes = append(routes, &router.Route{
  546. Endpoint: getGitlabRepoBuildpackEndpoint,
  547. Handler: getGitlabRepoBuildpackHandler,
  548. Router: r,
  549. })
  550. // GET /api/projects/{project_id}/integrations/gitlab/{integration_id}/repos/procfile
  551. getGitlabRepoProcfileEndpoint := factory.NewAPIEndpoint(
  552. &types.APIRequestMetadata{
  553. Verb: types.APIVerbGet,
  554. Method: types.HTTPVerbGet,
  555. Path: &types.Path{
  556. Parent: basePath,
  557. RelativePath: fmt.Sprintf("%s/gitlab/{%s}/repos/procfile", relPath,
  558. types.URLParamIntegrationID),
  559. },
  560. Scopes: []types.PermissionScope{
  561. types.UserScope,
  562. types.ProjectScope,
  563. types.GitlabIntegrationScope,
  564. },
  565. },
  566. )
  567. getGitlabRepoProcfileHandler := project_integration.NewGetGitlabRepoProcfileHandler(
  568. config,
  569. factory.GetDecoderValidator(),
  570. factory.GetResultWriter(),
  571. )
  572. routes = append(routes, &router.Route{
  573. Endpoint: getGitlabRepoProcfileEndpoint,
  574. Handler: getGitlabRepoProcfileHandler,
  575. Router: r,
  576. })
  577. // GET /api/projects/{project_id}/integrations/gitlab/{integration_id}/repos/porteryaml
  578. getGitlabRepoPorterYamlContentsEndpoint := factory.NewAPIEndpoint(
  579. &types.APIRequestMetadata{
  580. Verb: types.APIVerbGet,
  581. Method: types.HTTPVerbGet,
  582. Path: &types.Path{
  583. Parent: basePath,
  584. RelativePath: fmt.Sprintf("%s/gitlab/{%s}/repos/porteryaml", relPath,
  585. types.URLParamIntegrationID),
  586. },
  587. Scopes: []types.PermissionScope{
  588. types.UserScope,
  589. types.ProjectScope,
  590. types.GitlabIntegrationScope,
  591. },
  592. },
  593. )
  594. getGitlabRepoPorterYamlContentsHandler := project_integration.NewGetGitlabRepoPorterYamlContentsHandler(
  595. config,
  596. factory.GetDecoderValidator(),
  597. factory.GetResultWriter(),
  598. )
  599. routes = append(routes, &router.Route{
  600. Endpoint: getGitlabRepoPorterYamlContentsEndpoint,
  601. Handler: getGitlabRepoPorterYamlContentsHandler,
  602. Router: r,
  603. })
  604. return routes, newPath
  605. }