@epilot/cli 0.1.103 → 0.1.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.0.3",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Integration Toolkit API",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.13.0",
|
|
6
6
|
"description": "API for integrating with external systems in a standardised way."
|
|
7
7
|
},
|
|
8
8
|
"tags": [
|
|
@@ -4125,6 +4125,11 @@
|
|
|
4125
4125
|
"properties": {
|
|
4126
4126
|
"s3_reference": {
|
|
4127
4127
|
"$ref": "#/components/schemas/S3Reference"
|
|
4128
|
+
},
|
|
4129
|
+
"include_preview": {
|
|
4130
|
+
"type": "boolean",
|
|
4131
|
+
"default": false,
|
|
4132
|
+
"description": "Return a sample of the file's first rows. Informational only — `:validate` is still the authority. `preview` is present iff this is true."
|
|
4128
4133
|
}
|
|
4129
4134
|
}
|
|
4130
4135
|
},
|
|
@@ -4153,7 +4158,8 @@
|
|
|
4153
4158
|
"use_case_slug",
|
|
4154
4159
|
"use_case_name",
|
|
4155
4160
|
"matched_columns",
|
|
4156
|
-
"file_columns"
|
|
4161
|
+
"file_columns",
|
|
4162
|
+
"entity_types"
|
|
4157
4163
|
],
|
|
4158
4164
|
"properties": {
|
|
4159
4165
|
"integration_id": {
|
|
@@ -4168,6 +4174,10 @@
|
|
|
4168
4174
|
"use_case_name": {
|
|
4169
4175
|
"type": "string"
|
|
4170
4176
|
},
|
|
4177
|
+
"entity_types": {
|
|
4178
|
+
"type": "integer",
|
|
4179
|
+
"description": "How many distinct entity schemas this mapping uses."
|
|
4180
|
+
},
|
|
4171
4181
|
"matched_columns": {
|
|
4172
4182
|
"type": "integer",
|
|
4173
4183
|
"description": "How many of the FILE's columns this use case reads, by exact trimmed name."
|
|
@@ -4325,6 +4335,41 @@
|
|
|
4325
4335
|
}
|
|
4326
4336
|
}
|
|
4327
4337
|
},
|
|
4338
|
+
"ErpImportFilePreview": {
|
|
4339
|
+
"type": "object",
|
|
4340
|
+
"description": "Sample of the file's first rows, using the same parser as `:validate`. `status` is the outcome of this read, not a verdict on the file.",
|
|
4341
|
+
"required": [
|
|
4342
|
+
"status"
|
|
4343
|
+
],
|
|
4344
|
+
"properties": {
|
|
4345
|
+
"status": {
|
|
4346
|
+
"type": "string",
|
|
4347
|
+
"description": "Treat an unrecognized value as \"no preview available\". Values may be added. UNREADABLE covers empty, header-only, malformed, or gone — there is no breakdown; `:validate` reports the reason.",
|
|
4348
|
+
"enum": [
|
|
4349
|
+
"AVAILABLE",
|
|
4350
|
+
"FORMAT_UNSUPPORTED",
|
|
4351
|
+
"UNREADABLE"
|
|
4352
|
+
]
|
|
4353
|
+
},
|
|
4354
|
+
"columns": {
|
|
4355
|
+
"type": "array",
|
|
4356
|
+
"description": "Effective column names (trimmed, duplicates collapsed). Set iff `status` is AVAILABLE.",
|
|
4357
|
+
"items": {
|
|
4358
|
+
"type": "string"
|
|
4359
|
+
}
|
|
4360
|
+
},
|
|
4361
|
+
"rows": {
|
|
4362
|
+
"type": "array",
|
|
4363
|
+
"description": "Up to the first 5 data rows, aligned to `columns`.",
|
|
4364
|
+
"items": {
|
|
4365
|
+
"type": "array",
|
|
4366
|
+
"items": {
|
|
4367
|
+
"type": "string"
|
|
4368
|
+
}
|
|
4369
|
+
}
|
|
4370
|
+
}
|
|
4371
|
+
}
|
|
4372
|
+
},
|
|
4328
4373
|
"CreateErpImportResponse": {
|
|
4329
4374
|
"type": "object",
|
|
4330
4375
|
"required": [
|
|
@@ -4334,6 +4379,9 @@
|
|
|
4334
4379
|
"import_id": {
|
|
4335
4380
|
"type": "string",
|
|
4336
4381
|
"description": "`imp_{ULID}` — time-ordered, also used as the job's correlation_id."
|
|
4382
|
+
},
|
|
4383
|
+
"preview": {
|
|
4384
|
+
"$ref": "#/components/schemas/ErpImportFilePreview"
|
|
4337
4385
|
}
|
|
4338
4386
|
}
|
|
4339
4387
|
},
|
|
@@ -5738,6 +5786,11 @@
|
|
|
5738
5786
|
"description": "The Event Catalog event name that triggers this outbound flow",
|
|
5739
5787
|
"example": "contract.created"
|
|
5740
5788
|
},
|
|
5789
|
+
"event_filter": {
|
|
5790
|
+
"type": "string",
|
|
5791
|
+
"description": "JSONata boolean predicate over the hydrated event payload. The use case handles the\nevent only when this evaluates truthy; when absent it handles every event of its name,\nwhich is the behaviour of every pre-existing configuration.\n\nThis is where event scoping belongs — narrowing to certain ticket purposes, contract\ntypes or channels. Evaluation input is the full hydrated event, so relation nodes such\nas `ticket` and `contact` are populated. An expression that throws is treated as no\nmatch and logged, so one malformed filter cannot block the other use cases subscribed\nto the same event.\n",
|
|
5792
|
+
"example": "$count(ticket._purpose[$ in ['bae4b4d1-d728-49ef-92ff-54486dd301b4']]) > 0"
|
|
5793
|
+
},
|
|
5741
5794
|
"mappings": {
|
|
5742
5795
|
"type": "array",
|
|
5743
5796
|
"minItems": 1,
|
|
@@ -5745,6 +5798,15 @@
|
|
|
5745
5798
|
"$ref": "#/components/schemas/OutboundMapping"
|
|
5746
5799
|
},
|
|
5747
5800
|
"description": "List of mappings that transform and deliver the event"
|
|
5801
|
+
},
|
|
5802
|
+
"ack_tracking": {
|
|
5803
|
+
"type": "string",
|
|
5804
|
+
"enum": [
|
|
5805
|
+
"on",
|
|
5806
|
+
"off"
|
|
5807
|
+
],
|
|
5808
|
+
"default": "on",
|
|
5809
|
+
"description": "Whether this use case participates in the acknowledgement protocol.\n\n`on` (the default, and the behaviour of every pre-existing use case) records an\nACK_PENDING on each event and expects the consumer to confirm receipt via\n`POST /v1/erp/tracking/acknowledgement`; unconfirmed events raise ACK_TIMEOUT after\nthe timeout window.\n\n`off` opts the use case out entirely: no tracking row, no ACK_PENDING, no\nACK_TIMEOUT. Set it for consumers that never acknowledge — otherwise every event\nproduces a guaranteed timeout warning — and for deliveries that already keep their\nown durable per-item record, such as `file_proxy`.\n\nThe tracking row is per-event, not per-use-case, so it is suppressed only when EVERY\nenabled use case matching the event has opted out.\n"
|
|
5748
5810
|
}
|
|
5749
5811
|
}
|
|
5750
5812
|
},
|
|
@@ -7854,11 +7916,63 @@
|
|
|
7854
7916
|
"FileProxyUseCaseConfiguration": {
|
|
7855
7917
|
"type": "object",
|
|
7856
7918
|
"required": [
|
|
7857
|
-
"steps"
|
|
7858
|
-
"response"
|
|
7919
|
+
"steps"
|
|
7859
7920
|
],
|
|
7860
|
-
"description": "Configuration for file_proxy use cases. Defines how to authenticate and
|
|
7921
|
+
"description": "Configuration for file_proxy use cases. Defines how to authenticate and move files\nbetween epilot and an external document system, in either direction (see `direction`).\n\n**Download** (`direction: download`, the default) fetches a file from the external system\nand serves it to a browser. The download URL always requires `orgId`, `integrationId`, and\neither `useCaseSlug` (recommended) or `useCaseId` (legacy UUID) as query parameters.\nThe `orgId` is included in the signed URL to establish organization context without\nrequiring authentication. Additional use-case-specific parameters are declared in the\n`params` array. `response` is REQUIRED for download use cases.\n\n**Upload** (`direction: upload`) pushes epilot files to the external system. It is not\nreachable over the download endpoint; an outbound use case points at it via a `file_proxy`\ndelivery, and this configuration owns everything about what gets sent: `fan_out` decides\nhow many deliveries one event produces, `params_mapping` builds the values, and the\n`steps` place those values into requests via `{{ params.* }}`.\n`upload` and `params_mapping` are REQUIRED and `response` MUST be omitted.\n\nOpenAPI 3.0 cannot express this conditional requiredness, so it is enforced by the\nserver-side validator, which returns an explicit message naming the offending field.\n",
|
|
7861
7922
|
"properties": {
|
|
7923
|
+
"direction": {
|
|
7924
|
+
"type": "string",
|
|
7925
|
+
"enum": [
|
|
7926
|
+
"download",
|
|
7927
|
+
"upload"
|
|
7928
|
+
],
|
|
7929
|
+
"default": "download",
|
|
7930
|
+
"description": "Direction of file travel. `download` (default) pulls a file from the external system\ninto epilot; `upload` pushes an epilot file out to the external system. Omitted means\n`download`, so every pre-existing configuration keeps its exact meaning.\n\nNote this is the direction of the FILE, not the epilot use-case type — an `upload`\nfile_proxy use case is still a `file_proxy` use case, never an `outbound` one.\n"
|
|
7931
|
+
},
|
|
7932
|
+
"upload": {
|
|
7933
|
+
"$ref": "#/components/schemas/FileProxyUploadConfig"
|
|
7934
|
+
},
|
|
7935
|
+
"fan_out": {
|
|
7936
|
+
"$ref": "#/components/schemas/FileProxyFanOutConfig"
|
|
7937
|
+
},
|
|
7938
|
+
"params_mapping": {
|
|
7939
|
+
"type": "string",
|
|
7940
|
+
"description": "Upload-only, REQUIRED when `direction` is `upload`. JSONata expression evaluated once\nper fan-out item, producing the `params` object that step templates read as\n`{{ params.* }}`.\n\nThe evaluation root is the hydrated event, so `contact.customer_pin` and\n`ticket._purpose` are reachable directly, unprefixed.\n\n**Everything per-item is a `$`-prefixed JSONata binding**: `$item` (the fan-out\nelement, absent when `fan_out` is disabled), `$file_base64` and `$file`\n(`{filename, mime_type, size_bytes}`) for the resolved file, plus `$constants`,\n`$lookups`, `$ack_id`, `$germanDate(iso)` and `$now()`. Writing `item.filename`\ninstead of `$item.filename` yields nothing — it reads a field named `item` on the\nevent, which does not exist.\n\nMust evaluate to an object. `constants` are shallow-merged underneath the result, so\nthe expression wins on any key collision.\n",
|
|
7941
|
+
"example": "{ \"documentType\": $lookups.documentType, \"fileName\": $item.filename, \"fileData\": $file_base64, \"pin\": contact.customer_pin }"
|
|
7942
|
+
},
|
|
7943
|
+
"lookups": {
|
|
7944
|
+
"type": "object",
|
|
7945
|
+
"additionalProperties": {
|
|
7946
|
+
"$ref": "#/components/schemas/FileProxyLookup"
|
|
7947
|
+
},
|
|
7948
|
+
"description": "Upload-only. Named translation tables resolved BEFORE `params_mapping` runs and bound\nas `$lookups`, so an expression reads `$lookups.documentType` rather than carrying a\nconditional chain. Deliberately generic: the next ERP calls the same concept\n`Belegart`.\n"
|
|
7949
|
+
},
|
|
7950
|
+
"constants": {
|
|
7951
|
+
"type": "object",
|
|
7952
|
+
"additionalProperties": true,
|
|
7953
|
+
"description": "Upload-only. Fixed values shallow-merged UNDERNEATH the `params_mapping` result — the\nexpression wins on key collisions, constants only add. Use for the unchanging strings\n(tenant, sender, channel) that would otherwise be repeated in every expression.\n",
|
|
7954
|
+
"example": {
|
|
7955
|
+
"mandant": "EPILOT_WNG",
|
|
7956
|
+
"sender": "KSSP"
|
|
7957
|
+
}
|
|
7958
|
+
},
|
|
7959
|
+
"file_source": {
|
|
7960
|
+
"type": "string",
|
|
7961
|
+
"description": "Upload-only. JSONata returning the attachment-shaped object (`entity_id`, optionally\n`s3ref`) whose bytes should be fetched for this delivery. The evaluation root is the\nevent; the fan-out element is the `$item` binding, same as in `params_mapping`.\n\nUsually unnecessary: when the fan-out item is itself attachment-shaped it is used\ndirectly. Supply this only when splitting over something that is not the attachment\n— for example one delivery per meter reading, each carrying a file referenced from\nelsewhere in the event. When nothing resolves, no file is fetched and `file_base64`\nis undefined, which is valid for a fan-out that sends metadata only.\n",
|
|
7962
|
+
"example": "event_attachments[entity_id = $item.file_id][0]"
|
|
7963
|
+
},
|
|
7964
|
+
"required_params": {
|
|
7965
|
+
"type": "array",
|
|
7966
|
+
"items": {
|
|
7967
|
+
"type": "string"
|
|
7968
|
+
},
|
|
7969
|
+
"description": "Upload-only. Params that MUST be present after `params_mapping` runs. Any listed name\nresolving to null or undefined fails the delivery terminally with\n`REQUIRED_PARAM_MISSING` before a single step executes.\n\nThis is the generic net behind a lookup's `on_miss: fail`: it catches a required field\ngoing missing for any reason, so the external system never receives a body that is\nsilently short a field its API requires.\n",
|
|
7970
|
+
"example": [
|
|
7971
|
+
"documentType",
|
|
7972
|
+
"fileName",
|
|
7973
|
+
"fileData"
|
|
7974
|
+
]
|
|
7975
|
+
},
|
|
7862
7976
|
"secure_proxy": {
|
|
7863
7977
|
"description": "Optional secure proxy attachment for routing all outbound file proxy requests.\nOnly `use_case_slug` is supported and the referenced secure_proxy use case\nmust belong to the same integration.\n",
|
|
7864
7978
|
"allOf": [
|
|
@@ -7875,7 +7989,7 @@
|
|
|
7875
7989
|
"items": {
|
|
7876
7990
|
"$ref": "#/components/schemas/FileProxyParam"
|
|
7877
7991
|
},
|
|
7878
|
-
"description": "Additional use-case-specific parameters expected in the download URL
|
|
7992
|
+
"description": "Download-only. Additional use-case-specific parameters expected in the download URL\nquery string (beyond the required orgId, integrationId, and useCaseSlug or useCaseId).\nRejected when `direction` is `upload`.\n"
|
|
7879
7993
|
},
|
|
7880
7994
|
"allowed_origins": {
|
|
7881
7995
|
"type": "array",
|
|
@@ -7884,7 +7998,7 @@
|
|
|
7884
7998
|
"format": "uri",
|
|
7885
7999
|
"pattern": "^https?://"
|
|
7886
8000
|
},
|
|
7887
|
-
"description": "Additional origins permitted to call /download for this use case
|
|
8001
|
+
"description": "Download-only. Additional origins permitted to call /download for this use case\n(CORS, exact match). Portal origins are always allowed. Rejected when `direction`\nis `upload`.\n"
|
|
7888
8002
|
},
|
|
7889
8003
|
"steps": {
|
|
7890
8004
|
"type": "array",
|
|
@@ -7892,7 +8006,7 @@
|
|
|
7892
8006
|
"items": {
|
|
7893
8007
|
"$ref": "#/components/schemas/FileProxyStep"
|
|
7894
8008
|
},
|
|
7895
|
-
"description": "Ordered list of HTTP steps to execute
|
|
8009
|
+
"description": "Ordered list of HTTP steps to execute. For `download` these retrieve the file; for\n`upload` they deliver it, each assembling its own request body from `{{ params.* }}`\nbuilt by `params_mapping`.\n"
|
|
7896
8010
|
},
|
|
7897
8011
|
"response": {
|
|
7898
8012
|
"$ref": "#/components/schemas/FileProxyResponseConfig"
|
|
@@ -7900,7 +8014,7 @@
|
|
|
7900
8014
|
"prevent_indirect_serving": {
|
|
7901
8015
|
"type": "boolean",
|
|
7902
8016
|
"default": false,
|
|
7903
|
-
"description": "
|
|
8017
|
+
"description": "Download-only; rejected when `direction` is `upload`.\nWhen `true`, this use case is served via the streaming endpoint: mapped file URLs\nare built as `/stream/download`, files of any size are streamed inline over HTTP\nresponse streaming, and buffered `/download` requests for oversize files are\n307-redirected to `/stream`. Files never transit epilot's temporary S3 storage on\nthe streaming path. Defaults to `false` (small files are served directly and large\nfiles are transparently served via a temporary S3 redirect).\n"
|
|
7904
8018
|
}
|
|
7905
8019
|
}
|
|
7906
8020
|
},
|
|
@@ -8026,7 +8140,9 @@
|
|
|
8026
8140
|
"type": "string",
|
|
8027
8141
|
"enum": [
|
|
8028
8142
|
"GET",
|
|
8029
|
-
"POST"
|
|
8143
|
+
"POST",
|
|
8144
|
+
"PUT",
|
|
8145
|
+
"PATCH"
|
|
8030
8146
|
],
|
|
8031
8147
|
"description": "HTTP method"
|
|
8032
8148
|
},
|
|
@@ -8039,7 +8155,7 @@
|
|
|
8039
8155
|
},
|
|
8040
8156
|
"body": {
|
|
8041
8157
|
"type": "string",
|
|
8042
|
-
"description": "Handlebars template for the request body (
|
|
8158
|
+
"description": "Handlebars template for the request body (write methods only). On an `upload` use\ncase this is where the payload is assembled, reading `{{ params.* }}` built by\n`params_mapping`, plus `{{ env.* }}` and `{{ steps.N.body }}`.\n\n**Route every user-controlled value through the `json` helper**: the template engine\ndoes not escape, so `\"name\":\"{{ params.fileName }}\"` produces invalid JSON the moment\na filename contains a quote. Write `\"name\": {{json params.fileName}}` instead — the\nhelper emits the surrounding quotes itself and renders absent values as `null`. Use\n`{{jsonEscape v}}` if you prefer to keep your own quotes. Upload configurations whose\nbody would break on such input are rejected at save time.\n\nHandlebars block helpers work, so optional fields can be omitted rather than sent\nempty: `{{#if params.pin}},\"pin\": {{json params.pin}}{{/if}}`. Note that `{{/if}}}`\nfails to parse — leave a space before a closing brace: `{{/if}} }`.\n"
|
|
8043
8159
|
},
|
|
8044
8160
|
"response_type": {
|
|
8045
8161
|
"type": "string",
|
|
@@ -8051,8 +8167,56 @@
|
|
|
8051
8167
|
}
|
|
8052
8168
|
}
|
|
8053
8169
|
},
|
|
8170
|
+
"FileProxyFanOutConfig": {
|
|
8171
|
+
"type": "object",
|
|
8172
|
+
"required": [
|
|
8173
|
+
"enabled"
|
|
8174
|
+
],
|
|
8175
|
+
"description": "Splits one event into several independent deliveries.\n\nMirrors the inbound mapping idiom, where an entity's JSONata expression returning an array\nproduces one entity update per element. Made explicit with a toggle here because an upload\nis also legitimately used without splitting, and because auto-detecting \"array means\nsplit\" would make a single-element result ambiguous.\n\nEach resulting delivery is fully independent: its own idempotency record, its own retry\nschedule, its own monitoring events. A four-item event can therefore end up three-of-four\ndelivered, which is the honest state to report.\n\nThe split is evaluated ONCE, when the event is enqueued, so item indices — and therefore\nidempotency keys — stay stable across retries.\n",
|
|
8176
|
+
"properties": {
|
|
8177
|
+
"enabled": {
|
|
8178
|
+
"type": "boolean",
|
|
8179
|
+
"description": "When false (or absent), the event produces exactly one delivery and `$item` is not\nbound in `params_mapping`.\n"
|
|
8180
|
+
},
|
|
8181
|
+
"split_expression": {
|
|
8182
|
+
"type": "string",
|
|
8183
|
+
"description": "JSONata over the event that MUST return an array; one delivery is created per element,\nbound as `$item` in `params_mapping`. Required when `enabled` is true.\n\nKeep this a plain projection — scoping which events are handled at all belongs in the\noutbound use case's `event_filter`, not here. A non-array result fails the event with\n`FAN_OUT_INVALID_RESULT`; an empty array produces no deliveries and one info-level\n`FAN_OUT_EMPTY`, which is the normal outcome for a catch-all subscription seeing an\nevent with nothing to send.\n",
|
|
8184
|
+
"example": "event_attachments"
|
|
8185
|
+
}
|
|
8186
|
+
}
|
|
8187
|
+
},
|
|
8188
|
+
"FileProxyUploadConfig": {
|
|
8189
|
+
"type": "object",
|
|
8190
|
+
"description": "Upload-side settings for a file_proxy use case with `direction: upload`.\nEverything about WHAT is sent lives on the outbound mapping\n(see `FileProxyDeliveryConfig`); this object only governs HOW the transfer is bounded\nand judged.\n",
|
|
8191
|
+
"properties": {
|
|
8192
|
+
"max_file_bytes": {
|
|
8193
|
+
"type": "integer",
|
|
8194
|
+
"minimum": 1,
|
|
8195
|
+
"maximum": 104857600,
|
|
8196
|
+
"description": "Per-file ceiling for this use case, in bytes. Files above it fail terminally with\n`FILE_TOO_LARGE` before any bytes are fetched. Defaults to — and is clamped by — the\nplatform ceiling of 100 MiB (104857600).\n"
|
|
8197
|
+
},
|
|
8198
|
+
"max_delivery_attempts": {
|
|
8199
|
+
"type": "integer",
|
|
8200
|
+
"minimum": 1,
|
|
8201
|
+
"maximum": 100,
|
|
8202
|
+
"default": 8,
|
|
8203
|
+
"description": "Maximum delivery attempts per item before the delivery is marked failed and the\nmessage is dead-lettered. Attempts are spaced by an exponential, jittered backoff\nspanning roughly 16 hours over the default 8 attempts, so an ERP maintenance window\ndoes not exhaust them.\n\nLives here rather than on the outbound delivery because how hard to retry is a\nproperty of the transport — the same judgement as `max_file_bytes` — and the outbound\ndelivery is a pure pointer.\n"
|
|
8204
|
+
},
|
|
8205
|
+
"success_when": {
|
|
8206
|
+
"type": "string",
|
|
8207
|
+
"description": "Optional JSONata predicate evaluated against the final step result\n(`{ statusCode, headers, body }`) to decide whether the external system really\naccepted the file. When omitted, any 2xx counts as delivered. Use this for systems\nthat return 200 with an error envelope.\n",
|
|
8208
|
+
"example": "body.status = 'OK'"
|
|
8209
|
+
},
|
|
8210
|
+
"external_id": {
|
|
8211
|
+
"type": "string",
|
|
8212
|
+
"description": "Optional JSONata expression over the step results yielding the external system's\nidentifier for the stored document. Recorded on the delivery record and on the\n`FILE_PROXY_UPLOADED` monitoring event so an operator can find the document in the\ntarget system.\n",
|
|
8213
|
+
"example": "steps[-1].body.documentId"
|
|
8214
|
+
}
|
|
8215
|
+
}
|
|
8216
|
+
},
|
|
8054
8217
|
"FileProxyResponseConfig": {
|
|
8055
8218
|
"type": "object",
|
|
8219
|
+
"description": "How to extract the file from the step results. REQUIRED when `direction` is `download`;\nrejected when `direction` is `upload` (an upload has no file to extract).\n",
|
|
8056
8220
|
"required": [
|
|
8057
8221
|
"body",
|
|
8058
8222
|
"encoding"
|
|
@@ -8570,7 +8734,7 @@
|
|
|
8570
8734
|
"enabled",
|
|
8571
8735
|
"delivery"
|
|
8572
8736
|
],
|
|
8573
|
-
"description": "A mapping that delivers an event to an external system —
|
|
8737
|
+
"description": "A mapping that delivers an event to an external system by one of three mechanisms — pushed to a webhook (with a JSONata payload transformation), made available on the pull-based poll queue (raw event payload, no transformation), or handed to a file_proxy use case that uploads files to an external document system (a pointer only; the referenced use case owns the payload and the fan-out)",
|
|
8574
8738
|
"properties": {
|
|
8575
8739
|
"id": {
|
|
8576
8740
|
"type": "string",
|
|
@@ -8584,7 +8748,7 @@
|
|
|
8584
8748
|
},
|
|
8585
8749
|
"jsonata_expression": {
|
|
8586
8750
|
"type": "string",
|
|
8587
|
-
"description": "JSONata expression to transform the event payload. Required for webhook delivery
|
|
8751
|
+
"description": "JSONata expression to transform the event payload. Required for webhook delivery, ignored for poll delivery, and rejected for file_proxy delivery — a file_proxy payload is built by the referenced use case's `params_mapping`, so accepting an expression here would silently do nothing.",
|
|
8588
8752
|
"example": "{ \"id\": entity._id, \"customer\": entity.customer_name }"
|
|
8589
8753
|
},
|
|
8590
8754
|
"enabled": {
|
|
@@ -8608,20 +8772,24 @@
|
|
|
8608
8772
|
}
|
|
8609
8773
|
},
|
|
8610
8774
|
"DeliveryConfig": {
|
|
8611
|
-
"description": "Configuration for how the event should be delivered. webhook = push delivery via svc-webhooks (JSONata-transformed payload); poll = pull-based queue delivery where the consumer fetches items via the poll API (raw event payload)",
|
|
8775
|
+
"description": "Configuration for how the event should be delivered. webhook = push delivery via svc-webhooks (JSONata-transformed payload); poll = pull-based queue delivery where the consumer fetches items via the poll API (raw event payload); file_proxy = one push per event attachment to an external document system, through a file_proxy use case (JSONata-transformed payload carrying the file bytes)",
|
|
8612
8776
|
"oneOf": [
|
|
8613
8777
|
{
|
|
8614
8778
|
"$ref": "#/components/schemas/WebhookDeliveryConfig"
|
|
8615
8779
|
},
|
|
8616
8780
|
{
|
|
8617
8781
|
"$ref": "#/components/schemas/PollDeliveryConfig"
|
|
8782
|
+
},
|
|
8783
|
+
{
|
|
8784
|
+
"$ref": "#/components/schemas/FileProxyDeliveryConfig"
|
|
8618
8785
|
}
|
|
8619
8786
|
],
|
|
8620
8787
|
"discriminator": {
|
|
8621
8788
|
"propertyName": "type",
|
|
8622
8789
|
"mapping": {
|
|
8623
8790
|
"webhook": "#/components/schemas/WebhookDeliveryConfig",
|
|
8624
|
-
"poll": "#/components/schemas/PollDeliveryConfig"
|
|
8791
|
+
"poll": "#/components/schemas/PollDeliveryConfig",
|
|
8792
|
+
"file_proxy": "#/components/schemas/FileProxyDeliveryConfig"
|
|
8625
8793
|
}
|
|
8626
8794
|
}
|
|
8627
8795
|
},
|
|
@@ -8693,6 +8861,67 @@
|
|
|
8693
8861
|
}
|
|
8694
8862
|
}
|
|
8695
8863
|
},
|
|
8864
|
+
"FileProxyDeliveryConfig": {
|
|
8865
|
+
"type": "object",
|
|
8866
|
+
"required": [
|
|
8867
|
+
"type",
|
|
8868
|
+
"use_case_slug"
|
|
8869
|
+
],
|
|
8870
|
+
"description": "Push delivery to an external document system through a `file_proxy` use case.\n\nA pure pointer, deliberately. The outbound use case decides WHEN to deliver — its event\nname plus `event_filter` — and the referenced `file_proxy` use case decides WHAT and HOW:\nwhich items to fan out over (`fan_out`), what values to build (`params_mapping`,\n`lookups`, `constants`), and the steps that send them. Keeping every file concern on the\nfile_proxy side is what lets one upload recipe be shared by several event subscriptions\nwithout duplicating any of it.\n\n`jsonata_expression` on the mapping is NOT used for this delivery type and is rejected.\n\nThe slug is resolved at delivery time, not at save time, so use cases can be saved in any\norder; a dangling reference surfaces as a `USE_CASE_NOT_FOUND` monitoring event naming\nthe referencing mapping.\n",
|
|
8871
|
+
"properties": {
|
|
8872
|
+
"type": {
|
|
8873
|
+
"type": "string",
|
|
8874
|
+
"enum": [
|
|
8875
|
+
"file_proxy"
|
|
8876
|
+
],
|
|
8877
|
+
"description": "Delivery mechanism type"
|
|
8878
|
+
},
|
|
8879
|
+
"use_case_slug": {
|
|
8880
|
+
"type": "string",
|
|
8881
|
+
"description": "Slug of a `file_proxy` use case with `direction: upload` in the SAME integration.\n",
|
|
8882
|
+
"example": "wemag_d3_document_upload"
|
|
8883
|
+
}
|
|
8884
|
+
}
|
|
8885
|
+
},
|
|
8886
|
+
"FileProxyLookup": {
|
|
8887
|
+
"type": "object",
|
|
8888
|
+
"required": [
|
|
8889
|
+
"source",
|
|
8890
|
+
"entries"
|
|
8891
|
+
],
|
|
8892
|
+
"description": "A named translation from a value in the event to a value the external system expects.\n",
|
|
8893
|
+
"properties": {
|
|
8894
|
+
"source": {
|
|
8895
|
+
"type": "string",
|
|
8896
|
+
"description": "JSONata expression over the event producing the lookup key",
|
|
8897
|
+
"example": "ticket._purpose_name[0]"
|
|
8898
|
+
},
|
|
8899
|
+
"entries": {
|
|
8900
|
+
"type": "object",
|
|
8901
|
+
"additionalProperties": {
|
|
8902
|
+
"type": "string"
|
|
8903
|
+
},
|
|
8904
|
+
"description": "Key-to-value translation table",
|
|
8905
|
+
"example": {
|
|
8906
|
+
"Zählerstandsmeldung": "Zählerstand",
|
|
8907
|
+
"Kündigung": "Kündigung"
|
|
8908
|
+
}
|
|
8909
|
+
},
|
|
8910
|
+
"default": {
|
|
8911
|
+
"type": "string",
|
|
8912
|
+
"description": "Value used when the key is absent from `entries`"
|
|
8913
|
+
},
|
|
8914
|
+
"on_miss": {
|
|
8915
|
+
"type": "string",
|
|
8916
|
+
"enum": [
|
|
8917
|
+
"default",
|
|
8918
|
+
"warn",
|
|
8919
|
+
"fail"
|
|
8920
|
+
],
|
|
8921
|
+
"description": "What happens when the key is not in `entries`.\n`default` substitutes `default` silently; `warn` substitutes it and emits a\n`LOOKUP_UNMAPPED` warning so the gap is visible without stopping delivery;\n`fail` aborts the delivery terminally.\nDefaults to `default` when a `default` is set, and to `warn` when it is not.\n"
|
|
8922
|
+
}
|
|
8923
|
+
}
|
|
8924
|
+
},
|
|
8696
8925
|
"OutboundStatusResponse": {
|
|
8697
8926
|
"type": "object",
|
|
8698
8927
|
"required": [
|
|
@@ -8763,6 +8992,60 @@
|
|
|
8763
8992
|
},
|
|
8764
8993
|
"poll": {
|
|
8765
8994
|
"$ref": "#/components/schemas/OutboundPollStatus"
|
|
8995
|
+
},
|
|
8996
|
+
"file_proxy": {
|
|
8997
|
+
"type": "array",
|
|
8998
|
+
"items": {
|
|
8999
|
+
"$ref": "#/components/schemas/OutboundFileProxyTargetStatus"
|
|
9000
|
+
},
|
|
9001
|
+
"description": "One entry per file_proxy mapping on this use case. Present only on use cases with a\nfile_proxy delivery mapping.\n"
|
|
9002
|
+
}
|
|
9003
|
+
}
|
|
9004
|
+
},
|
|
9005
|
+
"OutboundFileProxyTargetStatus": {
|
|
9006
|
+
"type": "object",
|
|
9007
|
+
"description": "Resolution state of one file_proxy mapping's referenced upload use case.\n\nBecause the transport lives on a separate use case, edits to the endpoint or credentials\ndo not appear in THIS use case's history. `target_updated_at` is the hook that lets an\noperator notice a target changed underneath a delivery that started failing.\n",
|
|
9008
|
+
"required": [
|
|
9009
|
+
"mapping_id",
|
|
9010
|
+
"use_case_slug",
|
|
9011
|
+
"resolved"
|
|
9012
|
+
],
|
|
9013
|
+
"properties": {
|
|
9014
|
+
"mapping_id": {
|
|
9015
|
+
"type": "string",
|
|
9016
|
+
"description": "The mapping holding this file_proxy delivery"
|
|
9017
|
+
},
|
|
9018
|
+
"use_case_slug": {
|
|
9019
|
+
"type": "string",
|
|
9020
|
+
"description": "Slug of the referenced file_proxy use case"
|
|
9021
|
+
},
|
|
9022
|
+
"resolved": {
|
|
9023
|
+
"type": "boolean",
|
|
9024
|
+
"description": "Whether the slug currently resolves to an enabled `file_proxy` use case with\n`direction: upload` in this integration. References are resolved at delivery time,\nso `false` is a live warning rather than a save-time error.\n"
|
|
9025
|
+
},
|
|
9026
|
+
"target_use_case_id": {
|
|
9027
|
+
"type": "string",
|
|
9028
|
+
"format": "uuid",
|
|
9029
|
+
"description": "Id of the referenced use case — absent when unresolved"
|
|
9030
|
+
},
|
|
9031
|
+
"target_enabled": {
|
|
9032
|
+
"type": "boolean",
|
|
9033
|
+
"description": "Whether the referenced use case is enabled — absent when unresolved"
|
|
9034
|
+
},
|
|
9035
|
+
"target_updated_at": {
|
|
9036
|
+
"type": "string",
|
|
9037
|
+
"format": "date-time",
|
|
9038
|
+
"description": "When the referenced use case was last modified — absent when unresolved. Surfaced\nbecause a change here is invisible in this use case's own history diff.\n"
|
|
9039
|
+
},
|
|
9040
|
+
"unresolved_reason": {
|
|
9041
|
+
"type": "string",
|
|
9042
|
+
"enum": [
|
|
9043
|
+
"not_found",
|
|
9044
|
+
"wrong_type",
|
|
9045
|
+
"wrong_direction",
|
|
9046
|
+
"disabled"
|
|
9047
|
+
],
|
|
9048
|
+
"description": "Why the reference did not resolve — absent when `resolved` is true"
|
|
8766
9049
|
}
|
|
8767
9050
|
}
|
|
8768
9051
|
},
|
package/dist/bin/epilot.js
CHANGED
|
@@ -11,7 +11,7 @@ import { defineCommand } from "citty";
|
|
|
11
11
|
var main = defineCommand({
|
|
12
12
|
meta: {
|
|
13
13
|
name: "epilot",
|
|
14
|
-
version: "0.1.
|
|
14
|
+
version: "0.1.104",
|
|
15
15
|
description: "CLI for epilot APIs"
|
|
16
16
|
},
|
|
17
17
|
args: {
|
|
@@ -31,7 +31,7 @@ var main = defineCommand({
|
|
|
31
31
|
profile: () => import("../profile-OZJL5ZPT.js").then((m) => m.default),
|
|
32
32
|
config: () => import("../config-DGZIMLZK.js").then((m) => m.default),
|
|
33
33
|
completion: () => import("../completion-RUUFYBPO.js").then((m) => m.default),
|
|
34
|
-
upgrade: () => import("../upgrade-
|
|
34
|
+
upgrade: () => import("../upgrade-URUPXKJR.js").then((m) => m.default),
|
|
35
35
|
"access-token": () => import("../access-token-WWE6BDJH.js").then((m) => m.default),
|
|
36
36
|
address: () => import("../address-EH3C4CVB.js").then((m) => m.default),
|
|
37
37
|
"address-suggestions": () => import("../address-suggestions-RRSLOBFW.js").then((m) => m.default),
|
|
@@ -134,7 +134,7 @@ process.stderr.on("error", (err) => {
|
|
|
134
134
|
if (err.code === "EPIPE") process.exit(0);
|
|
135
135
|
throw err;
|
|
136
136
|
});
|
|
137
|
-
var VERSION = true ? "0.1.
|
|
137
|
+
var VERSION = true ? "0.1.104" : (await null).default.version;
|
|
138
138
|
var reorderedArgv = hoistFlagsAfterSubcommand(process.argv.slice(2));
|
|
139
139
|
process.argv = [process.argv[0], process.argv[1], ...reorderedArgv];
|
|
140
140
|
var args = process.argv.slice(2);
|
|
@@ -72,7 +72,7 @@ ${GREEN}${BOLD}Upgraded to @epilot/cli@${latest}${RESET}
|
|
|
72
72
|
}
|
|
73
73
|
});
|
|
74
74
|
var getCurrentVersion = () => {
|
|
75
|
-
if (true) return "0.1.
|
|
75
|
+
if (true) return "0.1.104";
|
|
76
76
|
try {
|
|
77
77
|
const output = execSync("npm ls -g @epilot/cli --depth=0 --json 2>/dev/null", {
|
|
78
78
|
encoding: "utf-8",
|