Update manifest structure (#17547)
Move all sync entities in an `entities` key. Rename functions to
logicFunctions
```json
{
application: {
...
},
entities: {
objects: [],
logicFunctions: [],
...
}
}
```
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { defineApp } from '@/application/define-app';
|
||||
import { defineApplication } from '@/sdk';
|
||||
|
||||
export default defineApp({
|
||||
export default defineApplication({
|
||||
universalIdentifier: 'invalid-app-0000-0000-0000-000000000001',
|
||||
displayName: 'Invalid App',
|
||||
description: 'An app with duplicate IDs for testing validation',
|
||||
icon: 'IconAlertTriangle',
|
||||
functionRoleUniversalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000002',
|
||||
defaultRoleUniversalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000002',
|
||||
});
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { defineObject } from '@/application/objects/define-object';
|
||||
import { FieldType } from '@/application/fields/field-type';
|
||||
import { defineObject, FieldType } from '@/sdk';
|
||||
|
||||
const DUPLICATE_ID = 'duplicate-id-0000-0000-000000000001';
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { defineObject } from '@/application/objects/define-object';
|
||||
import { FieldType } from '@/application/fields/field-type';
|
||||
import { defineObject, FieldType } from '@/sdk';
|
||||
|
||||
const DUPLICATE_ID = 'duplicate-id-0000-0000-000000000001';
|
||||
|
||||
|
||||
+77
-81
@@ -1,8 +1,8 @@
|
||||
import { FieldType } from '@/application';
|
||||
import type { ApplicationManifest } from 'twenty-shared/application';
|
||||
import { FieldType } from '@/sdk';
|
||||
import type { Manifest } from 'twenty-shared/application';
|
||||
import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
|
||||
export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
export const EXPECTED_MANIFEST: Manifest = {
|
||||
sources: {},
|
||||
publicAssets: [
|
||||
{
|
||||
@@ -24,7 +24,7 @@ export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
},
|
||||
description: 'A simple hello world app',
|
||||
displayName: 'Hello World',
|
||||
functionRoleUniversalIdentifier: 'b648f87b-1d26-4961-b974-0908fd991061',
|
||||
defaultRoleUniversalIdentifier: 'b648f87b-1d26-4961-b974-0908fd991061',
|
||||
icon: 'IconWorld',
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
},
|
||||
@@ -66,47 +66,43 @@ export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
universalIdentifier: 'f1234567-abcd-4000-8000-000000000001',
|
||||
},
|
||||
],
|
||||
objectExtensions: [
|
||||
|
||||
fields: [
|
||||
{
|
||||
fields: [
|
||||
objectUniversalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
|
||||
description: 'Priority level for the post card (1-10)',
|
||||
label: 'Priority',
|
||||
name: 'priority',
|
||||
type: FieldType.NUMBER,
|
||||
universalIdentifier: '7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d',
|
||||
},
|
||||
{
|
||||
objectUniversalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
|
||||
description: 'Post card category',
|
||||
label: 'Category',
|
||||
name: 'category',
|
||||
options: [
|
||||
{
|
||||
description: 'Priority level for the post card (1-10)',
|
||||
label: 'Priority',
|
||||
name: 'priority',
|
||||
type: FieldType.NUMBER,
|
||||
universalIdentifier: '7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d',
|
||||
color: 'blue',
|
||||
label: 'Personal',
|
||||
position: 0,
|
||||
value: 'PERSONAL',
|
||||
},
|
||||
{
|
||||
description: 'Post card category',
|
||||
label: 'Category',
|
||||
name: 'category',
|
||||
options: [
|
||||
{
|
||||
color: 'blue',
|
||||
label: 'Personal',
|
||||
position: 0,
|
||||
value: 'PERSONAL',
|
||||
},
|
||||
{
|
||||
color: 'green',
|
||||
label: 'Business',
|
||||
position: 1,
|
||||
value: 'BUSINESS',
|
||||
},
|
||||
{
|
||||
color: 'orange',
|
||||
label: 'Promotional',
|
||||
position: 2,
|
||||
value: 'PROMOTIONAL',
|
||||
},
|
||||
],
|
||||
type: FieldType.SELECT,
|
||||
universalIdentifier: '8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e',
|
||||
color: 'green',
|
||||
label: 'Business',
|
||||
position: 1,
|
||||
value: 'BUSINESS',
|
||||
},
|
||||
{
|
||||
color: 'orange',
|
||||
label: 'Promotional',
|
||||
position: 2,
|
||||
value: 'PROMOTIONAL',
|
||||
},
|
||||
],
|
||||
targetObject: {
|
||||
nameSingular: 'postCard',
|
||||
},
|
||||
type: FieldType.SELECT,
|
||||
universalIdentifier: '8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e',
|
||||
},
|
||||
],
|
||||
objects: [
|
||||
@@ -210,44 +206,6 @@ export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
|
||||
},
|
||||
],
|
||||
packageJson: {
|
||||
name: 'rich-app',
|
||||
version: '0.1.0',
|
||||
license: 'MIT',
|
||||
engines: {
|
||||
node: '^24.5.0',
|
||||
npm: 'please-use-yarn',
|
||||
yarn: '>=4.0.2',
|
||||
},
|
||||
packageManager: 'yarn@4.9.2',
|
||||
scripts: {
|
||||
'auth:login': 'twenty auth:login',
|
||||
'auth:logout': 'twenty auth:logout',
|
||||
'auth:status': 'twenty auth:status',
|
||||
'auth:switch': 'twenty auth:switch',
|
||||
'auth:list': 'twenty auth:list',
|
||||
'app:dev': 'twenty app:dev',
|
||||
'entity:add': 'twenty entity:add',
|
||||
'app:generate': 'twenty app:generate',
|
||||
'function:logs': 'twenty function:logs',
|
||||
'function:execute': 'twenty function:execute',
|
||||
'app:uninstall': 'twenty app:uninstall',
|
||||
help: 'twenty help',
|
||||
lint: 'eslint',
|
||||
'lint:fix': 'eslint --fix',
|
||||
},
|
||||
dependencies: {
|
||||
'twenty-sdk': 'latest',
|
||||
},
|
||||
devDependencies: {
|
||||
typescript: '^5.9.3',
|
||||
'@types/node': '^24.7.2',
|
||||
'@types/react': '^19.0.2',
|
||||
react: '^19.0.2',
|
||||
eslint: '^9.32.0',
|
||||
'typescript-eslint': '^8.50.0',
|
||||
},
|
||||
},
|
||||
roles: [
|
||||
{
|
||||
canBeAssignedToAgents: false,
|
||||
@@ -276,8 +234,8 @@ export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
{
|
||||
canReadFieldValue: false,
|
||||
canUpdateFieldValue: false,
|
||||
fieldName: 'content',
|
||||
objectNameSingular: 'postCard',
|
||||
fieldUniversalIdentifier: 'b2c37dc0-8ae7-470e-96cd-1476b47dfaff',
|
||||
objectUniversalIdentifier: '9f9882af-170c-4879-b013-f9628b77c050',
|
||||
},
|
||||
],
|
||||
label: 'Default function role',
|
||||
@@ -287,14 +245,14 @@ export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
canReadObjectRecords: true,
|
||||
canSoftDeleteObjectRecords: false,
|
||||
canUpdateObjectRecords: true,
|
||||
objectNameSingular: 'postCard',
|
||||
objectUniversalIdentifier: '9f9882af-170c-4879-b013-f9628b77c050',
|
||||
},
|
||||
],
|
||||
permissionFlags: [PermissionFlagType.APPLICATIONS],
|
||||
universalIdentifier: 'b648f87b-1d26-4961-b974-0908fd991061',
|
||||
},
|
||||
],
|
||||
functions: [
|
||||
logicFunctions: [
|
||||
{
|
||||
builtHandlerChecksum: '[checksum]',
|
||||
builtHandlerPath: 'src/root.function.mjs',
|
||||
@@ -377,4 +335,42 @@ export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
|
||||
},
|
||||
],
|
||||
packageJson: {
|
||||
name: 'rich-app',
|
||||
version: '0.1.0',
|
||||
license: 'MIT',
|
||||
engines: {
|
||||
node: '^24.5.0',
|
||||
npm: 'please-use-yarn',
|
||||
yarn: '>=4.0.2',
|
||||
},
|
||||
packageManager: 'yarn@4.9.2',
|
||||
scripts: {
|
||||
'auth:login': 'twenty auth:login',
|
||||
'auth:logout': 'twenty auth:logout',
|
||||
'auth:status': 'twenty auth:status',
|
||||
'auth:switch': 'twenty auth:switch',
|
||||
'auth:list': 'twenty auth:list',
|
||||
'app:dev': 'twenty app:dev',
|
||||
'entity:add': 'twenty entity:add',
|
||||
'app:generate': 'twenty app:generate',
|
||||
'function:logs': 'twenty function:logs',
|
||||
'function:execute': 'twenty function:execute',
|
||||
'app:uninstall': 'twenty app:uninstall',
|
||||
help: 'twenty help',
|
||||
lint: 'eslint',
|
||||
'lint:fix': 'eslint --fix',
|
||||
},
|
||||
dependencies: {
|
||||
'twenty-sdk': 'latest',
|
||||
},
|
||||
devDependencies: {
|
||||
typescript: '^5.9.3',
|
||||
'@types/node': '^24.7.2',
|
||||
'@types/react': '^19.0.2',
|
||||
react: '^19.0.2',
|
||||
eslint: '^9.32.0',
|
||||
'typescript-eslint': '^8.50.0',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ import { OUTPUT_DIR } from 'twenty-shared/application';
|
||||
|
||||
export const defineEntitiesTests = (appPath: string): void => {
|
||||
const outputDir = join(appPath, OUTPUT_DIR);
|
||||
describe('functions', () => {
|
||||
it('should have built functions preserving source path structure', async () => {
|
||||
describe('logicFunctions', () => {
|
||||
it('should have built logicFunctions preserving source path structure', async () => {
|
||||
const files = await fs.readdir(outputDir, { recursive: true });
|
||||
const sortedFiles = files.map((f) => f.toString()).sort();
|
||||
|
||||
|
||||
+7
-7
@@ -19,13 +19,13 @@ export const defineManifestTests = (appPath: string): void => {
|
||||
normalizeManifestForComparison(EXPECTED_MANIFEST),
|
||||
);
|
||||
|
||||
for (const fn of manifest.functions) {
|
||||
for (const fn of manifest.entities.logicFunctions) {
|
||||
expect(fn.builtHandlerChecksum).toBeDefined();
|
||||
expect(fn.builtHandlerChecksum).not.toBeNull();
|
||||
expect(typeof fn.builtHandlerChecksum).toBe('string');
|
||||
}
|
||||
|
||||
for (const component of manifest.frontComponents ?? []) {
|
||||
for (const component of manifest.entities.frontComponents ?? []) {
|
||||
expect(component.builtComponentChecksum).toBeDefined();
|
||||
expect(component.builtComponentChecksum).not.toBeNull();
|
||||
expect(typeof component.builtComponentChecksum).toBe('string');
|
||||
@@ -44,11 +44,11 @@ export const defineManifestTests = (appPath: string): void => {
|
||||
it('should load all entity types', async () => {
|
||||
const manifest = await fs.readJson(manifestOutputPath);
|
||||
|
||||
expect(manifest?.objects).toHaveLength(2);
|
||||
expect(manifest?.functions).toHaveLength(4);
|
||||
expect(manifest?.frontComponents).toHaveLength(4);
|
||||
expect(manifest?.roles).toHaveLength(2);
|
||||
expect(manifest?.objectExtensions).toHaveLength(1);
|
||||
expect(manifest?.entities.objects).toHaveLength(2);
|
||||
expect(manifest?.entities.logicFunctions).toHaveLength(4);
|
||||
expect(manifest?.entities.frontComponents).toHaveLength(4);
|
||||
expect(manifest?.entities.roles).toHaveLength(2);
|
||||
expect(manifest?.entities.objectExtensions).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { defineApp } from '@/application/define-app';
|
||||
import { DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER } from './src/roles/default-function.role';
|
||||
import { defineApplication } from '@/sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from './src/roles/default-function.role';
|
||||
|
||||
export default defineApp({
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
displayName: 'Hello World',
|
||||
description: 'A simple hello world app',
|
||||
@@ -14,5 +14,5 @@ export default defineApp({
|
||||
isSecret: false,
|
||||
},
|
||||
},
|
||||
functionRoleUniversalIdentifier: DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { defineFrontComponent } from '@/application/front-components/define-front-component';
|
||||
import { defineFrontComponent } from '@/sdk';
|
||||
import { CardDisplay } from '../utils/card-display.component';
|
||||
|
||||
export default defineFrontComponent({
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { defineFrontComponent } from '@/application/front-components/define-front-component';
|
||||
import { defineFrontComponent } from '@/sdk';
|
||||
import { DEFAULT_NAME, formatGreeting } from '../utils/greeting.util';
|
||||
|
||||
const GreetingComponent = () => {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { defineFrontComponent } from '@/application/front-components/define-front-component';
|
||||
import { defineFrontComponent } from '@/sdk';
|
||||
|
||||
export const TestComponent = () => {
|
||||
return (
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { defineField, FieldType } from '@/sdk';
|
||||
import { POST_CARD_UNIVERSAL_IDENTIFIER } from '@/cli/__tests__/apps/rich-app/src/objects/postCard.object';
|
||||
import { POST_CARD_EXTENSION_CATEGORY_FIELD_ID } from '@/cli/__tests__/apps/rich-app/src/fields/postCardNumber.field';
|
||||
|
||||
export default defineField({
|
||||
objectUniversalIdentifier: POST_CARD_UNIVERSAL_IDENTIFIER,
|
||||
universalIdentifier: POST_CARD_EXTENSION_CATEGORY_FIELD_ID,
|
||||
type: FieldType.SELECT,
|
||||
name: 'category',
|
||||
label: 'Category',
|
||||
description: 'Post card category',
|
||||
options: [
|
||||
{ value: 'PERSONAL', label: 'Personal', color: 'blue', position: 0 },
|
||||
{ value: 'BUSINESS', label: 'Business', color: 'green', position: 1 },
|
||||
{
|
||||
value: 'PROMOTIONAL',
|
||||
label: 'Promotional',
|
||||
color: 'orange',
|
||||
position: 2,
|
||||
},
|
||||
],
|
||||
});
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { defineField, FieldType } from '@/sdk';
|
||||
import { POST_CARD_UNIVERSAL_IDENTIFIER } from '@/cli/__tests__/apps/rich-app/src/objects/postCard.object';
|
||||
|
||||
export const POST_CARD_EXTENSION_PRIORITY_FIELD_ID =
|
||||
'7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d';
|
||||
|
||||
export const POST_CARD_EXTENSION_CATEGORY_FIELD_ID =
|
||||
'8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e';
|
||||
|
||||
export default defineField({
|
||||
objectUniversalIdentifier: POST_CARD_UNIVERSAL_IDENTIFIER,
|
||||
universalIdentifier: POST_CARD_EXTENSION_PRIORITY_FIELD_ID,
|
||||
type: FieldType.NUMBER,
|
||||
name: 'priority',
|
||||
label: 'Priority',
|
||||
description: 'Priority level for the post card (1-10)',
|
||||
});
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import { defineFunction } from '@/application/functions/define-function';
|
||||
import { defineLogicFunction } from '@/sdk';
|
||||
import { DEFAULT_NAME, formatGreeting } from '../utils/greeting.util';
|
||||
|
||||
const greetingHandler = () => {
|
||||
return formatGreeting(DEFAULT_NAME);
|
||||
};
|
||||
|
||||
export default defineFunction({
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: '9d412d9e-2caf-487c-8b66-d1585883dd4e',
|
||||
name: 'greeting-function',
|
||||
timeoutSeconds: 5,
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { defineFunction } from '@/application/functions/define-function';
|
||||
import { defineLogicFunction } from '@/sdk';
|
||||
import { testFunction2 } from '../utils/test-function-2.util';
|
||||
|
||||
export const config = defineFunction({
|
||||
export const config = defineLogicFunction({
|
||||
universalIdentifier: 'eb3ffc98-88ec-45d4-9b4a-56833b219ccb',
|
||||
name: 'test-function-2',
|
||||
timeoutSeconds: 2,
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import { defineFunction } from '@/application/functions/define-function';
|
||||
import { defineLogicFunction } from '@/sdk';
|
||||
import { formatFarewell } from '../utils/greeting.util';
|
||||
|
||||
const handler = () => {
|
||||
return formatFarewell('test');
|
||||
};
|
||||
|
||||
export default defineFunction({
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
|
||||
name: 'test-function',
|
||||
timeoutSeconds: 2,
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
import { extendObject } from '@/application/objects/extend-object';
|
||||
import { FieldType } from '@/application/fields/field-type';
|
||||
|
||||
export const POST_CARD_EXTENSION_PRIORITY_FIELD_ID =
|
||||
'7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d';
|
||||
|
||||
export const POST_CARD_EXTENSION_CATEGORY_FIELD_ID =
|
||||
'8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e';
|
||||
|
||||
export default extendObject({
|
||||
targetObject: {
|
||||
nameSingular: 'postCard',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
universalIdentifier: POST_CARD_EXTENSION_PRIORITY_FIELD_ID,
|
||||
type: FieldType.NUMBER,
|
||||
name: 'priority',
|
||||
label: 'Priority',
|
||||
description: 'Priority level for the post card (1-10)',
|
||||
},
|
||||
{
|
||||
universalIdentifier: POST_CARD_EXTENSION_CATEGORY_FIELD_ID,
|
||||
type: FieldType.SELECT,
|
||||
name: 'category',
|
||||
label: 'Category',
|
||||
description: 'Post card category',
|
||||
options: [
|
||||
{ value: 'PERSONAL', label: 'Personal', color: 'blue', position: 0 },
|
||||
{ value: 'BUSINESS', label: 'Business', color: 'green', position: 1 },
|
||||
{
|
||||
value: 'PROMOTIONAL',
|
||||
label: 'Promotional',
|
||||
color: 'orange',
|
||||
position: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -1,5 +1,4 @@
|
||||
import { defineObject } from '@/application/objects/define-object';
|
||||
import { FieldType } from '@/application/fields/field-type';
|
||||
import { defineObject, FieldType } from '@/sdk';
|
||||
|
||||
enum PostCardStatus {
|
||||
DRAFT = 'DRAFT',
|
||||
@@ -8,8 +7,11 @@ enum PostCardStatus {
|
||||
RETURNED = 'RETURNED',
|
||||
}
|
||||
|
||||
export const POST_CARD_UNIVERSAL_IDENTIFIER =
|
||||
'54b589ca-eeed-4950-a176-358418b85c05';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
|
||||
universalIdentifier: POST_CARD_UNIVERSAL_IDENTIFIER,
|
||||
nameSingular: 'postCard',
|
||||
namePlural: 'postCards',
|
||||
labelSingular: 'Post card',
|
||||
|
||||
+6
-7
@@ -1,11 +1,10 @@
|
||||
import { PermissionFlag } from '@/application/permission-flag-type';
|
||||
import { defineRole } from '@/application/roles/define-role';
|
||||
import { PermissionFlag, defineRole } from '@/sdk';
|
||||
|
||||
export const DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER =
|
||||
export const DEFAULT_ROLE_UNIVERSAL_IDENTIFIER =
|
||||
'b648f87b-1d26-4961-b974-0908fd991061';
|
||||
|
||||
export default defineRole({
|
||||
universalIdentifier: DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
universalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
label: 'Default function role',
|
||||
description: 'Default role for function Twenty client',
|
||||
canReadAllObjectRecords: false,
|
||||
@@ -18,7 +17,7 @@ export default defineRole({
|
||||
canBeAssignedToApiKeys: false,
|
||||
objectPermissions: [
|
||||
{
|
||||
objectNameSingular: 'postCard',
|
||||
objectUniversalIdentifier: '9f9882af-170c-4879-b013-f9628b77c050',
|
||||
canReadObjectRecords: true,
|
||||
canUpdateObjectRecords: true,
|
||||
canSoftDeleteObjectRecords: false,
|
||||
@@ -27,8 +26,8 @@ export default defineRole({
|
||||
],
|
||||
fieldPermissions: [
|
||||
{
|
||||
objectNameSingular: 'postCard',
|
||||
fieldName: 'content',
|
||||
objectUniversalIdentifier: '9f9882af-170c-4879-b013-f9628b77c050',
|
||||
fieldUniversalIdentifier: 'b2c37dc0-8ae7-470e-96cd-1476b47dfaff',
|
||||
canReadFieldValue: false,
|
||||
canUpdateFieldValue: false,
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineFrontComponent } from '@/application/front-components/define-front-component';
|
||||
import { defineFrontComponent } from '@/sdk';
|
||||
|
||||
export const RootComponent = () => {
|
||||
return (
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { defineFunction } from '@/application/functions/define-function';
|
||||
import { defineLogicFunction } from '@/sdk';
|
||||
|
||||
const rootHandler = () => {
|
||||
return 'root-function-result';
|
||||
};
|
||||
|
||||
export default defineFunction({
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'f0f1f2f3-f4f5-4000-8000-000000000001',
|
||||
name: 'root-function',
|
||||
timeoutSeconds: 5,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { defineObject } from '@/application/objects/define-object';
|
||||
import { FieldType } from '@/application/fields/field-type';
|
||||
import { defineObject, FieldType } from '@/sdk';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: 'b0b1b2b3-b4b5-4000-8000-000000000001',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineRole } from '@/application/roles/define-role';
|
||||
import { defineRole } from '@/sdk';
|
||||
|
||||
export default defineRole({
|
||||
universalIdentifier: 'c0c1c2c3-c4c5-4000-8000-000000000001',
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ import { runAppDev } from '@/cli/__tests__/integration/utils/run-app-dev.util';
|
||||
import { type RunCliCommandResult } from '@/cli/__tests__/integration/utils/run-cli-command.util';
|
||||
import { defineConsoleOutputTests } from './tests/console-output.tests';
|
||||
import { defineFrontComponentsTests } from './tests/front-components.tests';
|
||||
import { defineFunctionsTests } from './tests/functions.tests';
|
||||
import { defineLogicFunctionsTests } from './tests/logic-functions.tests';
|
||||
import { defineManifestTests } from './tests/manifest.tests';
|
||||
|
||||
const APP_PATH = join(__dirname, '../..');
|
||||
@@ -22,6 +22,6 @@ describe('root-app app:dev', () => {
|
||||
|
||||
defineConsoleOutputTests(() => result);
|
||||
defineManifestTests(APP_PATH);
|
||||
defineFunctionsTests(APP_PATH);
|
||||
defineLogicFunctionsTests(APP_PATH);
|
||||
defineFrontComponentsTests(APP_PATH);
|
||||
});
|
||||
|
||||
+7
-5
@@ -1,7 +1,7 @@
|
||||
import { FieldType } from '@/application';
|
||||
import type { ApplicationManifest } from 'twenty-shared/application';
|
||||
import { FieldType } from '@/sdk';
|
||||
import type { Manifest } from 'twenty-shared/application';
|
||||
|
||||
export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
export const EXPECTED_MANIFEST: Manifest = {
|
||||
sources: {},
|
||||
yarnLock: '',
|
||||
packageJson: {
|
||||
@@ -47,8 +47,10 @@ export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
displayName: 'Root App',
|
||||
description: 'An app with all entities at root level',
|
||||
icon: 'IconFolder',
|
||||
functionRoleUniversalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000002',
|
||||
defaultRoleUniversalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000002',
|
||||
},
|
||||
publicAssets: [],
|
||||
fields: [],
|
||||
objects: [
|
||||
{
|
||||
universalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000030',
|
||||
@@ -68,7 +70,7 @@ export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
],
|
||||
},
|
||||
],
|
||||
functions: [
|
||||
logicFunctions: [
|
||||
{
|
||||
universalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000010',
|
||||
name: 'my-function',
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
import * as fs from 'fs-extra';
|
||||
import { join } from 'path';
|
||||
|
||||
export const defineFunctionsTests = (appPath: string): void => {
|
||||
describe('functions', () => {
|
||||
it('should have built functions at root level', async () => {
|
||||
export const defineLogicFunctionsTests = (appPath: string): void => {
|
||||
describe('logicFunctions', () => {
|
||||
it('should have built logicFunctions at root level', async () => {
|
||||
const outputDir = join(appPath, '.twenty/output');
|
||||
const files = await fs.readdir(outputDir, { recursive: true });
|
||||
const functionFiles = files
|
||||
+8
-7
@@ -1,6 +1,6 @@
|
||||
import * as fs from 'fs-extra';
|
||||
import { join } from 'path';
|
||||
import { type ApplicationManifest } from 'twenty-shared/application';
|
||||
import { type Manifest } from 'twenty-shared/application';
|
||||
|
||||
import { normalizeManifestForComparison } from '@/cli/__tests__/integration/utils/normalize-manifest.util';
|
||||
import { EXPECTED_MANIFEST } from '@/cli/__tests__/apps/root-app/__integration__/app-dev/expected-manifest';
|
||||
@@ -16,21 +16,22 @@ export const defineManifestTests = (appPath: string): void => {
|
||||
|
||||
it('should have correct manifest content', async () => {
|
||||
const manifestPath = join(appPath, '.twenty/output/manifest.json');
|
||||
const manifest: ApplicationManifest = await fs.readJSON(manifestPath);
|
||||
const manifest: Manifest = await fs.readJSON(manifestPath);
|
||||
|
||||
expect(manifest.application).toEqual(EXPECTED_MANIFEST.application);
|
||||
expect(manifest.objects).toEqual(EXPECTED_MANIFEST.objects);
|
||||
|
||||
expect(
|
||||
normalizeManifestForComparison({ functions: manifest.functions })
|
||||
.functions,
|
||||
normalizeManifestForComparison({
|
||||
logicFunctions: manifest.logicFunctions,
|
||||
}).logicFunctions,
|
||||
).toEqual(
|
||||
normalizeManifestForComparison({
|
||||
functions: EXPECTED_MANIFEST.functions,
|
||||
}).functions,
|
||||
logicFunctions: EXPECTED_MANIFEST.logicFunctions,
|
||||
}).logicFunctions,
|
||||
);
|
||||
|
||||
for (const fn of manifest.functions) {
|
||||
for (const fn of manifest.logicFunctions) {
|
||||
expect(fn.builtHandlerChecksum).toBeDefined();
|
||||
expect(fn.builtHandlerChecksum).not.toBeNull();
|
||||
expect(typeof fn.builtHandlerChecksum).toBe('string');
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { defineApp } from '@/application/define-app';
|
||||
import { defineApplication } from '@/sdk';
|
||||
|
||||
export default defineApp({
|
||||
export default defineApplication({
|
||||
universalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000001',
|
||||
displayName: 'Root App',
|
||||
description: 'An app with all entities at root level',
|
||||
icon: 'IconFolder',
|
||||
functionRoleUniversalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000002',
|
||||
defaultRoleUniversalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000002',
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineFrontComponent } from '@/application/front-components/define-front-component';
|
||||
import { defineFrontComponent } from '@/sdk';
|
||||
|
||||
export const MyComponent = () => {
|
||||
return (
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { defineFunction } from '@/application/functions/define-function';
|
||||
import { defineLogicFunction } from '@/sdk';
|
||||
|
||||
const myHandler = () => {
|
||||
return 'my-function-result';
|
||||
};
|
||||
|
||||
export default defineFunction({
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000010',
|
||||
name: 'my-function',
|
||||
timeoutSeconds: 5,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { FieldType } from '@/application/fields/field-type';
|
||||
import { defineObject } from '@/application/objects/define-object';
|
||||
import { FieldType, defineObject } from '@/sdk';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000030',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineRole } from '@/application/roles/define-role';
|
||||
import { defineRole } from '@/sdk';
|
||||
|
||||
export default defineRole({
|
||||
universalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000040',
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ export type LogPrefix =
|
||||
| 'init'
|
||||
| 'dev-mode'
|
||||
| 'manifest-watch'
|
||||
| 'functions-watch'
|
||||
| 'logicFunctions-watch'
|
||||
| 'front-components-watch';
|
||||
|
||||
export const getOutputByPrefix = (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Loose type for JSON manifest imports where enum values are inferred as strings
|
||||
type JsonManifestInput = {
|
||||
functions?: Array<{
|
||||
logicFunctions?: Array<{
|
||||
builtHandlerChecksum?: string | null;
|
||||
[key: string]: unknown;
|
||||
}>;
|
||||
@@ -16,7 +16,7 @@ export const normalizeManifestForComparison = <T extends JsonManifestInput>(
|
||||
manifest: T,
|
||||
): T => ({
|
||||
...manifest,
|
||||
functions: manifest.functions?.map((fn) => ({
|
||||
logicFunctions: manifest.logicFunctions?.map((fn) => ({
|
||||
...fn,
|
||||
builtHandlerChecksum: fn.builtHandlerChecksum ? '[checksum]' : null,
|
||||
})),
|
||||
|
||||
Reference in New Issue
Block a user