diff --git a/packages/backend/src/controllers/api/v1/templates/get-templates.ee.js b/packages/backend/src/controllers/api/v1/templates/get-templates.ee.js new file mode 100644 index 00000000..d1332528 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/templates/get-templates.ee.js @@ -0,0 +1,10 @@ +import { renderObject } from '../../../../helpers/renderer.js'; +import Template from '../../../../models/template.ee.js'; + +export default async (request, response) => { + const templates = await Template.query().orderBy('created_at', 'asc'); + + renderObject(response, templates, { + serializer: 'PublicTemplate', + }); +}; diff --git a/packages/backend/src/controllers/api/v1/templates/get-templates.ee.test.js b/packages/backend/src/controllers/api/v1/templates/get-templates.ee.test.js new file mode 100644 index 00000000..e45666eb --- /dev/null +++ b/packages/backend/src/controllers/api/v1/templates/get-templates.ee.test.js @@ -0,0 +1,31 @@ +import { vi, describe, it, expect, beforeEach } from 'vitest'; +import request from 'supertest'; +import app from '../../../../app.js'; +import { createApiToken } from '../../../../../test/factories/api-token.js'; +import { createTemplate } from '../../../../../test/factories/template.js'; +import getTemplatesMock from '../../../../../test/mocks/rest/internal/api/v1/admin/templates/get-templates.ee.js'; +import * as license from '../../../../helpers/license.ee.js'; + +describe('GET /api/v1/templates', () => { + let token; + + beforeEach(async () => { + vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true); + + token = (await createApiToken()).token; + }); + + it('should return templates', async () => { + const templateOne = await createTemplate(); + const templateTwo = await createTemplate(); + + const response = await request(app) + .get('/api/v1/templates') + .set('x-api-token', token) + .expect(200); + + const expectedPayload = await getTemplatesMock([templateOne, templateTwo]); + + expect(response.body).toStrictEqual(expectedPayload); + }); +}); diff --git a/packages/backend/src/routes/api/index.js b/packages/backend/src/routes/api/index.js index 60851284..50303493 100644 --- a/packages/backend/src/routes/api/index.js +++ b/packages/backend/src/routes/api/index.js @@ -4,6 +4,7 @@ import executionsRouter from './v1/executions.ee.js'; import flowsRouter from './v1/flows.ee.js'; import foldersRouter from './v1/folders.ee.js'; import usersRouter from './v1/users.ee.js'; +import templatesRouter from './v1/templates.ee.js'; const router = Router(); @@ -12,5 +13,6 @@ router.use('/v1/flows', flowsRouter); router.use('/v1/executions', executionsRouter); router.use('/v1/folders', foldersRouter); router.use('/v1/users', usersRouter); +router.use('/v1/templates', templatesRouter); export default router; diff --git a/packages/backend/src/routes/api/v1/templates.ee.js b/packages/backend/src/routes/api/v1/templates.ee.js new file mode 100644 index 00000000..6a4e43b4 --- /dev/null +++ b/packages/backend/src/routes/api/v1/templates.ee.js @@ -0,0 +1,8 @@ +import { Router } from 'express'; +import getTemplatesAction from '../../../controllers/api/v1/templates/get-templates.ee.js'; + +const router = Router(); + +router.get('/', getTemplatesAction); + +export default router; diff --git a/packages/backend/src/serializers/admin/template.ee.test.js b/packages/backend/src/serializers/admin/template.ee.test.js index aa78e56b..66b4fd88 100644 --- a/packages/backend/src/serializers/admin/template.ee.test.js +++ b/packages/backend/src/serializers/admin/template.ee.test.js @@ -9,7 +9,7 @@ describe('adminTemplateSerializer', () => { template = await createTemplate(); }); - it('should return flow data', async () => { + it('should return template data', async () => { const expectedPayload = { id: template.id, name: template.name, diff --git a/packages/backend/src/serializers/index.js b/packages/backend/src/serializers/index.js index b441fa41..cec30d64 100644 --- a/packages/backend/src/serializers/index.js +++ b/packages/backend/src/serializers/index.js @@ -1,29 +1,30 @@ -import userSerializer from './user.js'; -import roleSerializer from './role.js'; -import permissionSerializer from './permission.js'; -import adminSamlAuthProviderSerializer from './admin-saml-auth-provider.ee.js'; -import adminTemplateSerializer from './admin/template.ee.js'; -import adminApiTokenSerializer from './admin/api-token.ee.js'; -import adminApiTokenFullSerializer from './admin/api-token-full.ee.js'; -import templateSerializer from './template.ee.js'; -import samlAuthProviderSerializer from './saml-auth-provider.ee.js'; -import samlAuthProviderRoleMappingSerializer from './role-mapping.ee.js'; -import oauthClientSerializer from './oauth-client.js'; -import appConfigSerializer from './app-config.js'; -import flowSerializer from './flow.js'; -import stepSerializer from './step.js'; -import connectionSerializer from './connection.js'; -import appSerializer from './app.js'; -import userAppSerializer from './user-app.js'; -import authSerializer from './auth.js'; -import triggerSerializer from './trigger.js'; import actionSerializer from './action.js'; -import executionSerializer from './execution.js'; -import executionStepSerializer from './execution-step.js'; -import subscriptionSerializer from './subscription.ee.js'; +import adminSamlAuthProviderSerializer from './admin-saml-auth-provider.ee.js'; +import adminApiTokenFullSerializer from './admin/api-token-full.ee.js'; +import adminApiTokenSerializer from './admin/api-token.ee.js'; +import adminTemplateSerializer from './admin/template.ee.js'; import adminUserSerializer from './admin/user.js'; +import appConfigSerializer from './app-config.js'; +import appSerializer from './app.js'; +import authSerializer from './auth.js'; import configSerializer from './config.js'; +import connectionSerializer from './connection.js'; +import executionStepSerializer from './execution-step.js'; +import executionSerializer from './execution.js'; +import flowSerializer from './flow.js'; import folderSerializer from './folder.js'; +import oauthClientSerializer from './oauth-client.js'; +import permissionSerializer from './permission.js'; +import publicTemplateSerializer from './public-template.ee.js'; +import samlAuthProviderRoleMappingSerializer from './role-mapping.ee.js'; +import roleSerializer from './role.js'; +import samlAuthProviderSerializer from './saml-auth-provider.ee.js'; +import stepSerializer from './step.js'; +import subscriptionSerializer from './subscription.ee.js'; +import templateSerializer from './template.ee.js'; +import triggerSerializer from './trigger.js'; +import userAppSerializer from './user-app.js'; +import userSerializer from './user.js'; const serializers = { Action: actionSerializer, @@ -43,6 +44,7 @@ const serializers = { Folder: folderSerializer, OAuthClient: oauthClientSerializer, Permission: permissionSerializer, + PublicTemplate: publicTemplateSerializer, Role: roleSerializer, RoleMapping: samlAuthProviderRoleMappingSerializer, SamlAuthProvider: samlAuthProviderSerializer, diff --git a/packages/backend/src/serializers/public-template.ee.js b/packages/backend/src/serializers/public-template.ee.js new file mode 100644 index 00000000..c97b2ea0 --- /dev/null +++ b/packages/backend/src/serializers/public-template.ee.js @@ -0,0 +1,11 @@ +const publicTemplateSerializer = (template) => { + return { + id: template.id, + name: template.name, + flowData: template.getFlowDataWithIconUrls(), + createdAt: template.createdAt.getTime(), + updatedAt: template.updatedAt.getTime(), + }; +}; + +export default publicTemplateSerializer; diff --git a/packages/backend/src/serializers/public-template.ee.test.js b/packages/backend/src/serializers/public-template.ee.test.js new file mode 100644 index 00000000..3a4cefc2 --- /dev/null +++ b/packages/backend/src/serializers/public-template.ee.test.js @@ -0,0 +1,23 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import templateSerializer from './template.ee.js'; +import { createTemplate } from '../../test/factories/template.js'; + +describe('publicTemplateSerializer', () => { + let template; + + beforeEach(async () => { + template = await createTemplate(); + }); + + it('should return template data', async () => { + const expectedPayload = { + id: template.id, + name: template.name, + flowData: template.getFlowDataWithIconUrls(), + createdAt: template.createdAt.getTime(), + updatedAt: template.updatedAt.getTime(), + }; + + expect(templateSerializer(template)).toStrictEqual(expectedPayload); + }); +});