@synatic/entity-sync-core
v1.1.2
Published
Core Synatic entity sync logic — plan, preview, and execute against the entity-sync API
Readme
@synatic/entity-sync-core
Platform-neutral Synatic entity sync library. Generates sync plans from the entity-sync API, writes plan files to disk, and runs preview/execute against destination orgs.
Used by:
- entity-sync-action — GitHub Actions wrapper
- entity-sync-azure-devops — Azure Pipelines wrapper
Install
npm install @synatic/entity-sync-coreRoot types
Plans are built from one or more roots. Each root is an entity in the source org that anchors the dependency walk.
| rootType | Description |
| -------------- | ------------------------------------------------ |
| flow | A single flow and its forward dependencies |
| solution | A solution bundle and all bundled members |
| buffer | A buffer definition (data is not transferred) |
| dataStore | A data store and its collections |
| parameter | An org parameter (secrets become placeholders) |
| relay | A relay (new crypto generated on create) |
| userGroup | A user group (membership is not copied) |
| serviceView | A service view |
| flowTrigger | A flow trigger |
Single-root plan: --root-type flow --root-id <id>
Multi-root plan:
--roots '[{"rootType":"parameter","rootId":"P1"},{"rootType":"flow","rootId":"F1"}]'Plan options
Set at plan time via --plan-options (stored on the committed plan JSON as plan.options):
| Option | Default | Description |
| ------------------------- | ------- | ----------- |
| includeReverseDeps | false | Include entities that depend on the root |
| includeTriggers | true | Include flow triggers reachable from synced flows |
| adoptNativeOnNameMatch | false | Overwrite dest entities with the same name but no syncSource |
Example:
entity-sync plan ... --plan-options '{"includeReverseDeps":true,"adoptNativeOnNameMatch":false}'Plan graph
Each step lists:
| Field | Meaning |
| ----- | ------- |
| dependsOn | Hard dependencies (buffers, parameters, data stores, …). These drive topological order. A cycle among hard deps fails plan generation (cycle_detected). |
| softDependsOn | Other flows referenced via flow-call (not self). These do not affect sort, so recursive and mutually recursive flows can be planned. |
At execute time, softDependsOn still cascade-skips callers when a callee is excluded. Policy-skip of a callee does not cascade; the caller is rewritten to the existing destination id.
Flow-call flowIds in step payloads may still point at source ids on first write. After destination ids exist, a rewire pass remaps them. Leftover ids (callee excluded or outside the plan) are left unchanged and are not treated as failures.
Execute / preview options
Applied at preview or execute time (request body options, merged over plan.options). Lets one committed plan behave differently per destination.
| Option | Description |
| ------------------------- | ----------- |
| exclude | Blacklist: skip named entities by type; cascade-blocks dependents |
| entityPolicies.<type>.onExist | update or skip. Parameters default to skip (preserve dest values). Other types default to update. Skip keeps dest content and idMap for dependents. |
| adoptNativeOnNameMatch | Overrides the plan-time value for this run |
Example — overwrite destination parameters (opt in; skip is the default):
{
"entityPolicies": {
"parameter": { "onExist": "update" }
}
}Example — exclude specific entities:
{
"exclude": {
"parameter": { "names": ["ClientLocalSetting"] },
"flow": { "names": ["InternalOnlyFlow"] }
}
}CLI:
entity-sync execute ... \
--execute-options '{"entityPolicies":{"parameter":{"onExist":"update"}}}'Programmatic:
await client.preview(destOrgId, plan, { entityPolicies: { parameter: { onExist: "update" } } });
await client.execute(destOrgId, plan, { entityPolicies: { parameter: { onExist: "update" } } });CLI
entity-sync plan \
--api-url https://api.example.com \
--api-key syn_api_... \
--source-org-id 60ff27eab96f22106d98f1f2 \
--root-type flow \
--root-id 507f1f77bcf86cd799439011
entity-sync execute \
--api-url https://api.example.com \
--api-key syn_api_... \
--dest-org-id 507f1f77bcf86cd799439012 \
--plan-path .synatic/plans/plan.json \
--execute-options '{"entityPolicies":{"parameter":{"onExist":"update"}}}'Programmatic usage
import { parseConfig, runPlan, runExecute } from "@synatic/entity-sync-core";
const planConfig = parseConfig("plan", {
apiUrl: "https://api.example.com",
apiKey: "syn_api_...",
sourceOrgId: "60ff27eab96f22106d98f1f2",
rootType: "flow",
rootId: "507f1f77bcf86cd799439011",
});
const { plan, writtenFiles } = await runPlan(planConfig);Git operations (auto-commit, pull requests) are not part of this package — they live in platform adapters.
Development
npm install
npm test
npm run lintRelease
- Merge to
mainand verify CI passes. - Create a GitHub Release — CI publishes to npm using
NPM_TOKEN_SYNATIC. - Update consumer repos (
entity-sync-action,entity-sync-azure-devops) to pin the new version.
