@anuragpal02/zcl-contracts 0.2.0 → 0.3.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.
@@ -16,7 +16,25 @@ export declare const ledPanelSchema: z.ZodObject<{
16
16
  x: z.ZodNumber;
17
17
  y: z.ZodNumber;
18
18
  }, z.core.$strip>;
19
+ export declare const ledBoundsSchema: z.ZodObject<{
20
+ minX: z.ZodNumber;
21
+ minY: z.ZodNumber;
22
+ maxX: z.ZodNumber;
23
+ maxY: z.ZodNumber;
24
+ width: z.ZodNumber;
25
+ height: z.ZodNumber;
26
+ aspectRatio: z.ZodNumber;
27
+ }, z.core.$strip>;
28
+ export declare const ledPanelsSchema: z.ZodArray<z.ZodObject<{
29
+ id: z.ZodString;
30
+ name: z.ZodString;
31
+ width: z.ZodNumber;
32
+ height: z.ZodNumber;
33
+ x: z.ZodNumber;
34
+ y: z.ZodNumber;
35
+ }, z.core.$strip>>;
19
36
  export declare const ledMapSchema: z.ZodObject<{
37
+ projectId: z.ZodString;
20
38
  version: z.ZodNumber;
21
39
  panels: z.ZodArray<z.ZodObject<{
22
40
  id: z.ZodString;
@@ -26,7 +44,7 @@ export declare const ledMapSchema: z.ZodObject<{
26
44
  x: z.ZodNumber;
27
45
  y: z.ZodNumber;
28
46
  }, z.core.$strip>>;
29
- bounds: z.ZodObject<{
47
+ bounds: z.ZodNullable<z.ZodObject<{
30
48
  minX: z.ZodNumber;
31
49
  minY: z.ZodNumber;
32
50
  maxX: z.ZodNumber;
@@ -34,6 +52,44 @@ export declare const ledMapSchema: z.ZodObject<{
34
52
  width: z.ZodNumber;
35
53
  height: z.ZodNumber;
36
54
  aspectRatio: z.ZodNumber;
55
+ }, z.core.$strip>>;
56
+ createdAt: z.ZodString;
57
+ updatedAt: z.ZodString;
58
+ }, z.core.$strip>;
59
+ export declare const updateLedMapRequestSchema: z.ZodObject<{
60
+ expectedVersion: z.ZodNumber;
61
+ panels: z.ZodArray<z.ZodObject<{
62
+ id: z.ZodString;
63
+ name: z.ZodString;
64
+ width: z.ZodNumber;
65
+ height: z.ZodNumber;
66
+ x: z.ZodNumber;
67
+ y: z.ZodNumber;
68
+ }, z.core.$strip>>;
69
+ }, z.core.$strip>;
70
+ export declare const ledMapResponseSchema: z.ZodObject<{
71
+ data: z.ZodObject<{
72
+ projectId: z.ZodString;
73
+ version: z.ZodNumber;
74
+ panels: z.ZodArray<z.ZodObject<{
75
+ id: z.ZodString;
76
+ name: z.ZodString;
77
+ width: z.ZodNumber;
78
+ height: z.ZodNumber;
79
+ x: z.ZodNumber;
80
+ y: z.ZodNumber;
81
+ }, z.core.$strip>>;
82
+ bounds: z.ZodNullable<z.ZodObject<{
83
+ minX: z.ZodNumber;
84
+ minY: z.ZodNumber;
85
+ maxX: z.ZodNumber;
86
+ maxY: z.ZodNumber;
87
+ width: z.ZodNumber;
88
+ height: z.ZodNumber;
89
+ aspectRatio: z.ZodNumber;
90
+ }, z.core.$strip>>;
91
+ createdAt: z.ZodString;
92
+ updatedAt: z.ZodString;
37
93
  }, z.core.$strip>;
38
94
  }, z.core.$strip>;
39
95
  export declare const projectSchema: z.ZodObject<{
@@ -61,8 +117,11 @@ export declare const createProjectRequestSchema: z.ZodObject<{
61
117
  }>>;
62
118
  }, z.core.$strip>;
63
119
  export type CreateProjectRequest = z.input<typeof createProjectRequestSchema>;
120
+ export type LedBounds = z.infer<typeof ledBoundsSchema>;
64
121
  export type LedMap = z.infer<typeof ledMapSchema>;
122
+ export type LedMapResponse = z.infer<typeof ledMapResponseSchema>;
65
123
  export type LedPanel = z.infer<typeof ledPanelSchema>;
124
+ export type UpdateLedMapRequest = z.infer<typeof updateLedMapRequestSchema>;
66
125
  export type Project = z.infer<typeof projectSchema>;
67
126
  export type ProjectStatus = z.infer<typeof projectStatusSchema>;
68
127
  export type ProjectVisibility = z.infer<typeof projectVisibilitySchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../src/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,uBAAuB;;;EAAmC,CAAA;AACvE,eAAO,MAAM,mBAAmB;;;;EAA4C,CAAA;AAE5E,eAAO,MAAM,cAAc;;;;;;;iBAOzB,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;iBAYvB,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;iBASxB,CAAA;AAEF,eAAO,MAAM,0BAA0B;;;;;;iBAGrC,CAAA;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAA;AAC7E,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AACjD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AACrD,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AACnD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA"}
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../src/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,uBAAuB;;;EAAmC,CAAA;AACvE,eAAO,MAAM,mBAAmB;;;;EAA4C,CAAA;AAE5E,eAAO,MAAM,cAAc;;;;;;;iBAOzB,CAAA;AAEF,eAAO,MAAM,eAAe;;;;;;;;iBAQ1B,CAAA;AAMF,eAAO,MAAM,eAAe;;;;;;;kBAGgC,CAAA;AAsB5D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;iBAiCrB,CAAA;AAEJ,eAAO,MAAM,yBAAyB;;;;;;;;;;iBAGpC,CAAA;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;iBAAiC,CAAA;AAElE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;iBASxB,CAAA;AAEF,eAAO,MAAM,0BAA0B;;;;;;iBAGrC,CAAA;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAA;AAC7E,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AACvD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AACjD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACjE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AACrD,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAC3E,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AACnD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA"}
package/dist/projects.js CHANGED
@@ -1,28 +1,84 @@
1
1
  import { z } from 'zod';
2
- import { idSchema, isoDateSchema } from './common.js';
2
+ import { apiSuccessSchema, idSchema, isoDateSchema } from './common.js';
3
3
  export const projectVisibilitySchema = z.enum(['private', 'workspace']);
4
4
  export const projectStatusSchema = z.enum(['active', 'archived', 'deleted']);
5
5
  export const ledPanelSchema = z.object({
6
- id: z.string().min(1),
7
- name: z.string().min(1),
8
- width: z.number().int().positive(),
9
- height: z.number().int().positive(),
10
- x: z.number().int(),
11
- y: z.number().int()
6
+ id: z.string().trim().min(1).max(80),
7
+ name: z.string().trim().min(1).max(120),
8
+ width: z.number().int().positive().max(100000),
9
+ height: z.number().int().positive().max(100000),
10
+ x: z.number().int().min(-1000000).max(1000000),
11
+ y: z.number().int().min(-1000000).max(1000000)
12
+ });
13
+ export const ledBoundsSchema = z.object({
14
+ minX: z.number(),
15
+ minY: z.number(),
16
+ maxX: z.number(),
17
+ maxY: z.number(),
18
+ width: z.number().positive(),
19
+ height: z.number().positive(),
20
+ aspectRatio: z.number().positive()
12
21
  });
13
- export const ledMapSchema = z.object({
22
+ function hasUniquePanelIds(panels) {
23
+ return new Set(panels.map((panel) => panel.id)).size === panels.length;
24
+ }
25
+ export const ledPanelsSchema = z
26
+ .array(ledPanelSchema)
27
+ .max(200)
28
+ .refine(hasUniquePanelIds, 'LED panel ids must be unique');
29
+ function boundsMatchPanels(bounds, panels) {
30
+ const minX = Math.min(...panels.map((panel) => panel.x));
31
+ const minY = Math.min(...panels.map((panel) => panel.y));
32
+ const maxX = Math.max(...panels.map((panel) => panel.x + panel.width));
33
+ const maxY = Math.max(...panels.map((panel) => panel.y + panel.height));
34
+ const width = maxX - minX;
35
+ const height = maxY - minY;
36
+ const aspectRatio = width / height;
37
+ return (bounds.minX === minX &&
38
+ bounds.minY === minY &&
39
+ bounds.maxX === maxX &&
40
+ bounds.maxY === maxY &&
41
+ bounds.width === width &&
42
+ bounds.height === height &&
43
+ Math.abs(bounds.aspectRatio - aspectRatio) < 1e-9);
44
+ }
45
+ export const ledMapSchema = z
46
+ .object({
47
+ projectId: idSchema,
14
48
  version: z.number().int().nonnegative(),
15
- panels: z.array(ledPanelSchema),
16
- bounds: z.object({
17
- minX: z.number(),
18
- minY: z.number(),
19
- maxX: z.number(),
20
- maxY: z.number(),
21
- width: z.number().positive(),
22
- height: z.number().positive(),
23
- aspectRatio: z.number().positive()
24
- })
49
+ panels: ledPanelsSchema,
50
+ bounds: ledBoundsSchema.nullable(),
51
+ createdAt: isoDateSchema,
52
+ updatedAt: isoDateSchema
53
+ })
54
+ .superRefine((map, context) => {
55
+ if (map.panels.length === 0 && map.bounds !== null) {
56
+ context.addIssue({
57
+ code: 'custom',
58
+ path: ['bounds'],
59
+ message: 'Empty LED maps must have null bounds'
60
+ });
61
+ }
62
+ if (map.panels.length > 0 && map.bounds === null) {
63
+ context.addIssue({
64
+ code: 'custom',
65
+ path: ['bounds'],
66
+ message: 'Non-empty LED maps must include bounds'
67
+ });
68
+ }
69
+ if (map.panels.length > 0 && map.bounds !== null && !boundsMatchPanels(map.bounds, map.panels)) {
70
+ context.addIssue({
71
+ code: 'custom',
72
+ path: ['bounds'],
73
+ message: 'LED map bounds must match panels'
74
+ });
75
+ }
76
+ });
77
+ export const updateLedMapRequestSchema = z.object({
78
+ expectedVersion: z.number().int().nonnegative(),
79
+ panels: ledPanelsSchema
25
80
  });
81
+ export const ledMapResponseSchema = apiSuccessSchema(ledMapSchema);
26
82
  export const projectSchema = z.object({
27
83
  id: idSchema,
28
84
  workspaceId: idSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuragpal02/zcl-contracts",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -23,6 +23,7 @@
23
23
  "scripts": {
24
24
  "prebuild": "node -e \"fs.rmSync('dist', { recursive: true, force: true })\"",
25
25
  "build": "tsc -p tsconfig.json",
26
+ "prepack": "npm run build",
26
27
  "test": "vitest run",
27
28
  "typecheck": "tsc -p tsconfig.json --noEmit"
28
29
  },