@nifrajs/testing 1.11.0 → 1.12.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.
- package/README.md +64 -0
- package/dist/certification.d.ts +181 -0
- package/dist/certification.d.ts.map +1 -0
- package/dist/certification.js +483 -0
- package/dist/certification.js.map +1 -0
- package/dist/failure-lab.d.ts +133 -0
- package/dist/failure-lab.d.ts.map +1 -0
- package/dist/failure-lab.js +207 -0
- package/dist/failure-lab.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +9 -4
- package/src/certification.ts +669 -0
- package/src/failure-lab.ts +356 -0
- package/src/index.ts +39 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic durable-failure laboratory.
|
|
3
|
+
*
|
|
4
|
+
* The controller is an off-hot-path port: tests place named checkpoints around real adapters and a
|
|
5
|
+
* replayable schedule injects crashes, duplicate/reordered delivery, virtual delay, deadline expiry,
|
|
6
|
+
* lost provider replies, or checkpoint contention. Evidence contains tokens only - never payloads,
|
|
7
|
+
* provider results, exception messages, or stacks.
|
|
8
|
+
*/
|
|
9
|
+
export class FailureInjectedError extends Error {
|
|
10
|
+
kind;
|
|
11
|
+
point;
|
|
12
|
+
occurrence;
|
|
13
|
+
name = "FailureInjectedError";
|
|
14
|
+
constructor(kind, point, occurrence) {
|
|
15
|
+
super(`failure laboratory injected ${kind} at ${point}#${occurrence}`);
|
|
16
|
+
this.kind = kind;
|
|
17
|
+
this.point = point;
|
|
18
|
+
this.occurrence = occurrence;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const DEFAULT_SEED = 0x46_41_49_4c;
|
|
22
|
+
const MAX_DIRECTIVES = 128;
|
|
23
|
+
const MAX_OCCURRENCE = 10_000;
|
|
24
|
+
const MAX_COPIES = 10;
|
|
25
|
+
const MAX_DELAY_MS = 24 * 60 * 60_000;
|
|
26
|
+
const POINT = /^[a-z][a-z0-9._:-]{0,127}$/;
|
|
27
|
+
const SCENARIO = /^[a-z][a-z0-9._-]{0,127}$/;
|
|
28
|
+
const integerIn = (value, min, max, label) => {
|
|
29
|
+
if (!Number.isSafeInteger(value) || value < min || value > max) {
|
|
30
|
+
throw new RangeError(`failure laboratory: ${label} must be an integer from ${min} to ${max}`);
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
};
|
|
34
|
+
const pointOf = (value) => {
|
|
35
|
+
if (!POINT.test(value)) {
|
|
36
|
+
throw new TypeError(`failure laboratory: invalid failure point ${JSON.stringify(value)}`);
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
};
|
|
40
|
+
const normalizeSeed = (seed) => Number.isFinite(seed) ? Math.trunc(seed) >>> 0 : DEFAULT_SEED;
|
|
41
|
+
const hash = (value) => {
|
|
42
|
+
let result = 2_166_136_261;
|
|
43
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
44
|
+
result ^= value.charCodeAt(index);
|
|
45
|
+
result = Math.imul(result, 16_777_619);
|
|
46
|
+
}
|
|
47
|
+
return result >>> 0;
|
|
48
|
+
};
|
|
49
|
+
function normalizeSchedule(schedule) {
|
|
50
|
+
if (!Array.isArray(schedule) || schedule.length > MAX_DIRECTIVES) {
|
|
51
|
+
throw new RangeError(`failure laboratory: schedule cannot exceed ${MAX_DIRECTIVES} directives`);
|
|
52
|
+
}
|
|
53
|
+
const seen = new Set();
|
|
54
|
+
return Object.freeze(schedule.map((directive) => {
|
|
55
|
+
const point = pointOf(directive.point);
|
|
56
|
+
const occurrence = integerIn(directive.occurrence ?? 1, 1, MAX_OCCURRENCE, "occurrence");
|
|
57
|
+
const identity = `${directive.kind}\n${point}\n${occurrence}`;
|
|
58
|
+
if (seen.has(identity)) {
|
|
59
|
+
throw new Error(`failure laboratory: duplicate directive ${directive.kind} at ${point}#${occurrence}`);
|
|
60
|
+
}
|
|
61
|
+
seen.add(identity);
|
|
62
|
+
if (directive.kind === "duplicate-delivery") {
|
|
63
|
+
return Object.freeze({
|
|
64
|
+
kind: directive.kind,
|
|
65
|
+
point,
|
|
66
|
+
occurrence,
|
|
67
|
+
copies: integerIn(directive.copies ?? 2, 2, MAX_COPIES, "copies"),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (directive.kind === "delay") {
|
|
71
|
+
return Object.freeze({
|
|
72
|
+
kind: directive.kind,
|
|
73
|
+
point,
|
|
74
|
+
occurrence,
|
|
75
|
+
delayMs: integerIn(directive.delayMs, 1, MAX_DELAY_MS, "delayMs"),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return Object.freeze({ kind: directive.kind, point, occurrence });
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
/** Build one isolated deterministic controller. Construct a fresh lab for every replay. */
|
|
82
|
+
export function createFailureLab(options) {
|
|
83
|
+
const seed = normalizeSeed(options.seed);
|
|
84
|
+
const schedule = normalizeSchedule(options.schedule);
|
|
85
|
+
let virtualTimeMs = options.startTimeMs ?? 0;
|
|
86
|
+
if (!Number.isSafeInteger(virtualTimeMs) || virtualTimeMs < 0) {
|
|
87
|
+
throw new RangeError("failure laboratory: startTimeMs must be a non-negative safe integer");
|
|
88
|
+
}
|
|
89
|
+
const counts = new Map();
|
|
90
|
+
const emitted = [];
|
|
91
|
+
let sequence = 0;
|
|
92
|
+
const directives = (point, kinds) => {
|
|
93
|
+
pointOf(point);
|
|
94
|
+
const occurrences = new Map();
|
|
95
|
+
for (const kind of kinds) {
|
|
96
|
+
const key = `${kind}\n${point}`;
|
|
97
|
+
const occurrence = (counts.get(key) ?? 0) + 1;
|
|
98
|
+
counts.set(key, occurrence);
|
|
99
|
+
occurrences.set(kind, occurrence);
|
|
100
|
+
}
|
|
101
|
+
return schedule.filter((directive) => directive.point === point && occurrences.get(directive.kind) === directive.occurrence);
|
|
102
|
+
};
|
|
103
|
+
const emit = (directive) => {
|
|
104
|
+
emitted.push(Object.freeze({
|
|
105
|
+
sequence: ++sequence,
|
|
106
|
+
kind: directive.kind,
|
|
107
|
+
point: directive.point,
|
|
108
|
+
occurrence: directive.occurrence,
|
|
109
|
+
virtualTimeMs,
|
|
110
|
+
}));
|
|
111
|
+
};
|
|
112
|
+
const lab = {
|
|
113
|
+
checkpoint(point) {
|
|
114
|
+
for (const directive of directives(point, ["delay", "crash"])) {
|
|
115
|
+
if (directive.kind === "delay")
|
|
116
|
+
virtualTimeMs += directive.delayMs;
|
|
117
|
+
emit(directive);
|
|
118
|
+
if (directive.kind === "crash") {
|
|
119
|
+
throw new FailureInjectedError("crash", point, directive.occurrence);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
deliveries(point, values) {
|
|
124
|
+
let output = [...values];
|
|
125
|
+
for (const directive of directives(point, ["duplicate-delivery", "reorder-events"])) {
|
|
126
|
+
if (directive.kind === "duplicate-delivery") {
|
|
127
|
+
output = output.flatMap((value) => Array.from({ length: directive.copies }, () => value));
|
|
128
|
+
}
|
|
129
|
+
else if (directive.kind === "reorder-events" && output.length > 1) {
|
|
130
|
+
const offset = 1 + (hash(`${seed}:${point}:${directive.occurrence}`) % (output.length - 1));
|
|
131
|
+
output = [...output.slice(offset), ...output.slice(0, offset)];
|
|
132
|
+
}
|
|
133
|
+
emit(directive);
|
|
134
|
+
}
|
|
135
|
+
return Object.freeze(output);
|
|
136
|
+
},
|
|
137
|
+
async provider(point, operation) {
|
|
138
|
+
pointOf(point);
|
|
139
|
+
const result = await operation();
|
|
140
|
+
for (const directive of directives(point, ["lose-provider-reply"])) {
|
|
141
|
+
emit(directive);
|
|
142
|
+
throw new FailureInjectedError("lose-provider-reply", point, directive.occurrence);
|
|
143
|
+
}
|
|
144
|
+
return result;
|
|
145
|
+
},
|
|
146
|
+
remaining(point, remainingMs) {
|
|
147
|
+
if (!Number.isFinite(remainingMs)) {
|
|
148
|
+
throw new TypeError("failure laboratory: remainingMs must be finite");
|
|
149
|
+
}
|
|
150
|
+
const remaining = Math.max(0, remainingMs);
|
|
151
|
+
const injected = directives(point, ["expire-budget"]);
|
|
152
|
+
for (const directive of injected)
|
|
153
|
+
emit(directive);
|
|
154
|
+
return injected.length > 0 ? 0 : remaining;
|
|
155
|
+
},
|
|
156
|
+
checkpointContended(point) {
|
|
157
|
+
const injected = directives(point, ["contend-checkpoint"]);
|
|
158
|
+
for (const directive of injected)
|
|
159
|
+
emit(directive);
|
|
160
|
+
return injected.length > 0;
|
|
161
|
+
},
|
|
162
|
+
now: () => virtualTimeMs,
|
|
163
|
+
evidence: () => Object.freeze([...emitted]),
|
|
164
|
+
replay: () => Object.freeze({ seed, schedule }),
|
|
165
|
+
};
|
|
166
|
+
return Object.freeze(lab);
|
|
167
|
+
}
|
|
168
|
+
/** Run one scenario and evaluate its post-failure invariant without leaking its result or error text. */
|
|
169
|
+
export async function runFailureScenario(scenario, options) {
|
|
170
|
+
if (!SCENARIO.test(scenario.name)) {
|
|
171
|
+
throw new TypeError(`failure laboratory: invalid scenario name ${JSON.stringify(scenario.name)}`);
|
|
172
|
+
}
|
|
173
|
+
const lab = createFailureLab(options);
|
|
174
|
+
let result;
|
|
175
|
+
let error;
|
|
176
|
+
try {
|
|
177
|
+
result = await scenario.execute(lab);
|
|
178
|
+
}
|
|
179
|
+
catch (caught) {
|
|
180
|
+
error = caught;
|
|
181
|
+
}
|
|
182
|
+
let ok = false;
|
|
183
|
+
try {
|
|
184
|
+
ok =
|
|
185
|
+
(await scenario.verify({
|
|
186
|
+
lab,
|
|
187
|
+
...(error === undefined ? { result: result } : { error }),
|
|
188
|
+
})) === true;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
ok = false;
|
|
192
|
+
}
|
|
193
|
+
const errorSummary = error === undefined
|
|
194
|
+
? undefined
|
|
195
|
+
: Object.freeze({
|
|
196
|
+
name: error instanceof Error ? error.name : "NonErrorThrown",
|
|
197
|
+
...(error instanceof FailureInjectedError ? { kind: error.kind } : {}),
|
|
198
|
+
});
|
|
199
|
+
return Object.freeze({
|
|
200
|
+
name: scenario.name,
|
|
201
|
+
ok,
|
|
202
|
+
replay: lab.replay(),
|
|
203
|
+
evidence: lab.evidence(),
|
|
204
|
+
...(errorSummary === undefined ? {} : { error: errorSummary }),
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=failure-lab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure-lab.js","sourceRoot":"","sources":["../src/failure-lab.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* const { client, cookies } = testSession<typeof app>(app)
|
|
9
9
|
*/
|
|
10
10
|
export { AdversarialContractError, type AdversarialContractOptions, type AdversarialContractReport, type AdversarialContractResult, assertAdversarialContract, type ContractCaseContext, type ContractCaseKind, type ContractCoverageGap, type ContractCoverageGapCode, type ContractReplay, type ContractRuntime, type ContractTarget, type ContractTestApp, type ContractWitness, runAdversarialContract, } from "./adversarial.js";
|
|
11
|
+
export { AdapterCertificationError, type AdapterCertificationProfile, type AdapterCertificationReport, assertAdapterCertification, type CertifiableCacheEntry, type CertifiableCacheStore, type CertifiableDomainEvent, type CertifiableEventDeliveryAdapter, type CertifiableEventRecord, type CertifiableJobStore, type CertifiableRuntimeAdapter, type CertifiableRuntimeServer, type CertifiableStorageAdapter, type CertificationCapabilityEvidence, type CertificationCheck, type CertificationCheckEvidence, cacheStoreCertificationProfile, certifyAdapter, defineCertificationProfile, eventDeliveryCertificationProfile, jobStoreCertificationProfile, runtimeAdapterCertificationProfile, storageAdapterCertificationProfile, verifyAdapterCertification, } from "./certification.js";
|
|
11
12
|
export { type CookieJar, cookieJar } from "./cookies.js";
|
|
13
|
+
export { createFailureLab, type FailureDirective, type FailureEvidence, FailureInjectedError, type FailureKind, type FailureLab, type FailureLabOptions, type FailureReplay, type FailureScenario, type FailureScenarioReport, runFailureScenario, } from "./failure-lab.js";
|
|
12
14
|
export { assertIncidentReplays, type CapturedRequest, type CapturedRequestInput, type CaptureIncidentOptions, captureIncident, type GenerateRegressionTestOptions, generateRegressionTest, type IncidentCapsule, IncidentReplayError, type IncidentReplayResult, type ReplayIncidentOptions, redactForEmission, replayIncident, shapeOf, } from "./incident.js";
|
|
13
15
|
export { type AppLike, type TestSession, type TestSessionOptions, testSession } from "./session.js";
|
|
14
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,wBAAwB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,eAAe,EACf,KAAK,6BAA6B,EAClC,sBAAsB,EACtB,KAAK,eAAe,EACpB,mBAAmB,EACnB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,iBAAiB,EACjB,cAAc,EACd,OAAO,GACR,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,wBAAwB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,yBAAyB,EACzB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,EACpC,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,+BAA+B,EACpC,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,8BAA8B,EAC9B,cAAc,EACd,0BAA0B,EAC1B,iCAAiC,EACjC,4BAA4B,EAC5B,kCAAkC,EAClC,kCAAkC,EAClC,0BAA0B,GAC3B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EACL,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,oBAAoB,EACpB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,eAAe,EACf,KAAK,6BAA6B,EAClC,sBAAsB,EACtB,KAAK,eAAe,EACpB,mBAAmB,EACnB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,iBAAiB,EACjB,cAAc,EACd,OAAO,GACR,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* const { client, cookies } = testSession<typeof app>(app)
|
|
9
9
|
*/
|
|
10
10
|
export { AdversarialContractError, assertAdversarialContract, runAdversarialContract, } from "./adversarial.js";
|
|
11
|
+
export { AdapterCertificationError, assertAdapterCertification, cacheStoreCertificationProfile, certifyAdapter, defineCertificationProfile, eventDeliveryCertificationProfile, jobStoreCertificationProfile, runtimeAdapterCertificationProfile, storageAdapterCertificationProfile, verifyAdapterCertification, } from "./certification.js";
|
|
11
12
|
export { cookieJar } from "./cookies.js";
|
|
13
|
+
export { createFailureLab, FailureInjectedError, runFailureScenario, } from "./failure-lab.js";
|
|
12
14
|
export { assertIncidentReplays, captureIncident, generateRegressionTest, IncidentReplayError, redactForEmission, replayIncident, shapeOf, } from "./incident.js";
|
|
13
15
|
export { testSession } from "./session.js";
|
|
14
16
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,wBAAwB,EAIxB,yBAAyB,EAUzB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAkB,SAAS,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EACL,qBAAqB,EAIrB,eAAe,EAEf,sBAAsB,EAEtB,mBAAmB,EAGnB,iBAAiB,EACjB,cAAc,EACd,OAAO,GACR,MAAM,eAAe,CAAA;AACtB,OAAO,EAA2D,WAAW,EAAE,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,wBAAwB,EAIxB,yBAAyB,EAUzB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,yBAAyB,EAGzB,0BAA0B,EAa1B,8BAA8B,EAC9B,cAAc,EACd,0BAA0B,EAC1B,iCAAiC,EACjC,4BAA4B,EAC5B,kCAAkC,EAClC,kCAAkC,EAClC,0BAA0B,GAC3B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAkB,SAAS,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EACL,gBAAgB,EAGhB,oBAAoB,EAOpB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,qBAAqB,EAIrB,eAAe,EAEf,sBAAsB,EAEtB,mBAAmB,EAGnB,iBAAiB,EACjB,cAAc,EACd,OAAO,GACR,MAAM,eAAe,CAAA;AACtB,OAAO,EAA2D,WAAW,EAAE,MAAM,cAAc,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nifrajs/testing",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Contract-derived adversarial tests, runtime-matrix response conformance, and cookie-aware in-process sessions for Nifra apps.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -20,6 +20,11 @@
|
|
|
20
20
|
"bun": "./src/index.ts",
|
|
21
21
|
"types": "./dist/index.d.ts",
|
|
22
22
|
"default": "./dist/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./certification": {
|
|
25
|
+
"bun": "./src/certification.ts",
|
|
26
|
+
"types": "./dist/certification.d.ts",
|
|
27
|
+
"default": "./dist/certification.js"
|
|
23
28
|
}
|
|
24
29
|
},
|
|
25
30
|
"files": [
|
|
@@ -32,9 +37,9 @@
|
|
|
32
37
|
},
|
|
33
38
|
"license": "MIT",
|
|
34
39
|
"dependencies": {
|
|
35
|
-
"@nifrajs/client": "1.
|
|
36
|
-
"@nifrajs/core": "1.
|
|
37
|
-
"@nifrajs/mock": "1.
|
|
40
|
+
"@nifrajs/client": "1.12.0",
|
|
41
|
+
"@nifrajs/core": "1.12.0",
|
|
42
|
+
"@nifrajs/mock": "1.12.0"
|
|
38
43
|
},
|
|
39
44
|
"publishConfig": {
|
|
40
45
|
"access": "public"
|