@nfcard/validation 0.4.0 → 0.6.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/dist/index.d.ts +3061 -10
- package/dist/index.js +0 -0
- package/package.json +2 -2
- package/src/index.test.ts +101 -2
- package/src/index.ts +0 -0
package/dist/index.js
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nfcard/validation",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Shared Zod validation schemas for the NFCard product family.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"zod": "^3.24.0",
|
|
20
|
-
"@nfcard/types": "0.
|
|
20
|
+
"@nfcard/types": "0.5.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"tsup": "^8.0.0"
|
package/src/index.test.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import {
|
|
3
|
+
cardDesignSchema,
|
|
3
4
|
cardElementsSchema,
|
|
4
5
|
comboIdSchema,
|
|
5
6
|
configurationCreateSchema,
|
|
@@ -482,12 +483,21 @@ describe('profileCreateSchema', () => {
|
|
|
482
483
|
expect(r.success).toBe(false);
|
|
483
484
|
});
|
|
484
485
|
|
|
485
|
-
it('
|
|
486
|
+
it('accepts a missing label (NFCARD-128 — blank profile, label set later in the editor)', () => {
|
|
486
487
|
const r = profileCreateSchema.safeParse({
|
|
487
488
|
userData: { ...validUserData, email: '' },
|
|
488
489
|
digitalConfig: validDigitalConfig,
|
|
489
490
|
});
|
|
490
|
-
expect(r.success).toBe(
|
|
491
|
+
expect(r.success).toBe(true);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
it('accepts an empty label', () => {
|
|
495
|
+
const r = profileCreateSchema.safeParse({
|
|
496
|
+
label: '',
|
|
497
|
+
userData: { ...validUserData, email: '' },
|
|
498
|
+
digitalConfig: validDigitalConfig,
|
|
499
|
+
});
|
|
500
|
+
expect(r.success).toBe(true);
|
|
491
501
|
});
|
|
492
502
|
});
|
|
493
503
|
|
|
@@ -676,3 +686,92 @@ describe('hubConfigSchema', () => {
|
|
|
676
686
|
expect(hubConfigSchema.safeParse({ avatarUrl: '' }).success).toBe(true);
|
|
677
687
|
});
|
|
678
688
|
});
|
|
689
|
+
|
|
690
|
+
// ── cardDesign (cardgen interop, FOXHOLE-810) ───────────────────
|
|
691
|
+
|
|
692
|
+
const validCardDesign = {
|
|
693
|
+
material: '3dprint_standard' as const,
|
|
694
|
+
designType: 'custom' as const,
|
|
695
|
+
thicknessMm: 1.8,
|
|
696
|
+
pattern: {
|
|
697
|
+
family: 'spiral' as const,
|
|
698
|
+
variant: 'pulse' as const,
|
|
699
|
+
density: 0.55,
|
|
700
|
+
holeMinMm: 0.6,
|
|
701
|
+
holeMaxMm: 2.0,
|
|
702
|
+
intensity: 0.5,
|
|
703
|
+
cellShape: 0 as const,
|
|
704
|
+
cellRotationDeg: 0,
|
|
705
|
+
chipShape: 0 as const,
|
|
706
|
+
chipRotationDeg: 0,
|
|
707
|
+
},
|
|
708
|
+
layout: { chipAnchor: { col: 0 as const, row: 1 as const } },
|
|
709
|
+
filaments: { background: '#F2F1ED', text: '#1A1A1A', accent: '#3FA34D' },
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
const valid3dPhysicalConfig = {
|
|
713
|
+
material: '3dprint_standard' as const,
|
|
714
|
+
colour: '#F2F1ED',
|
|
715
|
+
comboId: 'A1' as const,
|
|
716
|
+
frontElements: validCardElements,
|
|
717
|
+
backElements: validCardElements,
|
|
718
|
+
};
|
|
719
|
+
|
|
720
|
+
describe('cardDesignSchema', () => {
|
|
721
|
+
it('accepts a valid 3D card design', () => {
|
|
722
|
+
expect(cardDesignSchema.safeParse(validCardDesign).success).toBe(true);
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
it('accepts a solid card (pattern: null)', () => {
|
|
726
|
+
expect(
|
|
727
|
+
cardDesignSchema.safeParse({ ...validCardDesign, pattern: null }).success,
|
|
728
|
+
).toBe(true);
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it('rejects plastic (cardgen has no FDM mesh for PVC)', () => {
|
|
732
|
+
expect(
|
|
733
|
+
cardDesignSchema.safeParse({ ...validCardDesign, material: 'plastic' }).success,
|
|
734
|
+
).toBe(false);
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
it('rejects holeMin > holeMax', () => {
|
|
738
|
+
const bad = { ...validCardDesign, pattern: { ...validCardDesign.pattern, holeMinMm: 3, holeMaxMm: 1 } };
|
|
739
|
+
expect(cardDesignSchema.safeParse(bad).success).toBe(false);
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
it('rejects an unknown pattern family', () => {
|
|
743
|
+
const bad = { ...validCardDesign, pattern: { ...validCardDesign.pattern, family: 'mosaic' } };
|
|
744
|
+
expect(cardDesignSchema.safeParse(bad).success).toBe(false);
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
it('rejects a chip anchor outside 0..2', () => {
|
|
748
|
+
const bad = { ...validCardDesign, layout: { chipAnchor: { col: 3, row: 1 } } };
|
|
749
|
+
expect(cardDesignSchema.safeParse(bad).success).toBe(false);
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
it('rejects a non-hex filament', () => {
|
|
753
|
+
const bad = { ...validCardDesign, filaments: { ...validCardDesign.filaments, accent: 'green' } };
|
|
754
|
+
expect(cardDesignSchema.safeParse(bad).success).toBe(false);
|
|
755
|
+
});
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
describe('physicalConfig.cardDesign (nested, not stripped)', () => {
|
|
759
|
+
it('accepts a 3D physicalConfig carrying a matching cardDesign', () => {
|
|
760
|
+
const res = physicalConfigSchema.safeParse({ ...valid3dPhysicalConfig, cardDesign: validCardDesign });
|
|
761
|
+
expect(res.success).toBe(true);
|
|
762
|
+
// and it survives (not stripped):
|
|
763
|
+
if (res.success) expect(res.data.cardDesign?.material).toBe('3dprint_standard');
|
|
764
|
+
});
|
|
765
|
+
|
|
766
|
+
it('rejects a cardDesign whose material disagrees with the card', () => {
|
|
767
|
+
const res = physicalConfigSchema.safeParse({
|
|
768
|
+
...valid3dPhysicalConfig,
|
|
769
|
+
cardDesign: { ...validCardDesign, material: 'metal' },
|
|
770
|
+
});
|
|
771
|
+
expect(res.success).toBe(false);
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
it('still accepts a legacy physicalConfig with no cardDesign', () => {
|
|
775
|
+
expect(physicalConfigSchema.safeParse(validPhysicalConfig).success).toBe(true);
|
|
776
|
+
});
|
|
777
|
+
});
|
package/src/index.ts
CHANGED
|
Binary file
|