@epistola.app/valtimo-plugin 0.6.0 → 0.8.0

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.
Files changed (33) hide show
  1. package/fesm2022/epistola.app-valtimo-plugin.mjs +1514 -456
  2. package/fesm2022/epistola.app-valtimo-plugin.mjs.map +1 -1
  3. package/lib/assets/epistola-logo.d.ts +1 -1
  4. package/lib/components/check-job-status-configuration/check-job-status-configuration.component.d.ts +4 -1
  5. package/lib/components/download-document-configuration/download-document-configuration.component.d.ts +8 -1
  6. package/lib/components/epistola-admin-page/epistola-admin-page.component.d.ts +17 -1
  7. package/lib/components/epistola-document/epistola-document.component.d.ts +65 -0
  8. package/lib/components/{epistola-download/epistola-download.formio.d.ts → epistola-document/epistola-document.formio.d.ts} +2 -2
  9. package/lib/components/epistola-document-preview/epistola-document-preview.component.d.ts +29 -18
  10. package/lib/components/epistola-document-preview/preview-utils.d.ts +18 -0
  11. package/lib/components/epistola-retry-form/epistola-retry-form.component.d.ts +3 -7
  12. package/lib/components/generate-document-configuration/generate-document-configuration.component.d.ts +20 -1
  13. package/lib/components/override-builder/override-builder.component.d.ts +42 -0
  14. package/lib/components/override-builder/override-builder.formio.d.ts +4 -0
  15. package/lib/components/process-link-selector/process-link-selector.component.d.ts +31 -0
  16. package/lib/components/process-link-selector/process-link-selector.formio.d.ts +4 -0
  17. package/lib/epistola-enabled.guard.d.ts +2 -0
  18. package/lib/epistola-runtime-config.d.ts +28 -0
  19. package/lib/epistola.module.d.ts +4 -5
  20. package/lib/models/admin.d.ts +28 -0
  21. package/lib/models/config.d.ts +27 -12
  22. package/lib/services/epistola-admin.service.d.ts +14 -1
  23. package/lib/services/epistola-plugin.service.d.ts +51 -7
  24. package/lib/services/epistola-task-context.interceptor.d.ts +29 -0
  25. package/lib/services/epistola-task-context.matcher.d.ts +19 -0
  26. package/lib/services/epistola-task-context.service.d.ts +26 -0
  27. package/lib/services/index.d.ts +2 -0
  28. package/package.json +4 -2
  29. package/public_api.d.ts +7 -4
  30. package/sbom.json +1 -0
  31. package/lib/components/epistola-download/epistola-download.component.d.ts +0 -24
  32. package/lib/components/epistola-preview-button/epistola-preview-button.component.d.ts +0 -35
  33. package/lib/components/epistola-preview-button/epistola-preview-button.formio.d.ts +0 -4
@@ -1 +1 @@
1
- export declare const EPISTOLA_PLUGIN_LOGO_BASE64 = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iIzMzNjZjYyI+PHBhdGggZD0iTTE0IDJINmMtMS4xIDAtMiAuOS0yIDJ2MTZjMCAxLjEuOSAyIDIgMmgxMmMxLjEgMCAyLS45IDItMlY4bC02LTZ6bTQgMThINlY0aDd2NWg1djExeiIvPjxwYXRoIGQ9Ik04IDEyaDh2Mkg4em0wIDRoOHYtMkg4em0wLThWNmg0djJ6Ii8+PC9zdmc+";
1
+ export declare const EPISTOLA_PLUGIN_LOGO_BASE64 = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAgMTIwIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjEyMCI+CiAgPCEtLSBTdGFjayBiYXNlIC0tPgogIDxyZWN0IHg9IjM2IiB5PSIxNiIgd2lkdGg9IjU0IiBoZWlnaHQ9IjcwIiByeD0iMyIgZmlsbD0iI2U2YzJiMCIgc3Ryb2tlPSIjNGYyZjJiIiBzdHJva2Utd2lkdGg9IjIiIHRyYW5zZm9ybT0icm90YXRlKDUgNjMgNTEpIi8+CiAgPHJlY3QgeD0iMzIiIHk9IjIyIiB3aWR0aD0iNTQiIGhlaWdodD0iNzAiIHJ4PSIzIiBmaWxsPSIjZjBkOGM4IiBzdHJva2U9IiM0ZjJmMmIiIHN0cm9rZS13aWR0aD0iMiIvPgogIDxyZWN0IHg9IjI4IiB5PSIyOCIgd2lkdGg9IjU0IiBoZWlnaHQ9IjcwIiByeD0iMyIgZmlsbD0iI2Y1ZWJlMyIgc3Ryb2tlPSIjNGYyZjJiIiBzdHJva2Utd2lkdGg9IjIuNSIvPgogIDxsaW5lIHgxPSIzOCIgeTE9IjQ0IiB4Mj0iNzIiIHkyPSI0NCIgc3Ryb2tlPSIjYzRhODgyIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxsaW5lIHgxPSIzOCIgeTE9IjU0IiB4Mj0iNzIiIHkyPSI1NCIgc3Ryb2tlPSIjYzRhODgyIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxsaW5lIHgxPSIzOCIgeTE9IjY0IiB4Mj0iNTgiIHkyPSI2NCIgc3Ryb2tlPSIjYzRhODgyIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDwhLS0gV2F4IHNlYWwgd2l0aCBjaGVja21hcmsgLS0+CiAgPGNpcmNsZSBjeD0iNTUiIGN5PSI4NCIgcj0iMTUiIGZpbGw9IiNiODVjM2MiIHN0cm9rZT0iIzRmMmYyYiIgc3Ryb2tlLXdpZHRoPSIyIi8+CiAgPGNpcmNsZSBjeD0iNTUiIGN5PSI4NCIgcj0iMTAuNSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZDQ4MzZhIiBzdHJva2Utd2lkdGg9IjEiLz4KICA8cG9seWxpbmUgcG9pbnRzPSI0OSw4NCA1Myw4OSA2Miw3OCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNGYyZjJiIiBzdHJva2Utd2lkdGg9IjIuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo=";
@@ -1,7 +1,7 @@
1
1
  import { EventEmitter, OnDestroy, OnInit } from '@angular/core';
