kalup

kalup.config.ts

Every field defineConfig accepts, its default, and what uses it in this version

kalup.config.ts names the project, sets the pull scope and declares the targets. It holds one export default defineConfig({ ... }) and nothing else. The CLI parses it and never runs it; the defineConfig import from kalup exists only so your editor type-checks the file.

A field the reader does not know is E_NOT_DATA with a list of the fields it does know. The file follows the same grammar as the object files: Config files.

A complete example

import { defineConfig } from 'kalup'

export default defineConfig({
  // The project name, used in the IR. Defaults to the directory name.
  name: 'acme-crm',
  // Optional. validate warns when a managed property's internal name lacks it.
  prefix: 'acme_',
  // The pull scope: which objects, and which of their properties, the files hold.
  objects: {
    companies: { include: ['name', 'domain'] },
    deals: { custom: false, include: ['dealname', 'amount'] },
    subscription: {},
  },
  // The portals this project works with. A target is a named portal, never an environment.
  targets: {
    sandbox: {
      portalId: 1111111,
      credentials: { read: { env: 'HUBSPOT_SANDBOX_KEY' } },
    },
    production: {
      portalId: 2222222,
      protected: true,
      credentials: { read: { env: 'HUBSPOT_PROD_READ_KEY' } },
      overrides: {
        'property:subscription/status': { name: 'subscriptionstatus' },
      },
    },
  },
})

init writes a smaller version of this file with one target. See kalup init.

Top level

FieldTypeDefaultWhat it does
namestringthe project directory's nameThe project name. It appears as project in the IR
prefixstringnoneWhen set, validate warns (W_PREFIX) for every managed property whose internal name does not start with it. A warning never changes the exit code
objectsmap of object name to scope{}The pull scope, below
targetsmap of target name to target{}The portals, below

objects: the pull scope

Each key is an object name. A standard object uses its HubSpot name (companies, contacts, deals, tickets, line_items and the others HubSpot lists properties for by name). Any other key is read as a custom object's name, such as subscription.

FieldTypeDefaultWhat it does
custombooleantruePull every property HubSpot did not define
includestring[][]HubSpot-defined properties to pull as well, by internal name
asstringPascalCase singular of the keyThe export name pull gives the object when it writes the object for the first time. companies becomes Company, line_items becomes LineItem by default. An export that already exists keeps its name: rename it in the file

A portal property is in scope when include names it, or when it is custom and custom is on. custom plus include is the only way to select properties. Without a scope, contacts alone hold hundreds of properties, so init warns when a first pull writes more than 200 properties for one object.

To see what the portal has outside the scope without writing anything, run kalup pull --discover. See kalup pull.

targets

A target is a named portal pinned to a portal ID. Every command that reads a target checks the key's portal against the pin first, and stops before reading anything when they differ.

FieldTypeDefaultWhat it does
portalIdpositive integerrequiredThe Hub ID of the portal. The wrong-portal guard. Missing or not a positive integer is E_PORTAL_ID
credentials.read.envstringHUBSPOT_SERVICE_KEYThe environment variable that holds the read key. credentials needs read when present
credentials.write.envstringnoneParsed and kept for the release that writes. Unused in this version
protectedbooleanfalseMarks a portal where changes need a person at a terminal. init sets it for a standard (production) account. Unused by the read-only commands
drift'hold' or 'overwrite'omitted, which plans will treat as 'hold'How a plan treats edits made in the HubSpot UI. Parsed and validated only
overridesmap of address to override{}Per-target differences, below

A target may not be named config (E_TARGET_NAME): compare reserves that word for the config side.

The key is read from the environment or from .env in the project directory, and it is never printed. Targets and credentials covers keys, scopes and the portal check.

overrides

An override lets one target differ from the files for one resource. The key is an address that exists in config; anything else is E_UNKNOWN_OVERRIDE.

FieldTypeUsed in this versionWhat it does
namestringyes, by pullThe internal name this resource has on this target. 'property:subscription/status': { name: 'subscriptionstatus' } makes pull read subscriptionstatus on that target and write it under status
skiptrueparsed and validatedLeave the resource out on this target
definitiona property definitionparsed and validatedDefinition fields that differ on this target
lookupmap of string to stringparsed and validatedValues that differ on this target

Any other override field is E_NOT_DATA.

What this version uses

FieldRead by
nameir and every command that loads the project
prefixvalidate
objectspull, init, status (to list the read scopes the key needs)
targets.*.portalId, credentials.readpull, status, init
targets.*.overrides.*.namepull
protected, drift, credentials.write, skip, definition, lookupParsed, validated and carried into the IR where the IR has a place for them. No command acts on them yet

Credentials never enter the IR. kalup ir shows each target's portalId, protected, drift and overrides, and nothing else about it.

Kalup is an independent open-source project maintained by Scopious. It is not affiliated with, endorsed by, or sponsored by HubSpot, Inc. HubSpot is a registered trademark of HubSpot, Inc.

On this page