# Config

The `@aziontech/config` package is the Azion Lib library for the project configuration that the [Azion CLI](/en/documentation/devtools/cli/) reads from [azion.config.js](/en/documentation/devtools/cli/azion-config-js/). Its functions type a configuration object, turn it into a manifest, and turn a manifest back into a configuration object. The functions are synchronous, take no token, and run in Node.js.

For every key and property of the configuration object, with its type, refer to [Configuration reference](/en/documentation/devtools/cli/azion-config-js/#configuration-reference).

Install the package:

```bash
npm install @aziontech/config
```

The samples on this page are ES modules that run in Node.js, and the TypeScript samples import types with `import type`. Each sample logs part of its result, and the output under it shows what the sample prints.

---

## defineConfig

Returns the configuration object you pass, unchanged and typed as [AzionConfig](#azionconfig). `defineConfig` does not check the values: a configuration with an invalid value, such as an application with `name: ''`, passes through without an error. To find where the Azion CLI checks the values, refer to [defineConfig](/en/documentation/devtools/cli/azion-config-js/#defineconfig) on the azion.config.js page.

```typescript
function defineConfig(config: AzionConfig): AzionConfig;
```

| Parameter | Type                          | Required | Description               |
| --------- | ----------------------------- | -------- | ------------------------- |
| `config`  | [`AzionConfig`](#azionconfig) | Yes      | The configuration object. |

Returns the same `config` object.

This sample declares a JavaScript build:

```javascript
import { defineConfig } from '@aziontech/config';

const config = defineConfig({
  build: {
    entry: './src/index.js',
    preset: 'javascript',
  },
});

export default config;
console.log(JSON.stringify(config));
```

Output:

```text
{"build":{"entry":"./src/index.js","preset":"javascript"}}
```

This sample declares a build, an application with a cache setting, and an Object Storage bucket filled from a local folder:

```javascript
import { defineConfig } from '@aziontech/config';

const config = defineConfig({
  build: {
    entry: './src/index.js',
    preset: 'javascript',
    bundler: 'esbuild',
  },
  applications: [
    {
      name: 'my-app',
      active: true,
      cache: [
        {
          name: 'my-cache',
          browser: { maxAgeSeconds: 3600 },
          edge: { maxAgeSeconds: 7200 },
        },
      ],
    },
  ],
  storage: [
    {
      name: 'my-storage',
      workloadsAccess: 'read_write',
      dir: './storage',
      prefix: 'app-data',
    },
  ],
});

export default config;
console.log(Object.keys(config));
```

Output:

```text
[ 'build', 'applications', 'storage' ]
```

A JavaScript file can also declare the type with a JSDoc annotation instead of calling `defineConfig`:

```javascript
/** @type {import('@aziontech/config').AzionConfig} */
const config = {
  build: {
    entry: './src/index.js',
    preset: 'javascript',
  },
};

export default config;
console.log(JSON.stringify(config));
```

Output:

```text
{"build":{"entry":"./src/index.js","preset":"javascript"}}
```

---

## processConfig

Turns a configuration object into a manifest, an object whose keys use snake\_case names. In a cache setting, for example, `browser.maxAgeSeconds` becomes `browser_cache.max_age`, and `edge.maxAgeSeconds` becomes `modules.cache.max_age`.

```typescript
function processConfig(inputConfig: AzionConfig): any;
```

| Parameter     | Type                          | Required | Description                                       |
| ------------- | ----------------------------- | -------- | ------------------------------------------------- |
| `inputConfig` | [`AzionConfig`](#azionconfig) | Yes      | The configuration object to turn into a manifest. |

Returns the manifest, typed `any`. The manifest holds 13 top-level keys, including the ones the configuration leaves out: `build`, `purge`, `network_list`, `waf`, `storage`, `firewall`, `functions`, `applications`, `connectors`, `workloads`, `workload_deployments`, `custom_pages`, and `kv`.

The manifest also carries settings that the configuration does not declare. In the sample below, the application declares a cache setting and no `applicationAcceleratorEnabled`, and the manifest sets `application_accelerator.enabled` to `true`.

This sample turns a configuration with one application into a manifest, then prints the manifest keys and the application:

```typescript
import { processConfig } from '@aziontech/config';
import type { AzionConfig } from '@aziontech/config';

const config: AzionConfig = {
  build: { entry: './src/index.js', preset: 'javascript' },
  applications: [{ name: 'my-app', cache: [{ name: 'my-cache', browser: { maxAgeSeconds: 3600 }, edge: { maxAgeSeconds: 7200 } }] }],
};

const manifest = processConfig(config);
console.log(Object.keys(manifest));
console.log(JSON.stringify(manifest.applications, null, 1));
```

Output:

```text
[
  'build',
  'purge',
  'network_list',
  'waf',
  'storage',
  'firewall',
  'functions',
  'applications',
  'connectors',
  'workloads',
  'workload_deployments',
  'custom_pages',
  'kv'
]
[
 {
  "name": "my-app",
  "active": true,
  "debug": false,
  "modules": {
   "cache": {
    "enabled": true
   },
   "functions": {
    "enabled": false
   },
   "application_accelerator": {
    "enabled": true
   },
   "image_processor": {
    "enabled": false
   }
  },
  "cache_settings": [
   {
    "name": "my-cache",
    "browser_cache": {
     "behavior": "override",
     "max_age": 3600
    },
    "modules": {
     "cache": {
      "behavior": "override",
      "max_age": 7200,
      "stale_cache": {
       "enabled": false
      },
      "large_file_cache": {
       "enabled": false,
       "offset": 1024
      },
      "tiered_cache": {
       "enabled": false
      }
     },
     "application_accelerator": {
      "cache_vary_by_method": [],
      "cache_vary_by_querystring": {
       "behavior": "ignore",
       "fields": [],
       "sort_enabled": false
      },
      "cache_vary_by_cookies": {
       "behavior": "ignore",
       "cookie_names": []
      },
      "cache_vary_by_devices": {
       "behavior": "ignore",
       "device_group": []
      }
     }
    }
   }
  ]
 }
]
```

---

## convertJsonConfigToObject

Turns a manifest, passed as a JSON string, into a configuration object with camelCase keys. The function checks the manifest first, and it throws when the manifest lacks any of `build`, `applications`, `workloads`, and `workload_deployments`.

```typescript
function convertJsonConfigToObject(config: string): AzionConfig;
```

| Parameter | Type     | Required | Description                    |
| --------- | -------- | -------- | ------------------------------ |
| `config`  | `string` | Yes      | The manifest as a JSON string. |

Returns an [AzionConfig](#azionconfig) object. A manifest that fails the check throws an `Error`; the message is in [Errors](#errors).

This sample reads the manifest that [azion build](/en/documentation/devtools/cli/build/) writes to `.edge/manifest.json` in the project folder, and prints the keys and the workloads of the configuration:

```typescript
import { readFileSync } from 'node:fs';
import { convertJsonConfigToObject } from '@aziontech/config';

// .edge/manifest.json is the manifest that `azion build` writes
const manifestJson: string = readFileSync('.edge/manifest.json', 'utf8');

const config = convertJsonConfigToObject(manifestJson);
console.log(Object.keys(config));
console.log(JSON.stringify(config.workloads));
```

Output:

```text
[ 'build', 'firewall', 'functions', 'applications', 'workloads' ]
[{"name":"$WORKLOAD_NAME","active":true,"infrastructure":1,"workloadDomainAllowAccess":true,"domains":[],"tls":{"certificate":null,"ciphers":null,"minimumVersion":"tls_1_3"},"protocols":{"http":{"versions":["http1","http2","http3"],"httpPorts":[80],"httpsPorts":[443],"quicPorts":[443]}},"deployments":[{"name":"$DEPLOYMENT_NAME","current":true,"active":true,"strategy":{"type":"default","attributes":{"application":"$APPLICATION_NAME","firewall":null,"customPage":null}}}]}]
```

The output keeps the placeholders that the manifest holds, such as `$WORKLOAD_NAME` and `$APPLICATION_NAME`.

This sample passes a manifest that holds only `workloads`, and prints the message of the error the function throws:

```javascript
import { convertJsonConfigToObject } from '@aziontech/config';

const manifestJson = { workloads: [{ name: 'my-workload', active: true, domains: ['example.com'] }] };
try {
  console.log(convertJsonConfigToObject(JSON.stringify(manifestJson)));
} catch (err) {
  console.log(err.message);
}
```

Output:

```text
⛔️ Azion Configuration Validation Failed
--------------------------------------------------
📍 Error #1:
   Message: The 'build', 'applications', 'workloads', and 'workload_deployments' fields are required in the manifest.
--------------------------------------------------
```

---

## Errors

`convertJsonConfigToObject` throws an `Error` when the manifest fails its check. The message numbers each problem and gives its text after `Message:`.

| Message                                                                                                     | Cause                                                | What to do                                                                                  |
| ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `The 'build', 'applications', 'workloads', and 'workload_deployments' fields are required in the manifest.` | The JSON string lacks at least one of the four keys. | Pass a complete manifest, such as the `.edge/manifest.json` file that `azion build` writes. |

`defineConfig` throws no error for an invalid value, because it does not check values.

---

## Types

The package exports `AzionConfig` and the type of each of its keys, such as `AzionBuild`, `AzionApplication`, and `AzionWorkload`. Import them with `import type`.

### AzionConfig

The configuration object that every function on this page takes or returns. Every key is optional. Each type links to its properties on the azion.config.js page.

| Property       | Type                                                                                 | Required | Description                                                                 |
| -------------- | ------------------------------------------------------------------------------------ | -------- | --------------------------------------------------------------------------- |
| `build`        | [`AzionBuild`](/en/documentation/devtools/cli/azion-config-js/#build)                | No       | How the project is built.                                                   |
| `applications` | [`AzionApplication[]`](/en/documentation/devtools/cli/azion-config-js/#applications) | No       | The applications, with their cache settings, rules, and function instances. |
| `functions`    | [`AzionFunction[]`](/en/documentation/devtools/cli/azion-config-js/#functions)       | No       | The functions.                                                              |
| `connectors`   | [`AzionConnector[]`](/en/documentation/devtools/cli/azion-config-js/#connectors)     | No       | The connectors, of type `http`, `storage`, or `live_ingest`.                |
| `storage`      | [`AzionBucket[]`](/en/documentation/devtools/cli/azion-config-js/#storage)           | No       | The Object Storage buckets and the local folders whose files go into them.  |
| `firewall`     | [`AzionFirewall[]`](/en/documentation/devtools/cli/azion-config-js/#firewall)        | No       | The firewalls, with their rules.                                            |
| `networkList`  | [`AzionNetworkList[]`](/en/documentation/devtools/cli/azion-config-js/#networklist)  | No       | The network lists, of type `ip_cidr`, `asn`, or `countries`.                |
| `purge`        | [`AzionPurge[]`](/en/documentation/devtools/cli/azion-config-js/#purge)              | No       | The URLs, cache keys, or wildcards to purge.                                |
| `waf`          | [`AzionWaf[]`](/en/documentation/devtools/cli/azion-config-js/#waf)                  | No       | The Web Application Firewall (WAF) configurations.                          |
| `workloads`    | [`AzionWorkload[]`](/en/documentation/devtools/cli/azion-config-js/#workloads)       | No       | The workloads that serve the applications on domains.                       |
| `customPages`  | [`AzionCustomPage[]`](/en/documentation/devtools/cli/azion-config-js/#custompages)   | No       | The custom error pages.                                                     |
| `kv`           | [`AzionKV[]`](/en/documentation/devtools/cli/azion-config-js/#kv)                    | No       | The KV Store namespaces.                                                    |

---

## Related resources

- [Azion Lib](/en/documentation/devtools/azion-lib.md): The libraries Azion Lib ships and the package each one comes from.
- [azion.config.js](/en/documentation/devtools/cli/azion-config-js.md): The file names the CLI reads, every configuration key, and the migration from a v3 configuration.
- [Azion CLI build](/en/documentation/devtools/cli/build.md): The command that builds a project and writes the manifest to the .edge folder.
- [Azion CLI config](/en/documentation/devtools/cli/config.md): The commands that create azion.json, apply the resources of an azion.config file, and delete the resources azion.json lists.