2
2
  import { FunctionConfigurationComponent } from '@valtimo/plugin';
3
3
  import { FormOutput } from '@valtimo/components';
4
- import { Observable } from 'rxjs';
4
+ import { BehaviorSubject, Observable } from 'rxjs';
5
5
  import { CheckJobStatusConfig } from '../../models';
6
6
  import * as i0 from "@angular/core";
7
7
  export declare class CheckJobStatusConfigurationComponent implements FunctionConfigurationComponent, OnInit, OnDestroy {
@@ -14,6 +14,9 @@ export declare class CheckJobStatusConfigurationComponent implements FunctionCon
14
14
  private saveSubscription;
15
15
  private readonly formValue$;
16
16
  private readonly valid$;
17
+ /** Resolved synchronously before the v-form renders — see download-document-configuration for the why. */
18
+ resolvedPrefill: Partial<CheckJobStatusConfig>;
19
+ readonly prefillResolved$: BehaviorSubject<boolean>;
17
20
  safeDisabled$: Observable<boolean>;
18
21
  ngOnInit(): void;
19
22
  ngOnDestroy(): void;
@@ -1,7 +1,7 @@
1
1
  import { EventEmitter, OnDestroy, OnInit } from '@angular/core';
2
2
  import { FunctionConfigurationComponent } from '@valtimo/plugin';
3
3
  import { FormOutput } from '@valtimo/components';
4
- import { Observable } from 'rxjs';
4
+ import { BehaviorSubject, Observable } from 'rxjs';
5
5
  import { DownloadDocumentConfig } from '../../models';
6
6
  import * as i0 from "@angular/core";
7
7
  export declare class DownloadDocumentConfigurationComponent implements FunctionConfigurationComponent, OnInit, OnDestroy {
@@ -14,6 +14,13 @@ export declare class DownloadDocumentConfigurationComponent implements FunctionC
14
14
  private saveSubscription;
15
15
  private readonly formValue$;
16
16
  private readonly valid$;
17
+ /**
18
+ * Resolved prefill — populated synchronously before the v-form renders. Avoids the
19
+ * v-input `[defaultValue]` async-binding race that otherwise drops one of the
20
+ * fields when prefill arrives after mount.
21
+ */
22
+ resolvedPrefill: Partial<DownloadDocumentConfig>;
23
+ readonly prefillResolved$: BehaviorSubject<boolean>;
17
24
  safeDisabled$: Observable<boolean>;
18
25
  ngOnInit(): void;
19
26
  ngOnDestroy(): void;
@@ -1,7 +1,7 @@
1
1
  import { OnInit } from '@angular/core';
2
2
  import { ActivatedRoute, Router } from '@angular/router';
3
3
  import { EpistolaAdminService } from '../../services/epistola-admin.service';
4
- import { PendingJob, PluginUsageEntry } from '../../models';
4
+ import { BpmnValidationViolation, PendingJob, PluginUsageEntry } from '../../models';
5
5
  import * as i0 from "@angular/core";
6
6
  /**
7
7
  * Combined view model for a single plugin configuration card.
@@ -26,8 +26,16 @@ export declare class EpistolaAdminPageComponent implements OnInit {
26
26
  cards: ConfigurationCard[];
27
27
  selectedCard: ConfigurationCard | null;
28
28
  activeTab: 'actions' | 'pending';
29
+ overviewTab: 'configurations' | 'validations';
29
30
  loading: boolean;
30
31
  pluginVersion: string | null;
32
+ validationViolations: BpmnValidationViolation[];
33
+ reconcilingExecutionIds: Set<string>;
34
+ reconcileFeedback: {
35
+ executionId: string;
36
+ type: 'success' | 'pending' | 'error';
37
+ message: string;
38
+ } | null;
31
39
  private connectionStatuses;
32
40
  private usageEntries;
33
41
  private pendingJobs;
@@ -40,8 +48,16 @@ export declare class EpistolaAdminPageComponent implements OnInit {
40
48
  selectConfiguration(card: ConfigurationCard): void;
41
49
  backToOverview(): void;
42
50
  setActiveTab(tab: 'actions' | 'pending'): void;
51
+ setOverviewTab(tab: 'configurations' | 'validations'): void;
43
52
  refresh(): void;
44
53
  exportProcessLink(entry: PluginUsageEntry): void;
54
+ /**
55
+ * Manually reconcile a single stuck catch event. Pulls the current Epistola job
56
+ * status and re-runs message correlation if the job is in a terminal state.
57
+ * Refreshes the Pending list on success so the row drops out of the table.
58
+ */
59
+ reconcilePending(job: PendingJob): void;
60
+ isReconciling(job: PendingJob): boolean;
45
61
  private updateUrl;
46
62
  private loadData;
47
63
  private tryBuildCards;
@@ -0,0 +1,65 @@
1
+ import { ChangeDetectorRef, EventEmitter, OnDestroy, OnInit } from '@angular/core';
2
+ import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
3
+ import { FormioCustomComponent, FormIoStateService } from '@valtimo/components';
4
+ import { EpistolaPluginService, EpistolaTaskContextService } from '../../services';
5
+ import * as i0 from "@angular/core";
6
+ export type EpistolaDocumentDisplay = 'inline' | 'button' | 'both';
7
+ /**
8
+ * Unified Formio component for the after-generation Epistola PDF UX. Reads
9
+ * the PDF id and tenant id from named process variables on the caller's
10
+ * task via the {@code /documents/download} endpoint.
11
+ *
12
+ * <p>Three presentations, all backed by the same backend call:
13
+ * <ul>
14
+ * <li>{@code display="inline"} — render the PDF inline in a panel.</li>
15
+ * <li>{@code display="button"} — show a click-to-save download button only.</li>
16
+ * <li>{@code display="both"} (default) — inline panel with a download icon
17
+ * in the header.</li>
18
+ * </ul>
19
+ *
20
+ * <p>For the dry-run / what-would-be-generated UX use
21
+ * {@code epistola-document-preview} instead.
22
+ */
23
+ export declare class EpistolaDocumentComponent implements FormioCustomComponent<unknown>, OnInit, OnDestroy {
24
+ private readonly epistolaPluginService;
25
+ private readonly sanitizer;
26
+ private readonly formIoStateService;
27
+ private readonly taskContext;
28
+ private readonly cdr;
29
+ value: unknown;
30
+ valueChange: EventEmitter<unknown>;
31
+ disabled: boolean;
32
+ label: string;
33
+ /** How to present the document. `both` (default) shows an inline panel with a download icon. */
34
+ display: EpistolaDocumentDisplay;
35
+ /**
36
+ * Process-variable name holding the Epistola result. Default: `epistolaResult`.
37
+ *
38
+ * Type-tolerant on the backend: if the named variable holds a rich result object
39
+ * (`Map<String, Object>` written by `generate-document` and updated by the result
40
+ * collector), the backend digs out the `documentId` key. If it holds a plain
41
+ * String (custom flow that wrote a bare id), the backend uses it as-is.
42
+ */
43
+ documentVariable: string;
44
+ /** Process-variable name holding the Epistola tenant id. Default: `epistolaTenantId`. */
45
+ tenantIdVariable: string;
46
+ /** Filename used for the download disposition. */
47
+ filename: string;
48
+ loading: boolean;
49
+ downloading: boolean;
50
+ error: string | null;
51
+ previewUrl: SafeResourceUrl | null;
52
+ private currentBlobUrl;
53
+ private subscription?;
54
+ get designMode(): boolean;
55
+ constructor(epistolaPluginService: EpistolaPluginService, sanitizer: DomSanitizer, formIoStateService: FormIoStateService, taskContext: EpistolaTaskContextService, cdr: ChangeDetectorRef);
56
+ ngOnInit(): void;
57
+ ngOnDestroy(): void;
58
+ refresh(): void;
59
+ download(): void;
60
+ private loadInline;
61
+ private buildRequest;
62
+ private revokeBlobUrl;
63
+ static ɵfac: i0.ɵɵFactoryDeclaration<EpistolaDocumentComponent, never>;
64
+ static ɵcmp: i0.ɵɵComponentDeclaration<EpistolaDocumentComponent, "epistola-document-component", never, { "value": { "alias": "value"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "label": { "alias": "label"; "required": false; }; "display": { "alias": "display"; "required": false; }; "documentVariable": { "alias": "documentVariable"; "required": false; }; "tenantIdVariable": { "alias": "tenantIdVariable"; "required": false; }; "filename": { "alias": "filename"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
65
+ }
@@ -1,4 +1,4 @@
1
1
  import { Injector } from '@angular/core';
2
2
  import { FormioCustomComponentInfo } from '@valtimo/components';
3
- export declare const EPISTOLA_DOWNLOAD_OPTIONS: FormioCustomComponentInfo;
4
- export declare function registerEpistolaDownloadComponent(injector: Injector): void;
3
+ export declare const EPISTOLA_DOCUMENT_OPTIONS: FormioCustomComponentInfo;
4
+ export declare function registerEpistolaDocumentComponent(injector: Injector): void;
@@ -1,41 +1,52 @@
1
1
  import { ChangeDetectorRef, EventEmitter, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
2
- import { HttpClient } from '@angular/common/http';
3
2
  import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
4
3
  import { FormioCustomComponent, FormIoStateService } from '@valtimo/components';
5
- import { ConfigService } from '@valtimo/shared';
6
- import { PreviewSource } from '../../models';
7
- import { EpistolaPluginService } from '../../services';
4
+ import { EpistolaPluginService, EpistolaTaskContextService } from '../../services';
8
5
  import * as i0 from "@angular/core";
9
- export declare class EpistolaDocumentPreviewComponent implements FormioCustomComponent<null>, OnChanges, OnDestroy {
6
+ export declare class EpistolaDocumentPreviewComponent implements FormioCustomComponent<Record<string, any> | null>, OnChanges, OnDestroy {
10
7
  private readonly epistolaPluginService;
11
- private readonly http;
12
8
  private readonly sanitizer;
13
- private readonly configService;
14
9
  private readonly formIoStateService;
15
10
  private readonly cdr;
16
- value: null;
17
- valueChange: EventEmitter<null>;
11
+ private readonly taskContext;
12
+ value: Record<string, any> | null;
13
+ valueChange: EventEmitter<Record<string, any>>;
18
14
  disabled: boolean;
19
15
  label: string;
20
- sources: PreviewSource[];
21
- selectedIndex: number;
22
- discovering: boolean;
16
+ processDefinitionKey?: string;
17
+ sourceActivityId?: string;
18
+ overrideMapping?: Record<string, any>;
23
19
  loading: boolean;
24
20
  error: string | null;
25
21
  previewUrl: SafeResourceUrl | null;
22
+ designMode: boolean;
26
23
  private initialized;
27
24
  private currentBlobUrl;
28
- private discoverSubscription?;
29
25
  private previewSubscription?;
30
- private readonly apiEndpoint;
31
- constructor(epistolaPluginService: EpistolaPluginService, http: HttpClient, sanitizer: DomSanitizer, configService: ConfigService, formIoStateService: FormIoStateService, cdr: ChangeDetectorRef);
26
+ constructor(epistolaPluginService: EpistolaPluginService, sanitizer: DomSanitizer, formIoStateService: FormIoStateService, cdr: ChangeDetectorRef, taskContext: EpistolaTaskContextService);
27
+ /**
28
+ * Resolve the active task id from {@link EpistolaTaskContextService}, populated
29
+ * by {@code EpistolaTaskContextInterceptor} on the canonical Valtimo task-open
30
+ * call. Returns null when used outside a task context (e.g. Formio builder).
31
+ */
32
+ private get currentTaskId();
33
+ get overrideMappingScopes(): string[];
34
+ overrideMappingEntries(scope: string): {
35
+ path: string;
36
+ field: string;
37
+ }[];
32
38
  ngOnChanges(changes: SimpleChanges): void;
33
39
  ngOnDestroy(): void;
34
- onSourceChange(event: Event): void;
35
40
  refresh(): void;
36
- private discoverSources;
41
+ /**
42
+ * Preview using the explicitly configured process link + input overrides.
43
+ * Requires a runtime task context — the backend authorizes the request against
44
+ * the task's process instance and case document, so all three ids must match.
45
+ */
37
46
  private loadPreview;
47
+ private handlePreviewSuccess;
48
+ private handlePreviewError;
38
49
  private revokeBlobUrl;
39
50
  static ɵfac: i0.ɵɵFactoryDeclaration<EpistolaDocumentPreviewComponent, never>;
40
- static ɵcmp: i0.ɵɵComponentDeclaration<EpistolaDocumentPreviewComponent, "epistola-document-preview-component", never, { "value": { "alias": "value"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "label": { "alias": "label"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
51
+ static ɵcmp: i0.ɵɵComponentDeclaration<EpistolaDocumentPreviewComponent, "epistola-document-preview-component", never, { "value": { "alias": "value"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "label": { "alias": "label"; "required": false; }; "processDefinitionKey": { "alias": "processDefinitionKey"; "required": false; }; "sourceActivityId": { "alias": "sourceActivityId"; "required": false; }; "overrideMapping": { "alias": "overrideMapping"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
41
52
  }
@@ -0,0 +1,18 @@
1
+ import { OverrideMapping } from '../override-builder/override-builder.component';
2
+ export declare const FORM_REF_PREFIX = "form:";
3
+ /**
4
+ * Detect if a string value is a JSONata expression (vs a plain literal).
5
+ * Checks for characters that indicate JSONata operators: $, &, (, {, ?, [
6
+ */
7
+ export declare function isExpression(value: string): boolean;
8
+ /**
9
+ * Expand dot-notation keys into nested objects.
10
+ * e.g. { "beslissing.tekst": "value" } -> { beslissing: { tekst: "value" } }
11
+ */
12
+ export declare function expandDotNotation(flat: Record<string, any>): Record<string, any>;
13
+ /**
14
+ * Given an override mapping (scope -> { inputPath -> "form:<componentKey>" })
15
+ * and form data, produce the inputOverrides object for the backend.
16
+ * The "form:" prefix identifies form field references; the remainder is the Formio component key.
17
+ */
18
+ export declare function computeInputOverrides(mapping: OverrideMapping, formData: Record<string, any>): Record<string, any>;
@@ -1,17 +1,14 @@
1
1
  import { ChangeDetectorRef, EventEmitter, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
2
- import { HttpClient } from '@angular/common/http';
3
2
  import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
4
3
  import { FormioCustomComponent, FormIoStateService } from '@valtimo/components';
5
- import { ConfigService } from '@valtimo/shared';
6
- import { EpistolaPluginService } from '../../services';
4
+ import { EpistolaPluginService, EpistolaTaskContextService } from '../../services';
7
5
  import * as i0 from "@angular/core";
8
6
  export declare class EpistolaRetryFormComponent implements FormioCustomComponent<string>, OnChanges, OnDestroy {
9
7
  private readonly epistolaPluginService;
10
8
  private readonly formIoStateService;
11
9
  private readonly cdr;
12
- private readonly http;
13
10
  private readonly sanitizer;
14
- private readonly configService;
11
+ private readonly taskContext;
15
12
  value: string;
16
13
  valueChange: EventEmitter<string>;
17
14
  disabled: boolean;
@@ -32,9 +29,8 @@ export declare class EpistolaRetryFormComponent implements FormioCustomComponent
32
29
  private currentBlobUrl;
33
30
  private resolvedSourceActivityId?;
34
31
  private processDefinitionKey?;
35
- private readonly apiEndpoint;
36
32
  formOptions: any;
37
- constructor(epistolaPluginService: EpistolaPluginService, formIoStateService: FormIoStateService, cdr: ChangeDetectorRef, http: HttpClient, sanitizer: DomSanitizer, configService: ConfigService);
33
+ constructor(epistolaPluginService: EpistolaPluginService, formIoStateService: FormIoStateService, cdr: ChangeDetectorRef, sanitizer: DomSanitizer, taskContext: EpistolaTaskContextService);
38
34
  ngOnChanges(changes: SimpleChanges): void;
39
35
  ngOnDestroy(): void;
40
36
  togglePreview(): void;
@@ -4,7 +4,7 @@ import { FormOutput, SelectItem } from '@valtimo/components';
4
4
  import { CaseManagementParams, ManagementContext } from '@valtimo/shared';
5
5
  import { ProcessLinkStateService } from '@valtimo/process-link';
6
6
  import { BehaviorSubject, Observable } from 'rxjs';
7
- import { AsyncResource, ExpressionFunctionInfo, GenerateDocumentConfig, TemplateField, VariableSuggestions } from '../../models';
7
+ import { AsyncResource, ExpressionFunctionInfo, GenerateDocumentConfig, JsonataFieldError, TemplateField, VariableSuggestions } from '../../models';
8
8
  import { EpistolaPluginService } from '../../services';
9
9
  import * as i0 from "@angular/core";
10
10
  export type VariantSelectionMode = 'explicit' | 'attributes';
@@ -35,11 +35,16 @@ export declare class GenerateDocumentConfigurationComponent implements FunctionC
35
35
  readonly selectedTemplateId$: BehaviorSubject<string>;
36
36
  readonly selectedVariantId$: BehaviorSubject<string>;
37
37
  variantSelectionMode: VariantSelectionMode;
38
+ variantIdExpressionMode: boolean;
39
+ variantIdExpression: string;
40
+ filenameExpressionMode: boolean;
41
+ filenameExpression: string;
38
42
  variantAttributeEntries: {
39
43
  key: string;
40
44
  value: string;
41
45
  required: boolean;
42
46
  _customKey?: boolean;
47
+ _expressionMode?: boolean;
43
48
  }[];
44
49
  availableAttributeKeys: string[];
45
50
  caseDefinitionKey: string | null;
@@ -51,6 +56,7 @@ export declare class GenerateDocumentConfigurationComponent implements FunctionC
51
56
  total: number;
52
57
  };
53
58
  prefillDataMapping: Record<string, any>;
59
+ validationErrors$: BehaviorSubject<JsonataFieldError[]>;
54
60
  private readonly destroy$;
55
61
  private saveSubscription;
56
62
  private readonly formValue$;
@@ -71,6 +77,8 @@ export declare class GenerateDocumentConfigurationComponent implements FunctionC
71
77
  addAttributeEntry(): void;
72
78
  removeAttributeEntry(index: number): void;
73
79
  onAttributeEntryChange(): void;
80
+ onVariantIdExpressionChange(): void;
81
+ onFilenameExpressionChange(): void;
74
82
  onKeySelected(entry: {
75
83
  key: string;
76
84
  value: string;
@@ -109,6 +117,17 @@ export declare class GenerateDocumentConfigurationComponent implements FunctionC
109
117
  private loadVariableSuggestions;
110
118
  private handleValid;
111
119
  private openSaveSubscription;
120
+ /**
121
+ * Build a JSONata validation request from the config and call the backend.
122
+ * Only fields that are JSONata expressions get validated:
123
+ * - dataMapping is always JSONata
124
+ * - filename / variantId only when their `fx` toggle is on
125
+ * - variant attribute values only when isExpression() reports true
126
+ * On invalid response, surface errors and abort the emit.
127
+ * If the validator endpoint itself fails (network/server), proceed with the
128
+ * emit — the validation is a quality-of-life check, not a hard gate.
129
+ */
130
+ private validateAndEmit;
112
131
  static ɵfac: i0.ɵɵFactoryDeclaration<GenerateDocumentConfigurationComponent, never>;
113
132
  static ɵcmp: i0.ɵɵComponentDeclaration<GenerateDocumentConfigurationComponent, "epistola-generate-document-configuration", never, { "save$": { "alias": "save$"; "required": false; }; "disabled$": { "alias": "disabled$"; "required": false; }; "pluginId": { "alias": "pluginId"; "required": false; }; "prefillConfiguration$": { "alias": "prefillConfiguration$"; "required": false; }; "selectedPluginConfigurationData$": { "alias": "selectedPluginConfigurationData$"; "required": false; }; "context$": { "alias": "context$"; "required": false; }; }, { "valid": "valid"; "configuration": "configuration"; }, never, never, true, never>;
114
133
  }
@@ -0,0 +1,42 @@
1
+ import { ChangeDetectorRef, EventEmitter } from '@angular/core';
2
+ import { FormioCustomComponent } from '@valtimo/components';
3
+ import * as i0 from "@angular/core";
4
+ interface OverrideRow {
5
+ scope: 'doc' | 'pv';
6
+ inputPath: string;
7
+ formFieldKey: string;
8
+ }
9
+ export interface FormFieldOption {
10
+ key: string;
11
+ label: string;
12
+ }
13
+ /**
14
+ * Override mapping format: scope → { inputPath → "form:<componentKey>" }
15
+ * The "form:" prefix identifies this as a reference to a Formio component.
16
+ */
17
+ export type OverrideMapping = Record<string, Record<string, string>>;
18
+ export declare class EpistolaOverrideBuilderComponent implements FormioCustomComponent<OverrideMapping | null> {
19
+ private readonly cdr;
20
+ value: OverrideMapping | null;
21
+ valueChange: EventEmitter<OverrideMapping>;
22
+ disabled: boolean;
23
+ label: string;
24
+ availableFields: FormFieldOption[];
25
+ rows: OverrideRow[];
26
+ advancedMode: boolean;
27
+ jsonText: string;
28
+ jsonError: string | null;
29
+ private initialized;
30
+ constructor(cdr: ChangeDetectorRef);
31
+ ngOnChanges(): void;
32
+ toggleMode(): void;
33
+ addRow(): void;
34
+ removeRow(index: number): void;
35
+ emitChange(): void;
36
+ onJsonChange(text: string): void;
37
+ private rowsToMapping;
38
+ private mappingToRows;
39
+ static ɵfac: i0.ɵɵFactoryDeclaration<EpistolaOverrideBuilderComponent, never>;
40
+ static ɵcmp: i0.ɵɵComponentDeclaration<EpistolaOverrideBuilderComponent, "epistola-override-builder-component", never, { "value": { "alias": "value"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "label": { "alias": "label"; "required": false; }; "availableFields": { "alias": "availableFields"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
41
+ }
42
+ export {};
@@ -0,0 +1,4 @@
1
+ import { Injector } from '@angular/core';
2
+ import { FormioCustomComponentInfo } from '@valtimo/components';
3
+ export declare const EPISTOLA_OVERRIDE_BUILDER_OPTIONS: FormioCustomComponentInfo;
4
+ export declare function registerEpistolaOverrideBuilderComponent(injector: Injector): void;
@@ -0,0 +1,31 @@
1
+ import { ChangeDetectorRef, EventEmitter, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
2
+ import { FormioCustomComponent } from '@valtimo/components';
3
+ import { EpistolaAdminService } from '../../services';
4
+ import { PluginUsageEntry } from '../../models';
5
+ import * as i0 from "@angular/core";
6
+ export interface ProcessLinkSelection {
7
+ processDefinitionKey: string;
8
+ sourceActivityId: string;
9
+ }
10
+ export declare class EpistolaProcessLinkSelectorComponent implements FormioCustomComponent<ProcessLinkSelection | null>, OnChanges, OnDestroy {
11
+ private readonly adminService;
12
+ private readonly cdr;
13
+ value: ProcessLinkSelection | null;
14
+ valueChange: EventEmitter<ProcessLinkSelection>;
15
+ disabled: boolean;
16
+ label: string;
17
+ filteredEntries: PluginUsageEntry[];
18
+ selectedKey: string;
19
+ loading: boolean;
20
+ error: string | null;
21
+ private initialized;
22
+ private loadSubscription?;
23
+ constructor(adminService: EpistolaAdminService, cdr: ChangeDetectorRef);
24
+ ngOnChanges(changes: SimpleChanges): void;
25
+ ngOnDestroy(): void;
26
+ onSelect(key: string): void;
27
+ entryKey(entry: PluginUsageEntry): string;
28
+ private loadEntries;
29
+ static ɵfac: i0.ɵɵFactoryDeclaration<EpistolaProcessLinkSelectorComponent, never>;
30
+ static ɵcmp: i0.ɵɵComponentDeclaration<EpistolaProcessLinkSelectorComponent, "epistola-process-link-selector-component", never, { "value": { "alias": "value"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "label": { "alias": "label"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
31
+ }
@@ -0,0 +1,4 @@
1
+ import { Injector } from '@angular/core';
2
+ import { FormioCustomComponentInfo } from '@valtimo/components';
3
+ export declare const EPISTOLA_PROCESS_LINK_SELECTOR_OPTIONS: FormioCustomComponentInfo;
4
+ export declare function registerEpistolaProcessLinkSelectorComponent(injector: Injector): void;
@@ -0,0 +1,2 @@
1
+ import { CanActivateFn } from '@angular/router';
2
+ export declare const epistolaEnabledGuard: CanActivateFn;
@@ -0,0 +1,28 @@
1
+ export interface EpistolaRuntimeEnv {
2
+ epistolaEnabled?: boolean | string;
3
+ }
4
+ interface EpistolaRuntimeWindow {
5
+ env?: EpistolaRuntimeEnv;
6
+ }
7
+ declare global {
8
+ interface Window extends EpistolaRuntimeWindow {
9
+ }
10
+ }
11
+ /**
12
+ * Reads the runtime feature flag that decides whether the Epistola plugin
13
+ * surfaces (admin menu, /epistola route, plugin specification, Formio
14
+ * components) should activate in the host Valtimo app.
15
+ *
16
+ * The flag is sourced from `window['env']['epistolaEnabled']`, populated at
17
+ * container start by `envsubst` against `assets/config.template.js` (the
18
+ * standard Valtimo runtime-config pattern). Defaults to enabled — only the
19
+ * literal `false` or string `'false'` disables the plugin, matching the
20
+ * backend's `epistola.enabled` `matchIfMissing = true` semantics.
21
+ *
22
+ * Exposed as a runtime helper rather than evaluated directly in `@NgModule`
23
+ * decorator metadata because Angular's AOT compiler cannot statically resolve
24
+ * `window` accesses (NG1010). Read from runtime code such as specification
25
+ * property getters, route guards, or the environment initializer instead.
26
+ */
27
+ export declare function isEpistolaEnabled(): boolean;
28
+ export {};
@@ -9,14 +9,13 @@ import * as i6 from "./components/epistola-configuration/epistola-configuration.
9
9
  import * as i7 from "./components/generate-document-configuration/generate-document-configuration.component";
10
10
  import * as i8 from "./components/check-job-status-configuration/check-job-status-configuration.component";
11
11
  import * as i9 from "./components/download-document-configuration/download-document-configuration.component";
12
- import * as i10 from "./components/epistola-download/epistola-download.component";
12
+ import * as i10 from "./components/epistola-document/epistola-document.component";
13
13
  import * as i11 from "./components/epistola-retry-form/epistola-retry-form.component";
14
- import * as i12 from "./components/epistola-preview-button/epistola-preview-button.component";
15
- import * as i13 from "./components/epistola-document-preview/epistola-document-preview.component";
16
- import * as i14 from "./components/epistola-admin-page/epistola-admin-page.component";
14
+ import * as i12 from "./components/epistola-document-preview/epistola-document-preview.component";
15
+ import * as i13 from "./components/epistola-admin-page/epistola-admin-page.component";
17
16
  export declare class EpistolaPluginModule {
18
17
  static forRoot(): ModuleWithProviders<EpistolaPluginModule>;
19
18
  static ɵfac: i0.ɵɵFactoryDeclaration<EpistolaPluginModule, never>;
20
- static ɵmod: i0.ɵɵNgModuleDeclaration<EpistolaPluginModule, never, [typeof i1.CommonModule, typeof i2.HttpClientModule, typeof i3.PluginTranslatePipeModule, typeof i4.FormModule, typeof i4.InputModule, typeof i4.SelectModule, typeof i5.EpistolaAdminRoutingModule, typeof i6.EpistolaConfigurationComponent, typeof i7.GenerateDocumentConfigurationComponent, typeof i8.CheckJobStatusConfigurationComponent, typeof i9.DownloadDocumentConfigurationComponent, typeof i10.EpistolaDownloadComponent, typeof i11.EpistolaRetryFormComponent, typeof i12.EpistolaPreviewButtonComponent, typeof i13.EpistolaDocumentPreviewComponent, typeof i14.EpistolaAdminPageComponent], [typeof i6.EpistolaConfigurationComponent, typeof i7.GenerateDocumentConfigurationComponent, typeof i8.CheckJobStatusConfigurationComponent, typeof i9.DownloadDocumentConfigurationComponent, typeof i10.EpistolaDownloadComponent, typeof i11.EpistolaRetryFormComponent, typeof i12.EpistolaPreviewButtonComponent, typeof i13.EpistolaDocumentPreviewComponent, typeof i14.EpistolaAdminPageComponent]>;
19
+ static ɵmod: i0.ɵɵNgModuleDeclaration<EpistolaPluginModule, never, [typeof i1.CommonModule, typeof i2.HttpClientModule, typeof i3.PluginTranslatePipeModule, typeof i4.FormModule, typeof i4.InputModule, typeof i4.SelectModule, typeof i5.EpistolaAdminRoutingModule, typeof i6.EpistolaConfigurationComponent, typeof i7.GenerateDocumentConfigurationComponent, typeof i8.CheckJobStatusConfigurationComponent, typeof i9.DownloadDocumentConfigurationComponent, typeof i10.EpistolaDocumentComponent, typeof i11.EpistolaRetryFormComponent, typeof i12.EpistolaDocumentPreviewComponent, typeof i13.EpistolaAdminPageComponent], [typeof i6.EpistolaConfigurationComponent, typeof i7.GenerateDocumentConfigurationComponent, typeof i8.CheckJobStatusConfigurationComponent, typeof i9.DownloadDocumentConfigurationComponent, typeof i10.EpistolaDocumentComponent, typeof i11.EpistolaRetryFormComponent, typeof i12.EpistolaDocumentPreviewComponent, typeof i13.EpistolaAdminPageComponent]>;
21
20
  static ɵinj: i0.ɵɵInjectorDeclaration<EpistolaPluginModule>;
22
21
  }
@@ -47,3 +47,31 @@ export interface PluginUsageEntry {
47
47
  configurationTitle: string;
48
48
  problems: string[];
49
49
  }
50
+ /**
51
+ * Outcome of a manual reconcile attempt for a stuck Epistola catch event.
52
+ * `correlated=true` means the Epistola job is in a terminal state and message
53
+ * correlation ran (count = how many process instances received it). `false`
54
+ * means the job is still PENDING/IN_PROGRESS — the backend returns 409.
55
+ */
56
+ export interface ReconcileResult {
57
+ executionId: string;
58
+ processInstanceId: string;
59
+ tenantId: string;
60
+ requestId: string;
61
+ epistolaStatus: string;
62
+ correlatedCount: number | null;
63
+ correlated: boolean;
64
+ }
65
+ /**
66
+ * A BPMN race-safety violation reported by the backend's deployment validator.
67
+ * `code` is one of the constants in
68
+ * `app.epistola.valtimo.web.rest.dto.BpmnValidationViolation` (kept stable so
69
+ * the UI can render specific remediation copy per code).
70
+ */
71
+ export interface BpmnValidationViolation {
72
+ processDefinitionKey: string;
73
+ processDefinitionName: string;
74
+ activityId: string;
75
+ code: string;
76
+ message: string;
77
+ }
@@ -26,7 +26,7 @@ export interface VariantAttributeEntry {
26
26
  *
27
27
  * Variant selection supports two modes:
28
28
  * - Explicit: set variantId directly
29
- * - By attributes: set variantAttributes with key-value pairs (values can be value resolver expressions)
29
+ * - By attributes: set variantAttributes with key-value pairs (values can be JSONata expressions)
30
30
  */
31
31
  export interface GenerateDocumentConfig {
32
32
  catalogId: string;
@@ -55,19 +55,15 @@ export interface CheckJobStatusConfig {
55
55
  * Specifies which process variables to read from and write to.
56
56
  */
57
57
  export interface DownloadDocumentConfig {
58
- documentIdVariable: string;
58
+ /**
59
+ * Name of the process variable that holds the result. May be a plain
60
+ * String document id (legacy) or a `Map<String, Object>` rich result with
61
+ * a `documentId` key (canonical, written by `generate-document` and
62
+ * updated by the result collector). The action extracts the document id.
63
+ */
64
+ documentVariable: string;
59
65
  contentVariable: string;
60
66
  }
61
- /**
62
- * A previewable document source discovered from running process instances.
63
- */
64
- export interface PreviewSource {
65
- processDefinitionKey: string;
66
- activityId: string;
67
- templateId: string;
68
- templateName: string;
69
- processInstanceId: string;
70
- }
71
67
  export interface VariableSuggestions {
72
68
  doc: string[];
73
69
  pv: string[];
@@ -77,3 +73,22 @@ export interface EvaluationResult {
77
73
  result: Record<string, any> | null;
78
74
  error: string | null;
79
75
  }
76
+ /**
77
+ * Request body for the JSONata save-time validation endpoint.
78
+ * All fields are optional; null/blank values are skipped.
79
+ */
80
+ export interface ValidateJsonataRequest {
81
+ dataMapping?: string | null;
82
+ filename?: string | null;
83
+ variantId?: string | null;
84
+ variantAttributeValues?: Record<string, string> | null;
85
+ }
86
+ export interface JsonataFieldError {
87
+ field: string;
88
+ expression: string;
89
+ message: string;
90
+ }
91
+ export interface JsonataValidationResult {
92
+ valid: boolean;
93
+ errors: JsonataFieldError[];
94
+ }
@@ -1,7 +1,7 @@
1
1
  import { HttpClient } from '@angular/common/http';
2
2
  import { ConfigService } from '@valtimo/shared';
3
3
  import { Observable } from 'rxjs';
4
- import { ConnectionStatus, PendingJob, PluginUsageEntry, VersionInfo } from '../models';
4
+ import { BpmnValidationViolation, ConnectionStatus, PendingJob, PluginUsageEntry, ReconcileResult, VersionInfo } from '../models';
5
5
  import * as i0 from "@angular/core";
6
6
  /**
7
7
  * Service for Epistola plugin administrative operations.
@@ -28,6 +28,19 @@ export declare class EpistolaAdminService {
28
28
  * Get all process instances currently waiting for an Epistola document generation result.
29
29
  */
30
30
  getPendingJobs(): Observable<PendingJob[]>;
31
+ /**
32
+ * Manually reconcile a stuck Epistola catch event by querying Epistola for the
33
+ * job's current status and re-running message correlation. Returns 200 with
34
+ * `correlated=true` on success, 409 with `correlated=false` when the job is
35
+ * still in flight, or surfaces a validation error when the execution can't be
36
+ * recovered (no subscription, missing variable, unknown tenant).
37
+ */
38
+ reconcilePending(executionId: string): Observable<ReconcileResult>;
39
+ /**
40
+ * Get the latest BPMN race-safety validation violations across deployed
41
+ * process definitions. Empty list = healthy.
42
+ */
43
+ getValidationViolations(): Observable<BpmnValidationViolation[]>;
31
44
  /**
32
45
  * Export a single process link as a .process-link.json file.
33
46
  */