# Sync CLI commands

> The commands in this section allow you to manage all project assets and sync them.

Source: https://docs.uniform.app/docs/guides/cli/commands/sync

The commands in this section allow you to manage all project assets.
[See the full list](https://docs.uniform.app/docs/guides/cli/common-tasks#sync-specific-project-assets).

## Configuration

The `uniform sync` command requires a configuration file to specify how it should work.
By default, it looks for the `uniform.config.ts` file in the project's root directory.

It's a TypeScript, JavaScript, or JSON file that exports the configuration object.
The object should have a `serialization` key with a configuration object to specify how
`uniform sync` command should work.

Here is an example of configuration file to enable backup/restore of canvas entities
with default settings (YAML format, mirror mode, `./uniform-data` directory).

```typescript
import type { CLIConfiguration } from '@uniformdev/cli';

const config: CLIConfiguration = {
  serialization: {
    entitiesConfig: {
      composition: {},
      component: {},
      projectMapDefinition: {},
      projectMapNode: {},
    }
  }
};

module.exports = config;
```

The configuration allows you to control 4 things:

- Serialization format: `yaml` or `json`
- Serialization mode: `mirror` or `createOrUpdate` or `create`
- Serialization directory or file path to store serialized data
- Serialization entities configuration: to specify which entities and how to serialize

Use will depend on your application. An example case could be where you want to push a new component from your local environment. Review the output details of the [push component](https://docs.uniform.app/docs/guides/cli/commands/canvas#push-component) command.

There are also 3 levels of granular configuration:

- Global configuration
- Per entity type configuration
- Per `pull` or `push` command configuration

Here is an example with explanation:

```typescript
import type { CLIConfiguration } from '@uniformdev/cli';

const config: CLIConfiguration = {
  // Sync command related configuration should be under "serialization" key
  serialization: {
    // Serialization format should be yaml for all enabled entities, unless other format is specified per entity type
    format: "yaml",
    // Same regarding mode
    mode: "mirror",
    // Same regarding directory. Note that every content type will be saved in its own subdirectory: `./uniform-data/<content-type>`
    directory: "./uniform-data",
    entitiesConfig: {
      // To enable serialization for specific entity type, you should add it to "entitiesConfig" object. empty object is enough
      category: {},
      component: {
        // Override serialization format for component entity type
        format: "json",
        mode: "createOrUpdate",
        directory: "./custom-directory-for-components"
      },
      composition: {
        format: "json",
        pull: {
          // Override serialization mode for composition entity type for push command
          mode: "create"
        },
        push: {
          // Disable only pushing compositions (if 'push' is not specified, it is enabled using top level settings by default)
          disabled: true
        },
        // Only pull published compositions
        state: 'published'
      }
    }
  }
}

module.exports = config;
```

The default configuration before merging with user provided configuration is:

```typescript
import type { CLIConfiguration } from '@uniformdev/cli';

const config: CLIConfiguration = {
    serialization: {
        format: "yaml",
        mode: "mirror",
        directory: "./uniform-data",
        // no entity types are enabled by default
        entitiesConfig: {}
    }
}

module.exports = config;
```

Most of the time you will need to override only `entitiesConfig` object:

```typescript
import type { CLIConfiguration } from '@uniformdev/cli';

const config: CLIConfiguration = {
  serialization: {
    format: 'yaml',
    mode: 'mirror',
    directory: './uniform-data',
    entitiesConfig: {
      aggregate: {},
      asset: {},
      category: {},
      component: {},
      componentPattern: {},
      composition: {
        push: {
          // May be useful to only create new compositions and not update existing ones to avoid accidental overrides
          mode: 'create',
        },
      },
      compositionPattern: {},
      contentType: {},
      dataType: {},
      enrichment: {},
      entry: {},
      entryPattern: {},
      label: {},
      locale: {},
      policyDocument: {},
      previewUrl: {},
      previewViewport: {},
      projectMapDefinition: {},
      projectMapNode: {},
      prompt: {},
      quirk: {},
      redirect: {},
      signal: {},
      test: {},
      webhook: {},
      workflow: {},
    },
  },
};

module.exports = config;
```

To configure this command you should provide the configuration file in one of two ways:

### Auto located file in the project root

Use the `cosmiconfig` package to locate the configuration file in the project root.
You can see [different ways of naming the configuration ](https://github.com/cosmiconfig/cosmiconfig#usage-for-end-users).

You can also use TypeScript files as configuration files. In this case, you should provide a `ts` extension in the file name.

### `--config` option

You can specify the file explicitly:

```shell
uniform sync pull --config ./production-uniform.config.ts
```

## Sync commands

### Pull

The pull command will fetch all configured project entities from the Uniform Project
and save them to the local file system. Items in [Trash](https://docs.uniform.app/docs/guides/content-organization/trash) are not exported.

```shell
uniform sync pull
```

### Push

The push command will read all configured project entities from the local file system
and push them to the target Uniform Project. In `mirror` mode, extras in the target that are not in the local files move to [Trash](https://docs.uniform.app/docs/guides/content-organization/trash).

```shell
uniform sync push
```

### Usage

#### Backup assets to a single JSON file

```typescript
import type { CLIConfiguration } from '@uniformdev/cli';

const config: CLIConfiguration = {
  serialization: {
    directory: './uniform-data/data.json',
    entitiesConfig: {
      composition: {},
      component: {},
      projectMapDefinition: {},
      projectMapNode: {},
    }
  }
};

module.exports = config;
```

#### Have different configurations for different environments

```typescript
import type { CLIConfiguration } from '@uniformdev/cli';

require('dotenv').config();

const prodConfig: CLIConfiguration = {
  serialization: {
    entitiesConfig: {
      composition: {},
      redirect: {},
      component: {},
      category: {},
      quirk: {},
      test: {},
    },
    directory: 'uniform-prodaction-data.json',
  },
};

const devConfig: CLIConfiguration = {
  serialization: {
    entitiesConfig: {
      composition: {
        push: {
          disabled: true,
        }
      },
      dataType: {
        push: {
          disabled: true,
        }
      },
      redirect: {},
      component: {},
      category: {},
      quirk: {},
      test: {},
    },
  },
};

module.exports = process.env.NODE_ENV === 'production' ? prodConfig : devConfig;
```
