@adminiumjs/add-on-contracts 0.2.1
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/LICENSE +661 -0
- package/dist/add-on-block.d.ts +155 -0
- package/dist/add-on-block.d.ts.map +1 -0
- package/dist/add-on-block.js +124 -0
- package/dist/add-on-block.js.map +1 -0
- package/dist/artwork-source.d.ts +71 -0
- package/dist/artwork-source.d.ts.map +1 -0
- package/dist/artwork-source.js +35 -0
- package/dist/artwork-source.js.map +1 -0
- package/dist/common.d.ts +19 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +15 -0
- package/dist/common.js.map +1 -0
- package/dist/contracts.d.ts +42 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +40 -0
- package/dist/contracts.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/product-personalizer.d.ts +205 -0
- package/dist/product-personalizer.d.ts.map +1 -0
- package/dist/product-personalizer.js +64 -0
- package/dist/product-personalizer.js.map +1 -0
- package/dist/shipping-carrier.d.ts +119 -0
- package/dist/shipping-carrier.d.ts.map +1 -0
- package/dist/shipping-carrier.js +74 -0
- package/dist/shipping-carrier.js.map +1 -0
- package/dist/slots.d.ts +119 -0
- package/dist/slots.d.ts.map +1 -0
- package/dist/slots.js +124 -0
- package/dist/slots.js.map +1 -0
- package/dist/testing/index.d.ts +48 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +177 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +40 -0
package/dist/slots.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slot registry v1 — CLOSED (24-marketplace-wave-4.md §5.4, eleven slots).
|
|
3
|
+
*
|
|
4
|
+
* A slot is a named place in a host surface, its payload, and its fill rule.
|
|
5
|
+
* The registry is closed for the same reason the widget-id vocabulary is: an
|
|
6
|
+
* open-ended extension point cannot be reviewed, translated, or kept working
|
|
7
|
+
* across host versions. Adding a slot is a spec change with a version bump on
|
|
8
|
+
* this package — never a pull request against an app.
|
|
9
|
+
*
|
|
10
|
+
* Every slot here is filled by something built in wave 4. A slot nobody fills
|
|
11
|
+
* is a guess about a future add-on, which is why an earlier draft's twelfth
|
|
12
|
+
* (`job.timeline.entries`) is absent.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
/** Which persona's surface the slot lives in. */
|
|
16
|
+
export const SLOT_SURFACES = ['customer', 'staff', 'admin', 'both'];
|
|
17
|
+
/**
|
|
18
|
+
* `multi` renders every enabled fill ordered by `order` then by add-on key, so
|
|
19
|
+
* the order is stable and does not depend on install sequence. `single` takes
|
|
20
|
+
* the lowest `order` and records a SLOT_CONFLICT warning naming the add-on that
|
|
21
|
+
* lost — never a silent override.
|
|
22
|
+
*/
|
|
23
|
+
export const SLOT_FILLS = ['multi', 'single', 'per-add-on'];
|
|
24
|
+
export const SLOT_REGISTRY = [
|
|
25
|
+
{
|
|
26
|
+
id: 'artwork.sources',
|
|
27
|
+
surface: 'customer',
|
|
28
|
+
fill: 'multi',
|
|
29
|
+
payload: 'the configured job: product, trim size mm, bleed mm, sides, quantity',
|
|
30
|
+
renders: 'an action tile, and a flow resolving to an ArtworkRef',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'checkout.delivery.methods',
|
|
34
|
+
surface: 'customer',
|
|
35
|
+
fill: 'multi',
|
|
36
|
+
payload: 'parcel estimate + destination',
|
|
37
|
+
renders: 'selectable rate rows',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 'order.dispatch.panel',
|
|
41
|
+
surface: 'customer',
|
|
42
|
+
fill: 'single',
|
|
43
|
+
payload: 'the dispatch record',
|
|
44
|
+
renders: 'a read-only tracking view',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
// Renamed from `job.dispatch.actions` on 2026-08-05 (D21): the id names a
|
|
48
|
+
// surface, not the print shop's domain, so a second host can fill it.
|
|
49
|
+
id: 'order.dispatch.actions',
|
|
50
|
+
surface: 'staff',
|
|
51
|
+
fill: 'multi',
|
|
52
|
+
payload: 'the order + its parcel estimate',
|
|
53
|
+
renders: 'an action and its result panel',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'settings.add-on.panel',
|
|
57
|
+
surface: 'admin',
|
|
58
|
+
fill: 'per-add-on',
|
|
59
|
+
// The values, a way to save a change to them, and the host's own catalogue
|
|
60
|
+
// as representative records. The last of those is what lets an add-on say
|
|
61
|
+
// something about the host's data — default parcel weights, say — without
|
|
62
|
+
// the host computing it, which is a thing only the add-on knows how to do.
|
|
63
|
+
payload: "the add-on's settings values, a patch handle, and sample records",
|
|
64
|
+
renders: 'a settings form, its controls and the sentence under each',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'nav.add-on.routes',
|
|
68
|
+
surface: 'both',
|
|
69
|
+
fill: 'multi',
|
|
70
|
+
payload: '—',
|
|
71
|
+
renders: 'full-screen routes under /add-ons/<key>/*',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'product.options.personalize',
|
|
75
|
+
surface: 'customer',
|
|
76
|
+
fill: 'single',
|
|
77
|
+
payload: 'the product + its variant and quantity',
|
|
78
|
+
renders: 'a personalization surface resolving to a Personalization',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'cart.line.preview',
|
|
82
|
+
surface: 'customer',
|
|
83
|
+
fill: 'multi',
|
|
84
|
+
payload: 'one basket / order line',
|
|
85
|
+
renders: 'a thumbnail and the values in words',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: 'product.admin.panel',
|
|
89
|
+
surface: 'staff',
|
|
90
|
+
fill: 'multi',
|
|
91
|
+
payload: 'the product record',
|
|
92
|
+
renders: 'a setup panel (zones, constraints, sample)',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: 'order.line.actions',
|
|
96
|
+
surface: 'staff',
|
|
97
|
+
fill: 'multi',
|
|
98
|
+
payload: 'one order line',
|
|
99
|
+
renders: 'per-line actions and their output',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
// The only slot whose host is Adminium itself rather than an example app,
|
|
103
|
+
// which is why its payload carries a table name.
|
|
104
|
+
id: 'record.editor.panel',
|
|
105
|
+
surface: 'admin',
|
|
106
|
+
fill: 'multi',
|
|
107
|
+
payload: 'the table name, the record, and write handles',
|
|
108
|
+
renders: "a panel inside the generated dashboard's record editor",
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
export const SLOT_IDS = SLOT_REGISTRY.map((s) => s.id);
|
|
112
|
+
export const slotIdSchema = z.enum(SLOT_IDS);
|
|
113
|
+
const BY_ID = new Map(SLOT_REGISTRY.map((s) => [s.id, s]));
|
|
114
|
+
export function isSlotId(v) {
|
|
115
|
+
return typeof v === 'string' && BY_ID.has(v);
|
|
116
|
+
}
|
|
117
|
+
export function slotDefinition(id) {
|
|
118
|
+
const found = BY_ID.get(id);
|
|
119
|
+
/* c8 ignore next */
|
|
120
|
+
if (found === undefined)
|
|
121
|
+
throw new Error(`unknown slot id: ${id}`);
|
|
122
|
+
return found;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=slots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots.js","sourceRoot":"","sources":["../src/slots.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conformance suites — part of the contract, not a courtesy (24 §5.5, D9).
|
|
3
|
+
*
|
|
4
|
+
* Every provider implementation runs the suite for the contract it claims, in
|
|
5
|
+
* its own repo, against its own transport. The claim "the next carrier is a
|
|
6
|
+
* copy of this one" rests entirely on `describeShippingCarrier` existing and
|
|
7
|
+
* passing against both the demo and the real transport; without it the claim is
|
|
8
|
+
* an assertion in a document.
|
|
9
|
+
*
|
|
10
|
+
* This is the ONLY entry point in the package that may import vitest — the
|
|
11
|
+
* types-and-validators half stays free of test and `node:` imports so the
|
|
12
|
+
* storefront, the SPAs and Electron can all use it (01 §3).
|
|
13
|
+
*/
|
|
14
|
+
import { type ArtworkSource, type JobSpec } from '../artwork-source.js';
|
|
15
|
+
import { type Personalization, type ProductPersonalizer, type ProductRef, type Template } from '../product-personalizer.js';
|
|
16
|
+
import { type Address, type OrderRef, type Parcel, type ShippingCarrier } from '../shipping-carrier.js';
|
|
17
|
+
export interface ArtworkSourceFixtures {
|
|
18
|
+
/** A job the source can serve. */
|
|
19
|
+
job: JobSpec;
|
|
20
|
+
/** A job it cannot — it must decline WITH A REASON rather than throw. */
|
|
21
|
+
unavailableJob?: JobSpec;
|
|
22
|
+
/**
|
|
23
|
+
* Drives `start()` to its cancel path. Implementations that cannot be
|
|
24
|
+
* cancelled headlessly may omit it; the cancel assertion is then skipped.
|
|
25
|
+
*/
|
|
26
|
+
cancel?: () => void;
|
|
27
|
+
}
|
|
28
|
+
export declare function describeArtworkSource(impl: ArtworkSource, fixtures: ArtworkSourceFixtures): void;
|
|
29
|
+
export interface ShippingCarrierFixtures {
|
|
30
|
+
parcel: Parcel;
|
|
31
|
+
from: Address;
|
|
32
|
+
to: Address;
|
|
33
|
+
/** An address the carrier refuses — the failure path must be demonstrable. */
|
|
34
|
+
rejectedTo: Address;
|
|
35
|
+
order: OrderRef;
|
|
36
|
+
}
|
|
37
|
+
export declare function describeShippingCarrier(impl: ShippingCarrier, fixtures: ShippingCarrierFixtures): void;
|
|
38
|
+
export interface ProductPersonalizerFixtures {
|
|
39
|
+
product: ProductRef;
|
|
40
|
+
template: Template;
|
|
41
|
+
/** Values that fit every zone. */
|
|
42
|
+
valid: Personalization;
|
|
43
|
+
/** Values that overrun at least one zone — must yield a numbered remedy. */
|
|
44
|
+
overrun: Personalization;
|
|
45
|
+
angle: string;
|
|
46
|
+
}
|
|
47
|
+
export declare function describeProductPersonalizer(impl: ProductPersonalizer, fixtures: ProductPersonalizerFixtures): void;
|
|
48
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAoB,KAAK,aAAa,EAAE,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,QAAQ,EACd,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAKL,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,MAAM,EACX,KAAK,eAAe,EACrB,MAAM,wBAAwB,CAAC;AAIhC,MAAM,WAAW,qBAAqB;IACpC,kCAAkC;IAClC,GAAG,EAAE,OAAO,CAAC;IACb,yEAAyE;IACzE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,qBAAqB,GAC9B,IAAI,CA2CN;AAID,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;IACZ,8EAA8E;IAC9E,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,eAAe,EACrB,QAAQ,EAAE,uBAAuB,GAChC,IAAI,CAkFN;AAID,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,UAAU,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,kCAAkC;IAClC,KAAK,EAAE,eAAe,CAAC;IACvB,4EAA4E;IAC5E,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,mBAAmB,EACzB,QAAQ,EAAE,2BAA2B,GACpC,IAAI,CAqDN"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conformance suites — part of the contract, not a courtesy (24 §5.5, D9).
|
|
3
|
+
*
|
|
4
|
+
* Every provider implementation runs the suite for the contract it claims, in
|
|
5
|
+
* its own repo, against its own transport. The claim "the next carrier is a
|
|
6
|
+
* copy of this one" rests entirely on `describeShippingCarrier` existing and
|
|
7
|
+
* passing against both the demo and the real transport; without it the claim is
|
|
8
|
+
* an assertion in a document.
|
|
9
|
+
*
|
|
10
|
+
* This is the ONLY entry point in the package that may import vitest — the
|
|
11
|
+
* types-and-validators half stays free of test and `node:` imports so the
|
|
12
|
+
* storefront, the SPAs and Electron can all use it (01 §3).
|
|
13
|
+
*/
|
|
14
|
+
import { describe, expect, it } from 'vitest';
|
|
15
|
+
import { artworkRefSchema } from '../artwork-source.js';
|
|
16
|
+
import { personalizationSchema, } from '../product-personalizer.js';
|
|
17
|
+
import { CarrierError, rateSchema, shipmentSchema, trackEventSchema, } from '../shipping-carrier.js';
|
|
18
|
+
export function describeArtworkSource(impl, fixtures) {
|
|
19
|
+
describe(`artwork-source@1 conformance — ${impl.key}`, () => {
|
|
20
|
+
it('has a non-empty key', () => {
|
|
21
|
+
expect(impl.key).toMatch(/^[a-z][a-z0-9-]*$/);
|
|
22
|
+
});
|
|
23
|
+
it('labels itself for a job without throwing', () => {
|
|
24
|
+
const label = impl.label(fixtures.job);
|
|
25
|
+
expect(typeof label).toBe('string');
|
|
26
|
+
expect(label.length).toBeGreaterThan(0);
|
|
27
|
+
});
|
|
28
|
+
it('reports availability as data, never as an exception', () => {
|
|
29
|
+
const verdict = impl.available(fixtures.job);
|
|
30
|
+
expect(verdict.ok).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
it('declines an unservable job WITH a reason', () => {
|
|
33
|
+
if (fixtures.unavailableJob === undefined)
|
|
34
|
+
return;
|
|
35
|
+
const verdict = impl.available(fixtures.unavailableJob);
|
|
36
|
+
expect(verdict.ok).toBe(false);
|
|
37
|
+
if (!verdict.ok)
|
|
38
|
+
expect(verdict.reason.trim().length).toBeGreaterThan(0);
|
|
39
|
+
});
|
|
40
|
+
it('returns an ArtworkRef whose shape the host can check', async () => {
|
|
41
|
+
const ref = await impl.start(fixtures.job);
|
|
42
|
+
expect(ref).not.toBeNull();
|
|
43
|
+
const parsed = artworkRefSchema.safeParse(ref);
|
|
44
|
+
expect(parsed.success, JSON.stringify(parsed.error?.issues)).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
it('stamps the ref with its own key, so the host can trace the source', async () => {
|
|
47
|
+
const ref = await impl.start(fixtures.job);
|
|
48
|
+
expect(ref?.source).toBe(impl.key);
|
|
49
|
+
});
|
|
50
|
+
it('resolves to null when the customer backs out', async () => {
|
|
51
|
+
if (fixtures.cancel === undefined)
|
|
52
|
+
return;
|
|
53
|
+
const pending = impl.start(fixtures.job);
|
|
54
|
+
fixtures.cancel();
|
|
55
|
+
await expect(pending).resolves.toBeNull();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
export function describeShippingCarrier(impl, fixtures) {
|
|
60
|
+
describe(`shipping-carrier@1 conformance — ${impl.key}`, () => {
|
|
61
|
+
it('has a non-empty key', () => {
|
|
62
|
+
expect(impl.key).toMatch(/^[a-z][a-z0-9-]*$/);
|
|
63
|
+
});
|
|
64
|
+
it('quotes at least one rate, each of the declared shape', async () => {
|
|
65
|
+
const rates = await impl.quote(fixtures.parcel, fixtures.from, fixtures.to);
|
|
66
|
+
expect(rates.length).toBeGreaterThan(0);
|
|
67
|
+
for (const rate of rates) {
|
|
68
|
+
const parsed = rateSchema.safeParse(rate);
|
|
69
|
+
expect(parsed.success, JSON.stringify(parsed.error?.issues)).toBe(true);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
it('quote is side-effect free — the same call twice gives the same rates', async () => {
|
|
73
|
+
const a = await impl.quote(fixtures.parcel, fixtures.from, fixtures.to);
|
|
74
|
+
const b = await impl.quote(fixtures.parcel, fixtures.from, fixtures.to);
|
|
75
|
+
expect(b).toEqual(a);
|
|
76
|
+
});
|
|
77
|
+
it('surfaces a refusal as a typed CarrierError carrying the carrier’s own message', async () => {
|
|
78
|
+
await expect(impl.quote(fixtures.parcel, fixtures.from, fixtures.rejectedTo)).rejects.toBeInstanceOf(CarrierError);
|
|
79
|
+
try {
|
|
80
|
+
await impl.quote(fixtures.parcel, fixtures.from, fixtures.rejectedTo);
|
|
81
|
+
expect.unreachable('the rejected address should not have quoted');
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
expect(err).toBeInstanceOf(CarrierError);
|
|
85
|
+
const carrier = err;
|
|
86
|
+
expect(carrier.carrierMessage.trim().length).toBeGreaterThan(0);
|
|
87
|
+
expect(carrier.code.trim().length).toBeGreaterThan(0);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
it('books a shipment of the declared shape', async () => {
|
|
91
|
+
const [rate] = await impl.quote(fixtures.parcel, fixtures.from, fixtures.to);
|
|
92
|
+
expect(rate).toBeDefined();
|
|
93
|
+
const shipment = await impl.book(rate, fixtures.order);
|
|
94
|
+
const parsed = shipmentSchema.safeParse(shipment);
|
|
95
|
+
expect(parsed.success, JSON.stringify(parsed.error?.issues)).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
it('book is idempotent for one OrderRef', async () => {
|
|
98
|
+
const [rate] = await impl.quote(fixtures.parcel, fixtures.from, fixtures.to);
|
|
99
|
+
const first = await impl.book(rate, fixtures.order);
|
|
100
|
+
const second = await impl.book(rate, fixtures.order);
|
|
101
|
+
expect(second.id).toBe(first.id);
|
|
102
|
+
expect(second.tracking).toBe(first.tracking);
|
|
103
|
+
});
|
|
104
|
+
it('tracks a booked shipment with events of the declared shape', async () => {
|
|
105
|
+
const [rate] = await impl.quote(fixtures.parcel, fixtures.from, fixtures.to);
|
|
106
|
+
const shipment = await impl.book(rate, fixtures.order);
|
|
107
|
+
const events = await impl.track(shipment.tracking);
|
|
108
|
+
expect(events.length).toBeGreaterThan(0);
|
|
109
|
+
for (const event of events) {
|
|
110
|
+
const parsed = trackEventSchema.safeParse(event);
|
|
111
|
+
expect(parsed.success, JSON.stringify(parsed.error?.issues)).toBe(true);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
it('returns empty rather than throwing for an unknown tracking reference', async () => {
|
|
115
|
+
await expect(impl.track('no-such-reference-0000')).resolves.toEqual([]);
|
|
116
|
+
});
|
|
117
|
+
it('produces a label file for a booked shipment', async () => {
|
|
118
|
+
const [rate] = await impl.quote(fixtures.parcel, fixtures.from, fixtures.to);
|
|
119
|
+
const shipment = await impl.book(rate, fixtures.order);
|
|
120
|
+
const file = await impl.label(shipment.id);
|
|
121
|
+
expect(file.fileId.length).toBeGreaterThan(0);
|
|
122
|
+
expect(file.bytes).toBeGreaterThan(0);
|
|
123
|
+
});
|
|
124
|
+
it('cancels a booked shipment without throwing', async () => {
|
|
125
|
+
const [rate] = await impl.quote(fixtures.parcel, fixtures.from, fixtures.to);
|
|
126
|
+
const shipment = await impl.book(rate, fixtures.order);
|
|
127
|
+
await expect(impl.cancel(shipment.id)).resolves.toBeUndefined();
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
export function describeProductPersonalizer(impl, fixtures) {
|
|
132
|
+
describe(`product-personalizer@1 conformance — ${impl.key}`, () => {
|
|
133
|
+
it('has a non-empty key', () => {
|
|
134
|
+
expect(impl.key).toMatch(/^[a-z][a-z0-9-]*$/);
|
|
135
|
+
});
|
|
136
|
+
it('reports availability as data', () => {
|
|
137
|
+
expect(impl.available(fixtures.product).ok).toBe(true);
|
|
138
|
+
});
|
|
139
|
+
it('accepts a personalization of the declared shape', () => {
|
|
140
|
+
const parsed = personalizationSchema.safeParse(fixtures.valid);
|
|
141
|
+
expect(parsed.success, JSON.stringify(parsed.error?.issues)).toBe(true);
|
|
142
|
+
});
|
|
143
|
+
it('passes every zone for values that fit', () => {
|
|
144
|
+
const verdicts = impl.validate(fixtures.valid, fixtures.template);
|
|
145
|
+
expect(verdicts.every((v) => v.ok)).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
it('every failing verdict carries at least one remedy WITH a number', () => {
|
|
148
|
+
const verdicts = impl.validate(fixtures.overrun, fixtures.template);
|
|
149
|
+
const failures = verdicts.filter((v) => !v.ok);
|
|
150
|
+
expect(failures.length).toBeGreaterThan(0);
|
|
151
|
+
for (const failure of failures) {
|
|
152
|
+
if (failure.ok)
|
|
153
|
+
continue;
|
|
154
|
+
expect(failure.reason.trim().length).toBeGreaterThan(0);
|
|
155
|
+
const { setSizeMm, shortenToChars } = failure.remedies;
|
|
156
|
+
expect(typeof setSizeMm === 'number' || typeof shortenToChars === 'number').toBe(true);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
it('render is deterministic — same values and angle give the same picture', async () => {
|
|
160
|
+
const a = await impl.render(fixtures.valid, { angle: fixtures.angle, widthPx: 480 });
|
|
161
|
+
const b = await impl.render(fixtures.valid, { angle: fixtures.angle, widthPx: 480 });
|
|
162
|
+
expect(b.digest).toBe(a.digest);
|
|
163
|
+
expect(b.fileId).toBe(a.fileId);
|
|
164
|
+
});
|
|
165
|
+
it('render distinguishes different values', async () => {
|
|
166
|
+
const a = await impl.render(fixtures.valid, { angle: fixtures.angle, widthPx: 480 });
|
|
167
|
+
const b = await impl.render(fixtures.overrun, { angle: fixtures.angle, widthPx: 480 });
|
|
168
|
+
expect(b.digest).not.toBe(a.digest);
|
|
169
|
+
});
|
|
170
|
+
it('the production file carries outlines, never a font reference', async () => {
|
|
171
|
+
const file = await impl.productionFile(fixtures.valid);
|
|
172
|
+
expect(file.bytes).toBeGreaterThan(0);
|
|
173
|
+
expect(file.filename).not.toMatch(/\.(ttf|otf|woff2?)$/i);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@adminiumjs/add-on-contracts",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"license": "AGPL-3.0-only",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/MoSofi/Adminium.git",
|
|
8
|
+
"directory": "packages/add-on-contracts"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://adminium.dev",
|
|
11
|
+
"bugs": "https://github.com/MoSofi/Adminium/issues",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"description": "Add-on slot + provider-contract registries, types and conformance suites",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./testing": {
|
|
22
|
+
"types": "./dist/testing/index.d.ts",
|
|
23
|
+
"default": "./dist/testing/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"zod": "^4.4.3"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"vitest": "^3.2.4"
|
|
31
|
+
},
|
|
32
|
+
"peerDependenciesMeta": {
|
|
33
|
+
"vitest": {
|
|
34
|
+
"optional": true
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist"
|
|
39
|
+
]
|
|
40
|
+
}
|