ngx-t-workflow-typings 3.2.0 → 3.2.2
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/dist/interfaces/ProcessStep/ProcessStep.interface.d.ts +107 -0
- package/dist/interfaces/ProcessStep/ProcessStep.interface.js +63 -0
- package/dist/interfaces/Requirements/StepReferenceRules.constant.js +25 -30
- package/dist/interfaces/Requirements/StepTypeRequirements.constant.js +136 -99
- package/package.json +3 -3
|
@@ -75,6 +75,100 @@ export interface BulkEmailConfig {
|
|
|
75
75
|
* Removed in the next major.
|
|
76
76
|
*/
|
|
77
77
|
export type LegacyBulkEmailConfig = BulkEmailConfig & Record<string, unknown>;
|
|
78
|
+
/**
|
|
79
|
+
* Who an email step sends to.
|
|
80
|
+
*
|
|
81
|
+
* The FIRST question the editor asks, because every other recipient control is
|
|
82
|
+
* gated on it. Replaces `BulkEmailType`, which asked about delivery mechanism —
|
|
83
|
+
* a question a workflow author has no basis to answer.
|
|
84
|
+
*/
|
|
85
|
+
export declare enum EmailRecipientMode {
|
|
86
|
+
/** One address, held in a form control on the document. */
|
|
87
|
+
FormControl = "formControl",
|
|
88
|
+
/** One address, resolved from the assignee of another step in this workflow. */
|
|
89
|
+
Member = "member",
|
|
90
|
+
/** One fixed address, typed into the step. */
|
|
91
|
+
Literal = "literal",
|
|
92
|
+
/** Every row of a list held on the document. The old `bulkEmail` behaviour. */
|
|
93
|
+
List = "list"
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Which template an email step starts from.
|
|
97
|
+
*
|
|
98
|
+
* Replaces `BulkEmailType.IServe` as the gate for the procurement-only fields:
|
|
99
|
+
* the author is picking a TEMPLATE, which they can reason about, instead of a
|
|
100
|
+
* delivery mode, which they cannot.
|
|
101
|
+
*/
|
|
102
|
+
export declare enum EmailTemplatePreset {
|
|
103
|
+
/** Author writes the whole body. */
|
|
104
|
+
Blank = "blank",
|
|
105
|
+
/** Procurement supplier bid invite — reveals the tender and closing-date keys. */
|
|
106
|
+
SupplierBidInvite = "supplierBidInvite"
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Serialised rich-text body, structurally typed.
|
|
110
|
+
*
|
|
111
|
+
* This is a Quill Delta op list, but the shape is declared locally rather than
|
|
112
|
+
* imported: `quill` is not a dependency of this package and must not become
|
|
113
|
+
* one. Stored as a plain object (never a `Delta` instance) so it round-trips
|
|
114
|
+
* through reactive-form state and the library's structural equality check —
|
|
115
|
+
* that check rejects values whose constructors differ.
|
|
116
|
+
*/
|
|
117
|
+
export interface EmailBodyDocument {
|
|
118
|
+
readonly ops: readonly unknown[];
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Configuration of an email (`bulkMail`) step.
|
|
122
|
+
*
|
|
123
|
+
* DELIBERATELY FLAT. Every member is one editor control and one `deepBind`
|
|
124
|
+
* path, so visibility gating, the required marker and error-to-control matching
|
|
125
|
+
* all address the same spelling with no mapping layer. Nesting would force the
|
|
126
|
+
* editor to bind `['email','recipients','listFormKey']` and buy nothing.
|
|
127
|
+
*
|
|
128
|
+
* Every member is optional because the editor writes them progressively; which
|
|
129
|
+
* ones are REQUIRED, and under which conditions, is stated by
|
|
130
|
+
* `STEP_TYPE_REQUIREMENTS[bulkMail]` rather than by the type.
|
|
131
|
+
*/
|
|
132
|
+
export interface EmailStepConfig {
|
|
133
|
+
/** Recipient strategy. Gates every other recipient field. */
|
|
134
|
+
mode?: EmailRecipientMode;
|
|
135
|
+
/** {@link EmailRecipientMode.FormControl}: the control holding the address. */
|
|
136
|
+
addressFormKey?: string;
|
|
137
|
+
/** {@link EmailRecipientMode.Member}: `stepId` whose assignee is mailed. */
|
|
138
|
+
memberStepId?: string;
|
|
139
|
+
/** {@link EmailRecipientMode.Literal}: the address itself. */
|
|
140
|
+
address?: string;
|
|
141
|
+
/** {@link EmailRecipientMode.List}: the control holding the recipient array. */
|
|
142
|
+
listFormKey?: string;
|
|
143
|
+
/** {@link EmailRecipientMode.List}: the property of each ROW holding the address. */
|
|
144
|
+
listAddressProperty?: string;
|
|
145
|
+
/** Template to start from. Gates the procurement-only keys below. */
|
|
146
|
+
preset?: EmailTemplatePreset;
|
|
147
|
+
/**
|
|
148
|
+
* Subject line: plain text that may embed `{{token}}` references.
|
|
149
|
+
*
|
|
150
|
+
* A TEMPLATE STRING, not a form-control pointer — that is the whole point of
|
|
151
|
+
* the change. `{{contractType}}` reads a form control, `{{$org.name}}` a
|
|
152
|
+
* server-resolved namespace, matching the `$`-picker convention already used
|
|
153
|
+
* by the payload and header template editors.
|
|
154
|
+
*/
|
|
155
|
+
subject?: string;
|
|
156
|
+
/** Editable rich-text source of the body. The source of record for re-editing. */
|
|
157
|
+
bodyDocument?: EmailBodyDocument;
|
|
158
|
+
/**
|
|
159
|
+
* The body compiled to sanitised, inline-styled, email-safe HTML with
|
|
160
|
+
* `<span data-token>` holes.
|
|
161
|
+
*
|
|
162
|
+
* DERIVED from {@link bodyDocument} at SAVE time, never at send time: a
|
|
163
|
+
* rich-text-editor upgrade must not be able to change the rendering of mail
|
|
164
|
+
* already configured. Produced by `quillToEmailHtml` in `ngx-t-workflows`.
|
|
165
|
+
*/
|
|
166
|
+
bodyHtml?: string;
|
|
167
|
+
/** {@link EmailTemplatePreset.SupplierBidInvite} only: control holding the tender number. */
|
|
168
|
+
tenderNumberFormKey?: string;
|
|
169
|
+
/** {@link EmailTemplatePreset.SupplierBidInvite} only: control holding the closing date. */
|
|
170
|
+
closingDateFormKey?: string;
|
|
171
|
+
}
|
|
78
172
|
export interface IProcessNodeBase extends ProcessStepTemplate {
|
|
79
173
|
stepId: string;
|
|
80
174
|
position: IPoint;
|
|
@@ -134,6 +228,19 @@ export type AdjudicationValue = AdjudicationConfig | string;
|
|
|
134
228
|
export interface ProcessStep extends IProcessNodeBase {
|
|
135
229
|
duration?: Duration;
|
|
136
230
|
reference?: string;
|
|
231
|
+
/**
|
|
232
|
+
* Configuration of an email step. THE field the editor writes.
|
|
233
|
+
*
|
|
234
|
+
* @see EmailStepConfig for why this replaces {@link ProcessStep.bulkEmail}
|
|
235
|
+
* rather than extending it.
|
|
236
|
+
*/
|
|
237
|
+
email?: EmailStepConfig;
|
|
238
|
+
/**
|
|
239
|
+
* @deprecated Superseded by {@link ProcessStep.email}. The builder no longer
|
|
240
|
+
* writes this field; it remains declared so existing readers compile and so a
|
|
241
|
+
* persisted document authored before the change still type-checks. The engine
|
|
242
|
+
* owns the read-time migration from these keys onto {@link EmailStepConfig}.
|
|
243
|
+
*/
|
|
137
244
|
bulkEmail?: BulkEmailConfig;
|
|
138
245
|
/**
|
|
139
246
|
* @deprecated LEGACY DUPLICATE of {@link BulkEmailConfig.documentValueWithEmail};
|
|
@@ -15,6 +15,69 @@ export var BulkEmailType;
|
|
|
15
15
|
/** "Email to list" — plain email to a list resolved from a document property. */
|
|
16
16
|
BulkEmailType["Default"] = "default";
|
|
17
17
|
})(BulkEmailType || (BulkEmailType = {}));
|
|
18
|
+
/* -------------------------------------------------------------------------- */
|
|
19
|
+
/* THE EMAIL STEP — supersedes `bulkEmail` entirely */
|
|
20
|
+
/* -------------------------------------------------------------------------- */
|
|
21
|
+
/* */
|
|
22
|
+
/* ONE step type, configured several ways. `bulkMail` stops meaning "send a */
|
|
23
|
+
/* supplier bid invite to a list" and starts meaning "send an email", with the */
|
|
24
|
+
/* recipient strategy and the template chosen per step. */
|
|
25
|
+
/* */
|
|
26
|
+
/* WHY A NEW FIELD RATHER THAN MORE KEYS ON `bulkEmail` */
|
|
27
|
+
/* --------------------------------------------------- */
|
|
28
|
+
/* `bulkEmail` carries four kinds of redundancy that cannot be removed in */
|
|
29
|
+
/* place: */
|
|
30
|
+
/* */
|
|
31
|
+
/* 1. `documentValueWithEmail` / `listPropertyWithEmail` exist BOTH here and */
|
|
32
|
+
/* as top-level `ProcessStep` columns. The editor writes the nested pair; */
|
|
33
|
+
/* the top-level pair is dead but persisted. */
|
|
34
|
+
/* 2. `type` offers two values of which one (`default`) has no send path */
|
|
35
|
+
/* anywhere — a legal, persisted, permanently inert configuration. */
|
|
36
|
+
/* 3. `emailSubjectFormKey` / `emailBodyFormKey` can only POINT at a form */
|
|
37
|
+
/* control. There is no way to author content, so every email's wording */
|
|
38
|
+
/* has to be smuggled in through a form field. */
|
|
39
|
+
/* 4. `tenderNumberFormKey` / `closingDateFormKey` are procurement-specific */
|
|
40
|
+
/* keys sitting on the general-purpose config, gated by a delivery mode */
|
|
41
|
+
/* rather than by a template. */
|
|
42
|
+
/* */
|
|
43
|
+
/* {@link EmailStepConfig} is the optimised shape: flat (so every member maps */
|
|
44
|
+
/* 1:1 onto one editor control and one `deepBind` path), mode-discriminated, */
|
|
45
|
+
/* and free of the duplicate pair. The editor writes ONLY this field. */
|
|
46
|
+
/* `bulkEmail` and the two top-level duplicates remain DECLARED so existing */
|
|
47
|
+
/* readers keep compiling, and the engine owns the read-time migration. */
|
|
48
|
+
/* -------------------------------------------------------------------------- */
|
|
49
|
+
/**
|
|
50
|
+
* Who an email step sends to.
|
|
51
|
+
*
|
|
52
|
+
* The FIRST question the editor asks, because every other recipient control is
|
|
53
|
+
* gated on it. Replaces `BulkEmailType`, which asked about delivery mechanism —
|
|
54
|
+
* a question a workflow author has no basis to answer.
|
|
55
|
+
*/
|
|
56
|
+
export var EmailRecipientMode;
|
|
57
|
+
(function (EmailRecipientMode) {
|
|
58
|
+
/** One address, held in a form control on the document. */
|
|
59
|
+
EmailRecipientMode["FormControl"] = "formControl";
|
|
60
|
+
/** One address, resolved from the assignee of another step in this workflow. */
|
|
61
|
+
EmailRecipientMode["Member"] = "member";
|
|
62
|
+
/** One fixed address, typed into the step. */
|
|
63
|
+
EmailRecipientMode["Literal"] = "literal";
|
|
64
|
+
/** Every row of a list held on the document. The old `bulkEmail` behaviour. */
|
|
65
|
+
EmailRecipientMode["List"] = "list";
|
|
66
|
+
})(EmailRecipientMode || (EmailRecipientMode = {}));
|
|
67
|
+
/**
|
|
68
|
+
* Which template an email step starts from.
|
|
69
|
+
*
|
|
70
|
+
* Replaces `BulkEmailType.IServe` as the gate for the procurement-only fields:
|
|
71
|
+
* the author is picking a TEMPLATE, which they can reason about, instead of a
|
|
72
|
+
* delivery mode, which they cannot.
|
|
73
|
+
*/
|
|
74
|
+
export var EmailTemplatePreset;
|
|
75
|
+
(function (EmailTemplatePreset) {
|
|
76
|
+
/** Author writes the whole body. */
|
|
77
|
+
EmailTemplatePreset["Blank"] = "blank";
|
|
78
|
+
/** Procurement supplier bid invite — reveals the tender and closing-date keys. */
|
|
79
|
+
EmailTemplatePreset["SupplierBidInvite"] = "supplierBidInvite";
|
|
80
|
+
})(EmailTemplatePreset || (EmailTemplatePreset = {}));
|
|
18
81
|
/**
|
|
19
82
|
* The adjudication role a workflow step plays.
|
|
20
83
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WorkflowStepTypeEnum } from '../ProcessStep/WorkflowStepType.interface.js';
|
|
2
|
-
import { AdjudicationType,
|
|
2
|
+
import { AdjudicationType, EmailRecipientMode, EmailTemplatePreset } from '../ProcessStep/ProcessStep.interface.js';
|
|
3
3
|
import { StepRequirementSeverity } from './StepTypeRequirements.interface.js';
|
|
4
4
|
import { ReferenceCatalog, ReferenceTargetKind, } from './StepReferenceRules.interface.js';
|
|
5
5
|
/** `ElementTypes.WorkflowAdjudication`. See the guard above. */
|
|
@@ -43,12 +43,10 @@ function formIdRule(stepType) {
|
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
|
-
* `
|
|
46
|
+
* `email.<key>` -> a control name in the document form.
|
|
47
47
|
*
|
|
48
|
-
* ERROR, not warning. Every one of these is dereferenced as
|
|
49
|
-
*
|
|
50
|
-
* path (`E/services/workflow.ts:595-611`), which runs only when
|
|
51
|
-
* `bulkEmail.type === 'i-serve'` — hence the shared `when` gate below.
|
|
48
|
+
* ERROR, not warning. Every one of these is dereferenced as `document.form[key]`
|
|
49
|
+
* by the WORKFLOW ENGINE on the send path (`E/services/workflow.ts:595-611`).
|
|
52
50
|
*
|
|
53
51
|
* The engine never guards these reads, so a stale key yields `undefined` and the
|
|
54
52
|
* enclosing branch silently no-ops. Worse, the send happens on the DEFERRED side
|
|
@@ -56,27 +54,31 @@ function formIdRule(stepType) {
|
|
|
56
54
|
* (`E/utils/workflowSideEffects.ts:25-27`): the API call succeeds, the step
|
|
57
55
|
* completes, and no email is ever sent.
|
|
58
56
|
*
|
|
59
|
-
* `
|
|
60
|
-
* ROW of the recipient list, not
|
|
57
|
+
* `email.listAddressProperty` is deliberately NOT one of these — it indexes a
|
|
58
|
+
* ROW of the recipient list, not the document form. See
|
|
61
59
|
* {@link EXCLUDED_STEP_REFERENCES}.
|
|
60
|
+
*
|
|
61
|
+
* @param key - The `EmailStepConfig` member, without the `email.` prefix.
|
|
62
|
+
* @param label - Display label for the offending control.
|
|
63
|
+
* @param consequence - One sentence on what breaks, for the author.
|
|
64
|
+
* @param when - The recipient mode or template preset that makes the key live.
|
|
65
|
+
* @param extraEvidence - Rule-specific `file:line` sites, read sites first.
|
|
62
66
|
*/
|
|
63
|
-
function
|
|
67
|
+
function emailKeyRule(key, label, consequence, when, extraEvidence) {
|
|
64
68
|
return {
|
|
65
|
-
id: `bulkMail.
|
|
69
|
+
id: `bulkMail.email.${key}`,
|
|
66
70
|
stepType: WorkflowStepTypeEnum.BulkMail,
|
|
67
|
-
field: `
|
|
71
|
+
field: `email.${key}`,
|
|
68
72
|
label,
|
|
69
73
|
targetKind: ReferenceTargetKind.FormControlInWorkflow,
|
|
70
|
-
|
|
71
|
-
when: [{ field: 'bulkEmail.type', equals: BulkEmailType.IServe }],
|
|
74
|
+
when,
|
|
72
75
|
severity: StepRequirementSeverity.Error,
|
|
73
76
|
message: consequence,
|
|
74
77
|
evidence: [
|
|
75
78
|
...extraEvidence,
|
|
76
|
-
'E/services/workflow.ts:589-594 (the send gate; everything below runs only under `type == "i-serve"`)',
|
|
77
79
|
'E/utils/workflowSideEffects.ts:25-27 (the send is deferred and its failures are logged and swallowed — nothing surfaces to the user)',
|
|
78
|
-
|
|
79
|
-
'W/component/workflow-diagram/store/workflowDiagramSelectors.ts
|
|
80
|
+
'W/component/workflow-diagram/processStepEditorConfig.ts (the writers; picker scope is the workflow-wide `allInputs` union, which is the right pool: the engine reads the accumulated `document.form`)',
|
|
81
|
+
'W/component/workflow-diagram/store/workflowDiagramSelectors.ts (that union)',
|
|
80
82
|
],
|
|
81
83
|
requires: [ReferenceCatalog.WorkflowControlNames],
|
|
82
84
|
requiresExternalCatalog: true,
|
|
@@ -271,27 +273,20 @@ export const STEP_REFERENCE_RULES = {
|
|
|
271
273
|
/* BULK MAIL */
|
|
272
274
|
/* ====================================================================== */
|
|
273
275
|
[WorkflowStepTypeEnum.BulkMail]: [
|
|
274
|
-
|
|
276
|
+
emailKeyRule('addressFormKey', 'Field holding the email address', 'This names the document field holding the recipient address. Pointing at a control this workflow does not have leaves the address `undefined`, so nothing is sent — while the step reports success.', [{ field: 'email.mode', equals: EmailRecipientMode.FormControl }], ['E/services/workflow.ts:601 (`document.form[propkey]`)']),
|
|
277
|
+
emailKeyRule('listFormKey', 'Field holding the recipient list', 'This names the document field holding the recipient list. Pointing at a control this workflow does not have makes the list `undefined`, the send loop never runs, and NOT ONE recipient is emailed — while the step reports success.', [{ field: 'email.mode', equals: EmailRecipientMode.List }], [
|
|
275
278
|
'E/services/workflow.ts:595,601 (`const propkey = ...; const arrValue = document.form[propkey]`)',
|
|
276
279
|
'E/services/workflow.ts:603 (`if (arrValue?.length > 0)` — the silent no-op)',
|
|
277
280
|
]),
|
|
278
|
-
|
|
279
|
-
'E/services/workflow.ts:597,606 (`document.form[emailSubjectKey]`)',
|
|
280
|
-
'E/services/mailer.ts:206,210 (`subject` and the `Rfqdescription` template variable)',
|
|
281
|
-
]),
|
|
282
|
-
bulkEmailKeyRule('emailBodyFormKey', 'Email body field', 'This names the document field holding the invite body. Pointing at a control this workflow does not have mails every supplier an empty invite.', [
|
|
283
|
-
'E/services/workflow.ts:598,607 (`document.form[emailBodyKey]`)',
|
|
284
|
-
'E/services/mailer.ts:214 (`Insertbody` template variable)',
|
|
285
|
-
]),
|
|
286
|
-
bulkEmailKeyRule('tenderNumberFormKey', 'Tender number field', "This names the document field holding the tender number, which goes into both the invite and the supplier's signed response token. Pointing at a control this workflow does not have produces an unidentifiable invite and a token that cannot be tied back to a tender.", [
|
|
281
|
+
emailKeyRule('tenderNumberFormKey', 'Field holding the tender number', "This names the document field holding the tender number, which goes into both the invite and the supplier's signed response token. Pointing at a control this workflow does not have produces an unidentifiable invite and a token that cannot be tied back to a tender.", [{ field: 'email.preset', equals: EmailTemplatePreset.SupplierBidInvite }], [
|
|
287
282
|
'E/services/workflow.ts:599,608 (`document.form[tenderNumberKey]`)',
|
|
288
283
|
'E/services/workflow.ts:617-620 (signed into the token payload)',
|
|
289
284
|
'E/services/mailer.ts:212 (`TenderNumber` template variable)',
|
|
290
285
|
]),
|
|
291
|
-
|
|
286
|
+
emailKeyRule('closingDateFormKey', 'Field holding the closing date', 'This is the worst of the set to get wrong. The closing date is the EXPIRY of the response token: an unresolvable control makes it `Invalid Date`, the token expiry becomes `NaN`, signing throws on the FIRST recipient, and the entire send loop aborts — no messages at all, and the failure is swallowed.', [{ field: 'email.preset', equals: EmailTemplatePreset.SupplierBidInvite }], [
|
|
292
287
|
'E/services/workflow.ts:600,609-611 (`new Date(document.form[closingDateKey]).toDateString()` -> "Invalid Date")',
|
|
293
288
|
"E/utils/tokenizer.ts:64-78 (`exp: Math.floor(new Date(date).getTime()/1000)` -> `NaN`; `jwt.sign` throws, rethrown as `Error('Session have Expired!')`)",
|
|
294
|
-
'E/services/workflow.ts:613-633 (the throw aborts the loop over ALL
|
|
289
|
+
'E/services/workflow.ts:613-633 (the throw aborts the loop over ALL recipients)',
|
|
295
290
|
]),
|
|
296
291
|
],
|
|
297
292
|
/* ====================================================================== */
|
|
@@ -826,9 +821,9 @@ export const EXCLUDED_STEP_REFERENCES = [
|
|
|
826
821
|
],
|
|
827
822
|
},
|
|
828
823
|
{
|
|
829
|
-
field: '
|
|
824
|
+
field: 'email.listAddressProperty',
|
|
830
825
|
stepType: WorkflowStepTypeEnum.BulkMail,
|
|
831
|
-
reason: "NOT A FORM CONTROL — it indexes into a ROW. The engine reads it as `element[emailColumnKey]` where `element` is an item of `document.form[
|
|
826
|
+
reason: "NOT A FORM CONTROL — it indexes into a ROW. The engine reads it as `element[emailColumnKey]` where `element` is an item of `document.form[listFormKey]`, so the valid names are the keys of the LIST ROWS, not the workflow's control names. Validating it against the control-name union would flag every correct configuration. Same class as the adjudication respondent keys. The field is still REQUIRED (at error) by the per-field layer, because the engine's send gate tests for its presence — only the cross-reference check is unsound.",
|
|
832
827
|
evidence: [
|
|
833
828
|
'E/services/workflow.ts:596,614-616 (`const emailColumnKey = ...; const element = arrValue[index]; const email = element[emailColumnKey]`)',
|
|
834
829
|
'E/services/workflow.ts:592 (still a hard conjunct of the send gate, hence the per-field requirement)',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WorkflowStepTypeEnum } from '../ProcessStep/WorkflowStepType.interface.js';
|
|
2
|
-
import { AdjudicationType,
|
|
2
|
+
import { AdjudicationType, EmailRecipientMode, EmailTemplatePreset } from '../ProcessStep/ProcessStep.interface.js';
|
|
3
3
|
import { StepFieldValueType, StepRequirementSeverity, StepTypeOrigin, } from './StepTypeRequirements.interface.js';
|
|
4
4
|
/* -------------------------------------------------------------------------- */
|
|
5
5
|
/* Evidence-file shorthands used throughout */
|
|
@@ -643,173 +643,210 @@ export const STEP_TYPE_REQUIREMENTS = {
|
|
|
643
643
|
/* ====================================================================== */
|
|
644
644
|
[WorkflowStepTypeEnum.BulkMail]: {
|
|
645
645
|
stepType: WorkflowStepTypeEnum.BulkMail,
|
|
646
|
-
label: '
|
|
646
|
+
label: 'Email',
|
|
647
647
|
origin: StepTypeOrigin.Authored,
|
|
648
648
|
systemStep: true,
|
|
649
649
|
required: [
|
|
650
650
|
LABEL_RULE,
|
|
651
651
|
{
|
|
652
|
-
field: '
|
|
653
|
-
label: '
|
|
652
|
+
field: 'email',
|
|
653
|
+
label: 'Email configuration',
|
|
654
654
|
type: StepFieldValueType.Object,
|
|
655
655
|
severity: StepRequirementSeverity.Error,
|
|
656
|
-
actionLabel: '
|
|
657
|
-
hint: 'Start by choosing the
|
|
658
|
-
message: 'Set up the
|
|
656
|
+
actionLabel: 'Who receives this email?',
|
|
657
|
+
hint: 'Start by choosing who receives the email; the remaining fields appear once you have.',
|
|
658
|
+
message: 'Set up the email before saving. Left blank, the step completes and not a single message is sent.',
|
|
659
659
|
evidence: [
|
|
660
|
-
'E/services/workflow.ts:
|
|
661
|
-
'
|
|
662
|
-
'
|
|
663
|
-
'W/component/workflow-diagram/processStepEditorConfig.ts:324-478 (seven `deepBind: [\'bulkEmail\', …]` write sites)',
|
|
664
|
-
'P/features/transactions/application/store/functions/workflow-document-utils.ts:352-356 (a bulk-mail step surfacing as ACTIVE means the automated transition never resolved -> `stuck`)',
|
|
660
|
+
'E/services/workflow.ts:588-635 (the send path; every value below is dereferenced there)',
|
|
661
|
+
'W/component/workflow-diagram/WorkflowStepDefault.ts (requiredProperties)',
|
|
662
|
+
'P/features/transactions/application/store/functions/workflow-document-utils.ts:352-356,417 (an email step surfacing as ACTIVE means the automated transition never resolved -> `stuck`)',
|
|
665
663
|
],
|
|
666
664
|
},
|
|
667
665
|
{
|
|
668
|
-
field: '
|
|
669
|
-
label: '
|
|
666
|
+
field: 'email.mode',
|
|
667
|
+
label: 'Recipients',
|
|
670
668
|
type: StepFieldValueType.String,
|
|
671
|
-
allowedValues: [
|
|
669
|
+
allowedValues: [
|
|
670
|
+
EmailRecipientMode.FormControl,
|
|
671
|
+
EmailRecipientMode.Member,
|
|
672
|
+
EmailRecipientMode.Literal,
|
|
673
|
+
EmailRecipientMode.List,
|
|
674
|
+
],
|
|
672
675
|
severity: StepRequirementSeverity.Error,
|
|
673
|
-
actionLabel: '
|
|
674
|
-
hint: '
|
|
675
|
-
message: 'Choose
|
|
676
|
+
actionLabel: 'Who receives this email?',
|
|
677
|
+
hint: 'One person from a form field, a step assignee, a fixed address, or everyone in a list.',
|
|
678
|
+
message: 'Choose who receives this email. Until you do, none of the recipient fields can be filled in and the step sends nothing.',
|
|
676
679
|
evidence: [
|
|
677
|
-
'E/services/workflow.ts:
|
|
678
|
-
'W/component/workflow-diagram/processStepEditorConfig.ts
|
|
679
|
-
'
|
|
680
|
+
'E/services/workflow.ts:589-594 (the send gate branches on the recipient strategy)',
|
|
681
|
+
'W/component/workflow-diagram/processStepEditorConfig.ts (ChipSelect, four options)',
|
|
682
|
+
'REPLACES `bulkEmail.type`, which asked about delivery mechanism rather than recipients and offered a value (`default`) with no send path at all.',
|
|
680
683
|
],
|
|
684
|
+
divergesFromDescriptor: 'REPLACES the `bulkEmail.type` rules. The old field forced the author to choose between "Procurement supplier bid invite" and "Email to list" before anything else, which is a question about the SENDER, not about the email. Recipient mode is the real discriminator and every other recipient control gates on it.',
|
|
681
685
|
},
|
|
682
686
|
{
|
|
683
|
-
field: '
|
|
684
|
-
label: '
|
|
687
|
+
field: 'email.subject',
|
|
688
|
+
label: 'Subject line',
|
|
685
689
|
type: StepFieldValueType.String,
|
|
686
690
|
severity: StepRequirementSeverity.Error,
|
|
687
|
-
actionLabel: '
|
|
688
|
-
hint: '
|
|
689
|
-
message: '
|
|
691
|
+
actionLabel: 'Subject',
|
|
692
|
+
hint: 'Type the subject. Press $ to insert a document value.',
|
|
693
|
+
message: 'Write the subject line. Without one every recipient gets a message with an empty subject, which most mail clients file as suspicious.',
|
|
690
694
|
evidence: [
|
|
691
|
-
'E/services/workflow.ts:
|
|
692
|
-
'E/services/
|
|
693
|
-
'
|
|
694
|
-
'W/component/workflow-diagram/processStepEditorConfig.ts:415-422',
|
|
695
|
-
'W/component/workflow-diagram/processStepEditorConfig.ts:429-433 (the list-property input is gated on this existing)',
|
|
695
|
+
'E/services/workflow.ts:597,606 (`document.form[emailSubjectKey]` — the legacy pointer this template string replaces)',
|
|
696
|
+
'E/services/mailer.ts:206,210 (`subject` and the `Rfqdescription` template variable)',
|
|
697
|
+
'W/shared/functions/quill-email/tokens.ts (the `{{token}}` grammar the subject accepts)',
|
|
696
698
|
],
|
|
697
|
-
divergesFromDescriptor: '
|
|
699
|
+
divergesFromDescriptor: 'The field is now a TEMPLATE STRING rather than a form-control pointer (`emailSubjectFormKey`). An author can type a subject and embed `{{token}}` references, instead of being forced to route the wording through a form field.',
|
|
698
700
|
},
|
|
699
701
|
{
|
|
700
|
-
field: '
|
|
701
|
-
label: '
|
|
702
|
+
field: 'email.bodyHtml',
|
|
703
|
+
label: 'Message body',
|
|
702
704
|
type: StepFieldValueType.String,
|
|
703
705
|
severity: StepRequirementSeverity.Error,
|
|
704
|
-
actionLabel: '
|
|
705
|
-
hint: '
|
|
706
|
-
message: '
|
|
706
|
+
actionLabel: 'Message',
|
|
707
|
+
hint: 'Write the message. Press $ to insert a document value.',
|
|
708
|
+
message: 'Write the message body. An empty body sends a blank email.',
|
|
707
709
|
evidence: [
|
|
708
|
-
'E/services/workflow.ts:
|
|
709
|
-
'E/services/
|
|
710
|
-
'
|
|
711
|
-
"W/component/workflow-diagram/processStepEditorConfig.ts:423-435 (editor gate: `{ testType: 'exists', deepBind: ['bulkEmail','documentValueWithEmail'] }`)",
|
|
710
|
+
'E/services/workflow.ts:598,607 (`document.form[emailBodyKey]` — the legacy pointer this replaces)',
|
|
711
|
+
'E/services/mailer.ts:214 (`Insertbody` template variable)',
|
|
712
|
+
'W/shared/functions/quill-email/quill-to-email-html.ts (compiles the authored body to sanitised, email-safe HTML at SAVE time)',
|
|
712
713
|
],
|
|
713
|
-
divergesFromDescriptor: '
|
|
714
|
+
divergesFromDescriptor: 'Derived, not typed by hand: the author edits `email.bodyDocument` in a rich-text editor and the builder compiles this field from it. Validated rather than `bodyDocument` because this is the value that is actually sent.',
|
|
714
715
|
},
|
|
715
716
|
],
|
|
716
717
|
conditional: [
|
|
717
718
|
{
|
|
718
|
-
field: '
|
|
719
|
-
label: '
|
|
719
|
+
field: 'email.addressFormKey',
|
|
720
|
+
label: 'Field holding the email address',
|
|
721
|
+
type: StepFieldValueType.String,
|
|
722
|
+
when: [{ field: 'email.mode', equals: EmailRecipientMode.FormControl }],
|
|
723
|
+
severity: StepRequirementSeverity.Error,
|
|
724
|
+
actionLabel: 'Which field holds the email address?',
|
|
725
|
+
hint: 'Point at the form field that captures the recipient address.',
|
|
726
|
+
message: 'Choose the field holding the recipient address. If it is blank or names a field this workflow does not have, there is no address to send to and the step still reports as done.',
|
|
727
|
+
evidence: [
|
|
728
|
+
'E/services/workflow.ts:601 (`document.form[propkey]` — same dereference, single-address arm)',
|
|
729
|
+
'W/component/workflow-diagram/store/workflowDiagramSelectors.ts (resolved against the workflow-wide control union)',
|
|
730
|
+
],
|
|
731
|
+
},
|
|
732
|
+
{
|
|
733
|
+
field: 'email.memberStepId',
|
|
734
|
+
label: 'Step whose assignee is emailed',
|
|
735
|
+
type: StepFieldValueType.String,
|
|
736
|
+
when: [{ field: 'email.mode', equals: EmailRecipientMode.Member }],
|
|
737
|
+
severity: StepRequirementSeverity.Error,
|
|
738
|
+
actionLabel: 'Which step assignee receives it?',
|
|
739
|
+
hint: 'Pick the step whose assigned member should be emailed.',
|
|
740
|
+
message: 'Choose which step assignee receives this email. Without it there is no-one to resolve an address for.',
|
|
741
|
+
evidence: [
|
|
742
|
+
'E/services/workflow.ts:724-733 (`nextProcess.members` -> `userModel.findOne` -> `nextUser` is the established member-to-address resolution)',
|
|
743
|
+
'W/component/workflow-diagram/processStepEditorConfig.ts (WorkflowStepPicker supplies `step.stepId`, a uuid string)',
|
|
744
|
+
],
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
field: 'email.address',
|
|
748
|
+
label: 'Email address',
|
|
749
|
+
type: StepFieldValueType.String,
|
|
750
|
+
when: [{ field: 'email.mode', equals: EmailRecipientMode.Literal }],
|
|
751
|
+
severity: StepRequirementSeverity.Error,
|
|
752
|
+
actionLabel: 'Email address',
|
|
753
|
+
hint: 'Type the fixed address this step always mails.',
|
|
754
|
+
message: 'Type the address this step sends to. A fixed address outlives the person who holds it, so prefer a shared mailbox over an individual.',
|
|
755
|
+
evidence: [
|
|
756
|
+
'E/services/mailer.ts:205 (`to: [email]` accepts a literal address unchanged)',
|
|
757
|
+
],
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
field: 'email.listFormKey',
|
|
761
|
+
label: 'Field holding the recipient list',
|
|
720
762
|
type: StepFieldValueType.String,
|
|
721
|
-
when: [{ field: '
|
|
763
|
+
when: [{ field: 'email.mode', equals: EmailRecipientMode.List }],
|
|
722
764
|
severity: StepRequirementSeverity.Error,
|
|
723
|
-
actionLabel: '
|
|
724
|
-
hint: 'Point
|
|
725
|
-
message: 'Choose the
|
|
765
|
+
actionLabel: 'Which field holds the list?',
|
|
766
|
+
hint: 'Point at the form field that holds the rows of recipients.',
|
|
767
|
+
message: 'Choose the field holding the recipient list. If it is blank or names a field this workflow does not have, the list is empty and nobody is emailed — though the step still reports as done.',
|
|
726
768
|
evidence: [
|
|
727
|
-
'E/services/workflow.ts:
|
|
728
|
-
'E/services/
|
|
729
|
-
'
|
|
769
|
+
'E/services/workflow.ts:591 (gate conjunct 1), :595,601 (`const arrValue = document.form[propkey]`)',
|
|
770
|
+
'E/services/workflow.ts:603 (`if (arrValue?.length > 0)` — the silent no-op when the key misses)',
|
|
771
|
+
'MIGRATION: same value as the legacy `bulkEmail.documentValueWithEmail`, under a name that says what it is.',
|
|
730
772
|
],
|
|
731
|
-
divergesFromDescriptor: 'PROMOTED to error and gated on `i-serve` (corrected). Previously an unconditional `warning`. The engine reads it only inside the `i-serve` branch, so the gate is now explicit, and it feeds an outgoing email — the coordinator\'s "sends mail" criterion.',
|
|
732
773
|
},
|
|
733
774
|
{
|
|
734
|
-
field: '
|
|
735
|
-
label: '
|
|
775
|
+
field: 'email.listAddressProperty',
|
|
776
|
+
label: 'Column holding the address',
|
|
736
777
|
type: StepFieldValueType.String,
|
|
737
|
-
when: [{ field: '
|
|
778
|
+
when: [{ field: 'email.mode', equals: EmailRecipientMode.List }],
|
|
738
779
|
severity: StepRequirementSeverity.Error,
|
|
739
|
-
actionLabel: '
|
|
740
|
-
hint: '
|
|
741
|
-
message: 'Choose
|
|
780
|
+
actionLabel: 'Which column holds the address?',
|
|
781
|
+
hint: 'Name the column inside each row that holds the email address.',
|
|
782
|
+
message: 'Choose which column of each row holds the email address. Without it the step either sends nothing or mails a blank address that every recipient bounces — one silent failure per recipient.',
|
|
742
783
|
evidence: [
|
|
743
|
-
'E/services/workflow.ts:
|
|
744
|
-
'E/services/mailer.ts:
|
|
745
|
-
'
|
|
784
|
+
'E/services/workflow.ts:592 (gate conjunct 2), :596,616 (`const email = element[emailColumnKey]`)',
|
|
785
|
+
'E/services/mailer.ts:205,219-229 (`to: [email]`; a provider rejection is caught and returned as `{delivered: 0}`, never surfaced)',
|
|
786
|
+
'NOT a form-control reference — it indexes a ROW. See EXCLUDED_STEP_REFERENCES.',
|
|
787
|
+
'MIGRATION: same value as the legacy `bulkEmail.listPropertyWithEmail`.',
|
|
746
788
|
],
|
|
747
|
-
divergesFromDescriptor: 'PROMOTED to error and gated on `i-serve` (corrected). Same reasoning as `emailSubjectFormKey`.',
|
|
748
789
|
},
|
|
749
790
|
{
|
|
750
|
-
field: '
|
|
751
|
-
label: '
|
|
791
|
+
field: 'email.tenderNumberFormKey',
|
|
792
|
+
label: 'Field holding the tender number',
|
|
752
793
|
type: StepFieldValueType.String,
|
|
753
|
-
when: [{ field: '
|
|
794
|
+
when: [{ field: 'email.preset', equals: EmailTemplatePreset.SupplierBidInvite }],
|
|
754
795
|
severity: StepRequirementSeverity.Error,
|
|
755
|
-
actionLabel: '
|
|
756
|
-
hint: 'Point
|
|
757
|
-
message:
|
|
796
|
+
actionLabel: 'Field holding the tender number',
|
|
797
|
+
hint: 'Point at the form field that holds the tender number.',
|
|
798
|
+
message: 'Choose the field holding the tender number — it identifies the bid the supplier is invited to and ties their response back to it. Without it the invite is unidentifiable and responses cannot be matched to a tender.',
|
|
758
799
|
evidence: [
|
|
759
|
-
'E/services/workflow.ts:599,608 (`
|
|
800
|
+
'E/services/workflow.ts:599,608 (`document.form[tenderNumberKey]`)',
|
|
760
801
|
'E/services/workflow.ts:617-620 (signed into the response token payload)',
|
|
761
802
|
'E/services/mailer.ts:212 (`TenderNumber` template variable)',
|
|
762
|
-
"W/component/workflow-diagram/processStepEditorConfig.ts:450-463 (editor gate: `expression: 'type === i-serve'` on `deepBind: ['bulkEmail','type']`)",
|
|
763
803
|
],
|
|
764
|
-
divergesFromDescriptor: '
|
|
804
|
+
divergesFromDescriptor: 'Gate changed from `bulkEmail.type === i-serve` to `email.preset === supplierBidInvite`. Same set of steps, but the author is picking a template rather than a delivery mode.',
|
|
765
805
|
},
|
|
766
806
|
{
|
|
767
|
-
field: '
|
|
768
|
-
label: '
|
|
807
|
+
field: 'email.closingDateFormKey',
|
|
808
|
+
label: 'Field holding the closing date',
|
|
769
809
|
type: StepFieldValueType.String,
|
|
770
|
-
when: [{ field: '
|
|
810
|
+
when: [{ field: 'email.preset', equals: EmailTemplatePreset.SupplierBidInvite }],
|
|
771
811
|
severity: StepRequirementSeverity.Error,
|
|
772
|
-
actionLabel: '
|
|
773
|
-
hint: 'Point
|
|
774
|
-
message:
|
|
812
|
+
actionLabel: 'Field holding the closing date',
|
|
813
|
+
hint: 'Point at a DATE field — it is also the deadline on each response link.',
|
|
814
|
+
message: 'Choose the field holding the tender closing date — it doubles as the deadline on each supplier response link. Leave it blank and the whole send fails on the first supplier, so not one invite goes out, with no error shown.',
|
|
775
815
|
evidence: [
|
|
776
816
|
'E/services/workflow.ts:600,609-611 (`new Date(document.form[closingDateKey]).toDateString()` -> "Invalid Date")',
|
|
777
|
-
|
|
778
|
-
"E/utils/tokenizer.ts:64-78 (`exp: Math.floor(new Date(date).getTime() / 1000)` -> `NaN`; `jwt.sign` throws and is rethrown as `Error('Session have Expired!')`)",
|
|
817
|
+
"E/utils/tokenizer.ts:64-78 (`exp: Math.floor(new Date(date).getTime() / 1000)` -> `NaN`; `jwt.sign` throws, rethrown as `Error('Session have Expired!')`)",
|
|
779
818
|
'E/services/workflow.ts:613-633 (the throw aborts the `for` loop over ALL suppliers)',
|
|
780
|
-
'E/utils/workflowSideEffects.ts:25-27 (`void effect().catch(
|
|
781
|
-
"W/component/workflow-diagram/processStepEditorConfig.ts:464-478 (editor gate: `expression: 'type === i-serve'`)",
|
|
819
|
+
'E/utils/workflowSideEffects.ts:25-27 (`void effect().catch(...)` — the abort is logged and swallowed, never surfaced)',
|
|
782
820
|
],
|
|
783
|
-
divergesFromDescriptor: '
|
|
821
|
+
divergesFromDescriptor: 'Gate changed to `email.preset === supplierBidInvite`, as for the tender number. Severity stays `error`: this is the worst field in the set to get wrong, because it fails the ENTIRE batch rather than one recipient.',
|
|
784
822
|
},
|
|
785
823
|
],
|
|
786
824
|
optional: [
|
|
787
825
|
{
|
|
788
|
-
field: '
|
|
789
|
-
label: '
|
|
826
|
+
field: 'email.preset',
|
|
827
|
+
label: 'Template',
|
|
790
828
|
type: StepFieldValueType.String,
|
|
791
|
-
allowedValues: [
|
|
829
|
+
allowedValues: [EmailTemplatePreset.Blank, EmailTemplatePreset.SupplierBidInvite],
|
|
792
830
|
severity: StepRequirementSeverity.Warning,
|
|
793
|
-
actionLabel: '
|
|
794
|
-
hint: '
|
|
795
|
-
message: '
|
|
831
|
+
actionLabel: 'Template',
|
|
832
|
+
hint: 'Start from a blank message, or from the procurement supplier bid invite.',
|
|
833
|
+
message: 'Pick a template to start from. Leaving it unset is the same as starting blank.',
|
|
796
834
|
evidence: [
|
|
797
|
-
'E/services/
|
|
798
|
-
'
|
|
799
|
-
'E/services/mailer.ts:183-231 (`SendSupplierEmail` uses the "bid invite" template exclusively)',
|
|
800
|
-
'W/component/workflow-diagram/processStepEditorConfig.ts:324-336 (the editor nonetheless offers both options)',
|
|
835
|
+
'E/services/mailer.ts:183-231 (`SendSupplierEmail` — the "bid invite" template the preset reproduces)',
|
|
836
|
+
'W/component/workflow-diagram/processStepEditorConfig.ts (ChipSelect, two options)',
|
|
801
837
|
],
|
|
802
|
-
divergesFromDescriptor: '
|
|
838
|
+
divergesFromDescriptor: 'NOT required: an unset preset is a well-defined state (blank), unlike the old `bulkEmail.type` where unset meant the step could never send.',
|
|
803
839
|
},
|
|
804
840
|
],
|
|
805
841
|
sockets: LINEAR_SOCKETS,
|
|
806
842
|
integrityNotes: [
|
|
807
|
-
'
|
|
808
|
-
'
|
|
809
|
-
'
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
843
|
+
'REWRITTEN against `ProcessStep.email`, which supersedes `bulkEmail` entirely. One step type, configured several ways: the recipient strategy is now an explicit four-value mode instead of being implied by which keys happen to be present, and the procurement-only fields gate on a TEMPLATE rather than on a delivery mode.',
|
|
844
|
+
'EVIDENCE PROVENANCE. The `file:line` sites cited for the `email.*` rules are the engine reads of the LEGACY key carrying the same value (`email.listFormKey` <- `bulkEmail.documentValueWithEmail` at `E/services/workflow.ts:595,601`, and so on). They are cited because they prove the field is load-bearing, not because the engine reads the new spelling today — the read-time migration from `bulkEmail` onto `EmailStepConfig` is the engines own half of this change and is tracked separately. No rule here claims a read site that does not exist.',
|
|
845
|
+
'ENGINE GATE, for reference (`E/services/workflow.ts:589-594`): `process.bulkEmail?.hasOwnProperty("documentValueWithEmail") && ...hasOwnProperty("listPropertyWithEmail") && process.bulkEmail?.type == "i-serve"`. It tests KEY PRESENCE, not truthiness — `documentValueWithEmail: ""` passes and then resolves `document.form[""]` to `undefined`, so the step reports success and sends nothing. The validator is deliberately STRICTER than the runtime: `hasValue` treats `""` as absent (`W/component/workflow-diagram/function/nodeValidator.ts:175-177`), so the canvas blocks exactly the configuration the engine would accept and silently no-op.',
|
|
846
|
+
'NO MEMBERS RULE, AND THAT IS CORRECT. An email step reached as the NEXT step advances only through `E/services/workflow.ts:843-848`, where `updateR = true` is set exclusively when the next step has no members; nothing else in the engine completes one, so members on an email step would stall the document permanently (`P/.../workflow-document-utils.ts:417` already reports that state as `system-fault`). A `maxItems: 0` rule was drafted for this and then REMOVED: the builder makes the state unreachable. `bulkMail` is `systemStep: true`, the context menu hard-disables the members picker for an automated step, and `W/component/workflow-diagram/store/workflowDiagramActions.ts:305,378` force `members: []` on save whenever `systemStep === true`. `W/component/workflow-diagram/function/nodeValidator.ts:156,330-331` consequently skips `members` and `formId` on system steps altogether, so the rule could never fire — and if it somehow did, it would be an error with no reachable control to clear it, which is the specific trap this validator exists to avoid. The hazard is real but the builder already forecloses it; the only way back in is flipping the step off `systemStep`, which is what the flag is for.',
|
|
847
|
+
'THE `default` MODE IS GONE. `bulkEmail.type` offered "Email to list", which has no send path anywhere in `osproc-be` — a legal, persisted, permanently inert configuration the editor actively recommended. It is not carried into `EmailRecipientMode`; list sending is `EmailRecipientMode.List`, which is the arm that actually works.',
|
|
848
|
+
'THE REDUNDANT PAIR IS GONE. `documentValueWithEmail` / `listPropertyWithEmail` existed BOTH as nested `bulkEmail` keys and as top-level `ProcessStep` columns, with the editor writing the nested pair and the top-level pair persisted but dead. `EmailStepConfig` has one spelling for each.',
|
|
849
|
+
'ELEMENT NAMES ARE NOW DISTINCT. Five editor elements previously shared `name: "bulkEmail"` across five different bind paths. Visibility is keyed on `name` (`W/component/workflow-diagram/function/getSectionElementsForWorkflowStep.ts:41`) and the required marker is a union of name and bind path (`:145-153`), so all five appeared and were marked required together — the editor could not express per-key requiredness for this step type. Each control now has its own name, which is what makes the conditional rules above renderable.',
|
|
813
850
|
],
|
|
814
851
|
},
|
|
815
852
|
/* ====================================================================== */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ngx-t-workflow-typings",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"description": "Typings and interfaces for the ngx-t-workflows library.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typings",
|
|
@@ -42,14 +42,14 @@
|
|
|
42
42
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"ngx-t-forms-types": ">=0.0.
|
|
45
|
+
"ngx-t-forms-types": ">=0.0.29",
|
|
46
46
|
"rxjs": ">=7.8.0"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"joi": "^18.0.2"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"ngx-t-forms-types": "^0.0.
|
|
52
|
+
"ngx-t-forms-types": "^0.0.29",
|
|
53
53
|
"rimraf": "^6.1.3",
|
|
54
54
|
"typescript": "^5.9.3"
|
|
55
55
|
}
|