2081 extensibility publish cli tools and update doc with recent changes (#17495)
- increase to 0.4.0 - update READMEs and doc
This commit is contained in:
@@ -15,9 +15,12 @@
|
||||
Create Twenty App is the official scaffolding CLI for building apps on top of [Twenty CRM](https://twenty.com). It sets up a ready‑to‑run project that works seamlessly with the [twenty-sdk](https://www.npmjs.com/package/twenty-sdk).
|
||||
|
||||
- Zero‑config project bootstrap
|
||||
- Preconfigured scripts for auth, generate, dev sync, one‑off sync, uninstall
|
||||
- Preconfigured scripts for auth, dev mode (watch & sync), generate, uninstall, and function management
|
||||
- Strong TypeScript support and typed client generation
|
||||
|
||||
## Documentation
|
||||
See Twenty application documentation https://docs.twenty.com/developers/extend/capabilities/apps
|
||||
|
||||
## Prerequisites
|
||||
- Node.js 24+ (recommended) and Yarn 4
|
||||
- A Twenty workspace and an API key (create one at https://app.twenty.com/settings/api-webhooks)
|
||||
@@ -32,7 +35,7 @@ cd my-twenty-app
|
||||
corepack enable
|
||||
yarn install
|
||||
|
||||
# Get Help
|
||||
# Get help
|
||||
yarn run help
|
||||
|
||||
# Authenticate using your API key (you'll be prompted)
|
||||
@@ -44,15 +47,15 @@ yarn entity:add
|
||||
# Generate a typed Twenty client and workspace entity types
|
||||
yarn app:generate
|
||||
|
||||
# Start dev mode: automatically syncs local changes to your workspace
|
||||
# Start dev mode: watches, builds, and syncs local changes to your workspace
|
||||
yarn app:dev
|
||||
|
||||
# Or run a one‑time sync
|
||||
yarn app:sync
|
||||
|
||||
# Watch your application's functions logs
|
||||
# Watch your application's function logs
|
||||
yarn function:logs
|
||||
|
||||
# Execute a function with a JSON payload
|
||||
yarn function:execute -n my-function -p '{"key": "value"}'
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn app:uninstall
|
||||
```
|
||||
@@ -64,9 +67,9 @@ yarn app:uninstall
|
||||
- Example placeholders to help you add entities, actions, and sync logic
|
||||
|
||||
## Next steps
|
||||
- Explore the generated project and add your first entity with `yarn entity:add`.
|
||||
- Explore the generated project and add your first entity with `yarn entity:add` (functions, front components, objects, roles).
|
||||
- Keep your types up‑to‑date using `yarn app:generate`.
|
||||
- Use `yarn app:dev` while you iterate to see changes instantly in your workspace.
|
||||
- Use `yarn app:dev` while you iterate — it watches, builds, and syncs changes to your workspace in real time.
|
||||
|
||||
|
||||
## Publish your application
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-twenty-app",
|
||||
"version": "0.3.1",
|
||||
"version": "0.4.0",
|
||||
"description": "Command-line interface to create Twenty application",
|
||||
"main": "dist/cli.cjs",
|
||||
"bin": "dist/cli.cjs",
|
||||
|
||||
@@ -14,12 +14,6 @@ Then, start development mode to sync your app and watch for changes:
|
||||
yarn app:dev
|
||||
```
|
||||
|
||||
Or run a one-time sync:
|
||||
|
||||
```bash
|
||||
yarn app:sync
|
||||
```
|
||||
|
||||
Open your Twenty instance and go to `/settings/applications` section to see the result.
|
||||
|
||||
## Available Commands
|
||||
@@ -29,11 +23,12 @@ Open your Twenty instance and go to `/settings/applications` section to see the
|
||||
yarn auth:login # Authenticate with Twenty
|
||||
yarn auth:logout # Remove credentials
|
||||
yarn auth:status # Check auth status
|
||||
yarn auth:switch # Switch default workspace
|
||||
yarn auth:list # List all configured workspaces
|
||||
|
||||
# Application
|
||||
yarn app:dev # Start dev mode (sync + watch)
|
||||
yarn app:sync # One-time sync
|
||||
yarn entity:add # Add a new entity (function, object, role)
|
||||
yarn app:dev # Start dev mode (watch, build, and sync)
|
||||
yarn entity:add # Add a new entity (function, front-component, object, role)
|
||||
yarn app:generate # Generate typed Twenty client
|
||||
yarn function:logs # Stream function logs
|
||||
yarn function:execute # Execute a function with JSON payload
|
||||
|
||||
@@ -67,8 +67,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
const packageJson = await fs.readJson(packageJsonPath);
|
||||
expect(packageJson.name).toBe('my-test-app');
|
||||
expect(packageJson.version).toBe('0.1.0');
|
||||
expect(packageJson.dependencies['twenty-sdk']).toBe('0.3.1');
|
||||
expect(packageJson.scripts['app:sync']).toBe('twenty app:sync');
|
||||
expect(packageJson.dependencies['twenty-sdk']).toBe('0.4.0');
|
||||
expect(packageJson.scripts['app:dev']).toBe('twenty app:dev');
|
||||
});
|
||||
|
||||
|
||||
@@ -238,8 +238,6 @@ const createPackageJson = async ({
|
||||
'auth:switch': 'twenty auth:switch',
|
||||
'auth:list': 'twenty auth:list',
|
||||
'app:dev': 'twenty app:dev',
|
||||
'app:build': 'twenty app:build',
|
||||
'app:sync': 'twenty app:sync',
|
||||
'entity:add': 'twenty entity:add',
|
||||
'app:generate': 'twenty app:generate',
|
||||
'function:logs': 'twenty function:logs',
|
||||
@@ -250,7 +248,7 @@ const createPackageJson = async ({
|
||||
'lint:fix': 'eslint --fix',
|
||||
},
|
||||
dependencies: {
|
||||
'twenty-sdk': '0.3.1',
|
||||
'twenty-sdk': '0.4.0',
|
||||
},
|
||||
devDependencies: {
|
||||
typescript: '^5.9.3',
|
||||
|
||||
@@ -48,15 +48,12 @@ From here you can:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn app:create-entity
|
||||
yarn entity:add
|
||||
|
||||
# Generate a typed Twenty client and workspace entity types
|
||||
yarn app:generate
|
||||
|
||||
# Run a one‑time sync (instead of watch mode)
|
||||
yarn app:sync
|
||||
|
||||
# Watch your application's functions logs
|
||||
# Watch your application's function logs
|
||||
yarn function:logs
|
||||
|
||||
# Execute a function by name
|
||||
@@ -66,7 +63,7 @@ yarn function:execute -n my-function -p '{"name": "test"}'
|
||||
yarn app:uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn app:help
|
||||
yarn help
|
||||
```
|
||||
|
||||
See also: the CLI reference pages for [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) and [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
@@ -95,11 +92,11 @@ my-twenty-app/
|
||||
tsconfig.json
|
||||
README.md
|
||||
src/
|
||||
app/
|
||||
application.config.ts # Required - main application configuration
|
||||
default-function.role.ts # Default role for serverless functions
|
||||
// your entities (*.object.ts, *.function.ts, *.role.ts)
|
||||
utils/ # Optional - handler implementations & utilities
|
||||
application.config.ts # Required - main application configuration
|
||||
default-function.role.ts # Default role for serverless functions
|
||||
hello-world.function.ts # Example serverless function
|
||||
hello-world.front-component.tsx # Example front component
|
||||
// your entities (*.object.ts, *.function.ts, *.front-component.tsx, *.role.ts)
|
||||
```
|
||||
|
||||
### Convention-over-configuration
|
||||
@@ -110,6 +107,7 @@ Applications use a **convention-over-configuration** approach where entities are
|
||||
|-------------|-------------|
|
||||
| `*.object.ts` | Custom object definitions |
|
||||
| `*.function.ts` | Serverless function definitions |
|
||||
| `*.front-component.tsx` | Front component definitions |
|
||||
| `*.role.ts` | Role definitions |
|
||||
|
||||
### Supported folder organizations
|
||||
@@ -118,55 +116,58 @@ You can organize your entities in any of these patterns:
|
||||
|
||||
**Traditional (by type):**
|
||||
```text
|
||||
src/app/
|
||||
src/
|
||||
├── application.config.ts
|
||||
├── objects/
|
||||
│ └── postCard.object.ts
|
||||
├── functions/
|
||||
│ └── createPostCard.function.ts
|
||||
├── components/
|
||||
│ └── card.front-component.tsx
|
||||
└── roles/
|
||||
└── admin.role.ts
|
||||
```
|
||||
|
||||
**Feature-based:**
|
||||
```text
|
||||
src/app/
|
||||
src/
|
||||
├── application.config.ts
|
||||
└── post-card/
|
||||
├── postCard.object.ts
|
||||
├── createPostCard.function.ts
|
||||
├── card.front-component.tsx
|
||||
└── postCardAdmin.role.ts
|
||||
```
|
||||
|
||||
**Flat:**
|
||||
```text
|
||||
src/app/
|
||||
src/
|
||||
├── application.config.ts
|
||||
├── postCard.object.ts
|
||||
├── createPostCard.function.ts
|
||||
├── card.front-component.tsx
|
||||
└── admin.role.ts
|
||||
```
|
||||
|
||||
At a high level:
|
||||
|
||||
- **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus scripts like `dev`, `sync`, `generate`, `create-entity`, `logs`, `uninstall`, and `auth` that delegate to the local `twenty` CLI.
|
||||
- **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus scripts like `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall`, and `auth:login` that delegate to the local `twenty` CLI.
|
||||
- **.gitignore**: Ignores common artifacts such as `node_modules`, `.yarn`, `generated/` (typed client), `dist/`, `build/`, coverage folders, log files, and `.env*` files.
|
||||
- **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Lock and configure the Yarn 4 toolchain used by the project.
|
||||
- **.nvmrc**: Pins the Node.js version expected by the project.
|
||||
- **eslint.config.mjs** and **tsconfig.json**: Provide linting and TypeScript configuration for your app's TypeScript sources.
|
||||
- **README.md**: A short README in the app root with basic instructions.
|
||||
- **src/app/**: The main place where you define your application-as-code:
|
||||
- **src/**: The main place where you define your application-as-code:
|
||||
- `application.config.ts`: Global configuration for your app (metadata and runtime wiring). See "Application config" below.
|
||||
- `*.role.ts`: Role definitions used by your serverless functions. See "Default function role" below.
|
||||
- `*.object.ts`: Custom object definitions.
|
||||
- `*.function.ts`: Serverless function definitions.
|
||||
- **src/utils/**: Optional folder for handler implementations and utilities.
|
||||
- `*.front-component.tsx`: Front component definitions.
|
||||
|
||||
Later commands will add more files and folders:
|
||||
|
||||
- `yarn app:generate` will create a `generated/` folder (typed Twenty client + workspace types).
|
||||
- `yarn app:create-entity` will add entity definition files under `src/app/` for your custom objects, functions, or roles.
|
||||
l
|
||||
- `yarn entity:add` will add entity definition files under `src/` for your custom objects, functions, front components, or roles.
|
||||
|
||||
## Authentication
|
||||
|
||||
@@ -297,63 +298,12 @@ Key points:
|
||||
- The `universalIdentifier` must be unique and stable across deployments.
|
||||
- Each field requires a `name`, `type`, `label`, and its own stable `universalIdentifier`.
|
||||
- The `fields` array is optional — you can define objects without custom fields.
|
||||
- You can scaffold new objects using `yarn app:create-entity`, which guides you through naming, fields, and relationships.
|
||||
- You can scaffold new objects using `yarn entity:add`, which guides you through naming, fields, and relationships.
|
||||
|
||||
<Note>
|
||||
**Base fields are created automatically.** When you define a custom object, Twenty automatically adds standard fields such as `name`, `createdAt`, `updatedAt`, `createdBy`, `position`, and `deletedAt`. You don't need to define these in your `fields` array — only add your custom fields.
|
||||
</Note>
|
||||
|
||||
<Accordion title="Alternative: Decorator-based syntax">
|
||||
You can also define objects using TypeScript decorators. This approach uses class-based syntax with `@Object`, `@Field`, and `@Relation` decorators:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
type AddressField,
|
||||
Field,
|
||||
FieldType,
|
||||
type FullNameField,
|
||||
Object,
|
||||
OnDeleteAction,
|
||||
Relation,
|
||||
RelationType,
|
||||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
|
||||
} from 'twenty-sdk';
|
||||
import { type Note } from '../../generated';
|
||||
|
||||
@Object({
|
||||
universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
|
||||
nameSingular: 'postCard',
|
||||
namePlural: 'postCards',
|
||||
labelSingular: 'Post card',
|
||||
labelPlural: 'Post cards',
|
||||
description: 'A post card object',
|
||||
icon: 'IconMail',
|
||||
})
|
||||
export class PostCard {
|
||||
@Field({
|
||||
universalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b',
|
||||
type: FieldType.TEXT,
|
||||
label: 'Content',
|
||||
description: "Postcard's content",
|
||||
icon: 'IconAbc',
|
||||
})
|
||||
content: string;
|
||||
|
||||
@Relation({
|
||||
universalIdentifier: 'c9e2b4f4-b9ad-4427-9b42-9971b785edfe',
|
||||
type: RelationType.ONE_TO_MANY,
|
||||
label: 'Notes',
|
||||
icon: 'IconComment',
|
||||
inverseSideTargetUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.note,
|
||||
onDelete: OnDeleteAction.CASCADE,
|
||||
})
|
||||
notes: Note[];
|
||||
}
|
||||
```
|
||||
|
||||
Note: The decorator approach requires `experimentalDecorators` in your TypeScript config.
|
||||
</Accordion>
|
||||
|
||||
|
||||
### Application config (application.config.ts)
|
||||
|
||||
@@ -463,14 +413,9 @@ Each function file uses `defineFunction()` to export a configuration with a hand
|
||||
// src/app/createPostCard.function.ts
|
||||
import { defineFunction } from 'twenty-sdk';
|
||||
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk';
|
||||
import Twenty, { type Person } from '../../generated';
|
||||
import Twenty, { type Person } from '~/generated';
|
||||
|
||||
const handler = async (
|
||||
params:
|
||||
| RoutePayload
|
||||
| DatabaseEventPayload<ObjectRecordCreateEvent<Person>>
|
||||
| CronPayload,
|
||||
) => {
|
||||
const handler = async (params: RoutePayload) => {
|
||||
const client = new Twenty(); // generated typed client
|
||||
const name = 'name' in params.queryStringParameters
|
||||
? params.queryStringParameters.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world'
|
||||
@@ -501,18 +446,18 @@ export default defineFunction({
|
||||
isAuthRequired: false,
|
||||
},
|
||||
// Cron trigger (CRON pattern)
|
||||
{
|
||||
universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2',
|
||||
type: 'cron',
|
||||
pattern: '0 0 1 1 *',
|
||||
},
|
||||
// {
|
||||
// universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2',
|
||||
// type: 'cron',
|
||||
// pattern: '0 0 1 1 *',
|
||||
// },
|
||||
// Database event trigger
|
||||
{
|
||||
universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156',
|
||||
type: 'databaseEvent',
|
||||
eventName: 'person.updated',
|
||||
updatedFields: ['name'],
|
||||
},
|
||||
// {
|
||||
// universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156',
|
||||
// type: 'databaseEvent',
|
||||
// eventName: 'person.updated',
|
||||
// updatedFields: ['name'],
|
||||
// },
|
||||
],
|
||||
});
|
||||
```
|
||||
@@ -620,7 +565,7 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
You can create new functions in two ways:
|
||||
|
||||
- **Scaffolded**: Run `yarn app:create-entity` and choose the option to add a new function. This generates a starter file with a handler and config.
|
||||
- **Scaffolded**: Run `yarn entity:add` and choose the option to add a new function. This generates a starter file with a handler and config.
|
||||
- **Manual**: Create a new `*.function.ts` file and use `defineFunction()`, following the same pattern.
|
||||
|
||||
### Generated typed client
|
||||
@@ -628,13 +573,13 @@ You can create new functions in two ways:
|
||||
Run yarn app:generate to create a local typed client in generated/ based on your workspace schema. Use it in your functions:
|
||||
|
||||
```typescript
|
||||
import Twenty from './generated';
|
||||
import Twenty from '~/generated';
|
||||
|
||||
const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
The client is re-generated by `yarn app:generate`. Re-run after changing your objects and `yarn app:sync` or when onboarding to a new workspace.
|
||||
The client is re-generated by `yarn app:generate`. Re-run after changing your objects or when onboarding to a new workspace.
|
||||
|
||||
#### Runtime credentials in serverless functions
|
||||
|
||||
@@ -666,25 +611,29 @@ Then add scripts like these:
|
||||
```json filename="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
"auth": "twenty auth login",
|
||||
"generate": "twenty app generate",
|
||||
"dev": "twenty app dev",
|
||||
"sync": "twenty app sync",
|
||||
"uninstall": "twenty app uninstall",
|
||||
"logs": "twenty app logs",
|
||||
"create-entity": "twenty app add",
|
||||
"help": "twenty --help"
|
||||
"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",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
"function:execute": "twenty function:execute",
|
||||
"help": "twenty help"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now you can run the same commands via Yarn, e.g. `yarn app:dev`, `yarn app:sync`, etc.
|
||||
Now you can run the same commands via Yarn, e.g. `yarn app:dev`, `yarn app:generate`, etc.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Authentication errors: run `yarn auth:login` and ensure your API key has the required permissions.
|
||||
- Cannot connect to server: verify the API URL and that the Twenty server is reachable.
|
||||
- Types or client missing/outdated: run `yarn app:generate` and then `yarn app:dev`.
|
||||
- Types or client missing/outdated: run `yarn app:generate`.
|
||||
- Dev mode not syncing: ensure `yarn app:dev` is running and that changes are not ignored by your environment.
|
||||
|
||||
Discord Help Channel: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
A CLI and SDK to develop, build, and publish applications that extend [Twenty CRM](https://twenty.com).
|
||||
|
||||
- Type‑safe client and workspace entity typings
|
||||
- Built‑in CLI for auth, generate, dev sync, one‑off sync, and uninstall
|
||||
- Built‑in CLI for auth, dev mode (watch & sync), generate, uninstall, and function management
|
||||
- Works great with the scaffolder: [create-twenty-app](https://www.npmjs.com/package/create-twenty-app)
|
||||
|
||||
## Documentation
|
||||
See Twenty application documentation https://docs.twenty.com/developers/extend/capabilities/apps
|
||||
|
||||
## Prerequisites
|
||||
- Node.js 24+ (recommended) and Yarn 4
|
||||
- A Twenty workspace and an API key. Generate one at https://app.twenty.com/settings/api-webhooks
|
||||
@@ -43,8 +46,17 @@ Options:
|
||||
-h, --help display help for command
|
||||
|
||||
Commands:
|
||||
auth Authentication commands
|
||||
app Application development commands
|
||||
auth:login Authenticate with Twenty
|
||||
auth:logout Remove authentication credentials
|
||||
auth:status Check authentication status
|
||||
auth:switch Switch the default workspace
|
||||
auth:list List all configured workspaces
|
||||
app:dev Watch and sync local application changes
|
||||
app:generate Generate Twenty client
|
||||
app:uninstall Uninstall application from Twenty
|
||||
entity:add Add a new entity to your application
|
||||
function:logs Watch application function logs
|
||||
function:execute Execute a serverless function with a JSON payload
|
||||
help [command] display help for command
|
||||
```
|
||||
|
||||
@@ -108,27 +120,27 @@ twenty auth:switch production
|
||||
|
||||
Application development commands.
|
||||
|
||||
- `twenty app:sync [appPath]` — One-time sync of the application to your Twenty workspace.
|
||||
- Behavior: Compute your application's manifest and send it to your workspace to sync your application
|
||||
|
||||
- `twenty app:dev [appPath]` — Start development mode: sync local application changes.
|
||||
- Options:
|
||||
- `-d, --debounce <ms>`: Debounce delay in milliseconds (default: `1000`).
|
||||
- Behavior: Performs an initial sync, then watches the directory for changes and re-syncs after debounced edits. Press Ctrl+C to stop.
|
||||
- `twenty app:dev [appPath]` — Start development mode: watch and sync local application changes.
|
||||
- Behavior: Builds your application (functions and front components), computes the manifest, syncs everything to your workspace, then watches the directory for changes and re-syncs automatically. Displays an interactive UI showing build and sync status in real time. Press Ctrl+C to stop.
|
||||
|
||||
- `twenty app:uninstall [appPath]` — Uninstall the application from the current workspace.
|
||||
- Note: `twenty app:delete` exists as a hidden alias for backward compatibility.
|
||||
|
||||
- `twenty app:generate [appPath]` — Generate the typed Twenty client for your application.
|
||||
|
||||
### Entity
|
||||
|
||||
- `twenty entity:add [entityType]` — Add a new entity to your application.
|
||||
- Arguments:
|
||||
- `entityType`: one of `function` or `object`. If omitted, an interactive prompt is shown.
|
||||
- `entityType`: one of `function`, `front-component`, `object`, or `role`. If omitted, an interactive prompt is shown.
|
||||
- Options:
|
||||
- `--path <path>`: The path where the entity file should be created (relative to the current directory).
|
||||
- Behavior:
|
||||
- `object`: prompts for singular/plural names and labels, then creates a new object definition file.
|
||||
- `function`: prompts for a name and scaffolds a serverless function file.
|
||||
- `object`: prompts for singular/plural names and labels, then creates a `*.object.ts` definition file.
|
||||
- `function`: prompts for a name and scaffolds a `*.function.ts` serverless function file.
|
||||
- `front-component`: prompts for a name and scaffolds a `*.front-component.tsx` file.
|
||||
- `role`: prompts for a name and scaffolds a `*.role.ts` role definition file.
|
||||
|
||||
- `twenty app:generate [appPath]` — Generate the typed Twenty client for your application.
|
||||
### Function
|
||||
|
||||
- `twenty function:logs [appPath]` — Stream application function logs.
|
||||
- Options:
|
||||
@@ -144,24 +156,27 @@ Application development commands.
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
# Start dev mode with default debounce
|
||||
# Start dev mode (watch, build, and sync)
|
||||
twenty app:dev
|
||||
|
||||
# Start dev mode with custom workspace profile
|
||||
# Start dev mode with a custom workspace profile
|
||||
twenty app:dev --workspace my-custom-workspace
|
||||
|
||||
# Dev mode with custom debounce
|
||||
twenty app:dev --debounce 1500
|
||||
|
||||
# One-time sync of the current directory
|
||||
twenty app:sync
|
||||
|
||||
# Add a new object interactively
|
||||
# Add a new entity interactively
|
||||
twenty entity:add
|
||||
|
||||
# Add a new function
|
||||
twenty entity:add function
|
||||
|
||||
# Add a new front component
|
||||
twenty entity:add front-component
|
||||
|
||||
# Generate client types
|
||||
twenty app:generate
|
||||
|
||||
# Uninstall the app from the workspace
|
||||
twenty app:uninstall
|
||||
|
||||
# Watch all function logs
|
||||
twenty function:logs
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-sdk",
|
||||
"version": "0.3.1",
|
||||
"version": "0.4.0",
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.mjs",
|
||||
"types": "dist/index.d.ts",
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:build": "twenty app:build",
|
||||
"app:sync": "twenty app:sync",
|
||||
"entity:add": "twenty entity:add",
|
||||
"app:generate": "twenty app:generate",
|
||||
"function:logs": "twenty function:logs",
|
||||
|
||||
-2
@@ -219,8 +219,6 @@ export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
'auth:switch': 'twenty auth:switch',
|
||||
'auth:list': 'twenty auth:list',
|
||||
'app:dev': 'twenty app:dev',
|
||||
'app:build': 'twenty app:build',
|
||||
'app:sync': 'twenty app:sync',
|
||||
'entity:add': 'twenty entity:add',
|
||||
'app:generate': 'twenty app:generate',
|
||||
'function:logs': 'twenty function:logs',
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:build": "twenty app:build",
|
||||
"app:sync": "twenty app:sync",
|
||||
"entity:add": "twenty entity:add",
|
||||
"app:generate": "twenty app:generate",
|
||||
"function:logs": "twenty function:logs",
|
||||
|
||||
-2
@@ -21,8 +21,6 @@ export const EXPECTED_MANIFEST: ApplicationManifest = {
|
||||
'auth:switch': 'twenty auth:switch',
|
||||
'auth:list': 'twenty auth:list',
|
||||
'app:dev': 'twenty app:dev',
|
||||
'app:build': 'twenty app:build',
|
||||
'app:sync': 'twenty app:sync',
|
||||
'entity:add': 'twenty entity:add',
|
||||
'app:generate': 'twenty app:generate',
|
||||
'function:logs': 'twenty function:logs',
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:build": "twenty app:build",
|
||||
"app:sync": "twenty app:sync",
|
||||
"entity:add": "twenty entity:add",
|
||||
"app:generate": "twenty app:generate",
|
||||
"function:logs": "twenty function:logs",
|
||||
|
||||
@@ -2,7 +2,7 @@ import { CURRENT_EXECUTION_DIRECTORY } from '@/cli/utilities/config/current-exec
|
||||
import { getFrontComponentBaseFile } from '@/cli/utilities/entity/entity-front-component-template';
|
||||
import { getFunctionBaseFile } from '@/cli/utilities/entity/entity-function-template';
|
||||
import { convertToLabel } from '@/cli/utilities/entity/entity-label';
|
||||
import { getNewObjectFileContent } from '@/cli/utilities/entity/entity-object-template';
|
||||
import { getObjectBaseFile } from '@/cli/utilities/entity/entity-object-template';
|
||||
import { getRoleBaseFile } from '@/cli/utilities/entity/entity-role-template';
|
||||
import chalk from 'chalk';
|
||||
import * as fs from 'fs-extra';
|
||||
@@ -45,7 +45,7 @@ export class EntityAddCommand {
|
||||
// Use *.object.ts naming convention
|
||||
const objectFileName = `${camelcase(name)}.object.ts`;
|
||||
|
||||
const decoratedObject = getNewObjectFileContent({
|
||||
const decoratedObject = getObjectBaseFile({
|
||||
data: entityData,
|
||||
name,
|
||||
});
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
import { getNewObjectFileContent } from '@/cli/utilities/entity/entity-object-template';
|
||||
import { getObjectBaseFile } from '@/cli/utilities/entity/entity-object-template';
|
||||
|
||||
describe('getNewObjectFileContent', () => {
|
||||
it('should return proper object file using defineObject', () => {
|
||||
const result = getNewObjectFileContent({
|
||||
const result = getObjectBaseFile({
|
||||
data: {
|
||||
nameSingular: 'company',
|
||||
namePlural: 'companies',
|
||||
@@ -28,7 +28,7 @@ describe('getNewObjectFileContent', () => {
|
||||
});
|
||||
|
||||
it('should generate unique UUIDs for each object', () => {
|
||||
const result1 = getNewObjectFileContent({
|
||||
const result1 = getObjectBaseFile({
|
||||
data: {
|
||||
nameSingular: 'company',
|
||||
namePlural: 'companies',
|
||||
@@ -38,7 +38,7 @@ describe('getNewObjectFileContent', () => {
|
||||
name: 'company',
|
||||
});
|
||||
|
||||
const result2 = getNewObjectFileContent({
|
||||
const result2 = getObjectBaseFile({
|
||||
data: {
|
||||
nameSingular: 'person',
|
||||
namePlural: 'people',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
export const getNewObjectFileContent = ({
|
||||
export const getObjectBaseFile = ({
|
||||
data,
|
||||
}: {
|
||||
data: {
|
||||
|
||||
Reference in New Issue
Block a user