@flighthq/shape-formats 0.3.0-next.906.07cea63 → 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.
@@ -1 +1 @@
1
- {"version":3,"file":"shapeJson.d.ts","sourceRoot":"","sources":["../src/shapeJson.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAMrG,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,sBAAsB,CAAC,GAAG,MAAM,CA+B1G;AAMD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,KAAK,GAAG,IAAI,CAqCpG"}
1
+ {"version":3,"file":"shapeJson.d.ts","sourceRoot":"","sources":["../src/shapeJson.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAQrG,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,sBAAsB,CAAC,GAAG,MAAM,CA+B1G;AASD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,KAAK,GAAG,IAAI,CAsCpG"}
package/dist/shapeJson.js CHANGED
@@ -1,13 +1,15 @@
1
1
  import { createMatrix } from '@flighthq/geometry/contract';
2
- import { appendShapeBeginBitmapFill, appendShapeBeginFill, appendShapeBeginGradientFill, appendShapeCircle, appendShapeCubicCurveTo, appendShapeCurveTo, appendShapeDrawTriangles, appendShapeEllipse, appendShapeEndFill, appendShapeLineBitmapStyle, appendShapeLineGradientStyle, appendShapeLineStyle, appendShapeLineTo, appendShapeMoveTo, appendShapePath, appendShapeRectangle, appendShapeRoundRectangle, createShape, } from '@flighthq/shape/contract';
2
+ import { appendShapeBeginTextureFill, appendShapeBeginFill, appendShapeBeginGradientFill, appendShapeCircle, appendShapeCubicCurveTo, appendShapeCurveTo, appendShapeDrawTriangles, appendShapeEllipse, appendShapeEndFill, appendShapeLineTextureStyle, appendShapeLineGradientStyle, appendShapeLineStyle, appendShapeLineTo, appendShapeMoveTo, appendShapePath, appendShapeRectangle, appendShapeRoundRectangle, createShape, } from '@flighthq/shape/contract';
3
3
  // Serializes a shape's full drawing-command stream to a native JSON string that `parseShapeJson`
4
- // restores losslessly. Every non-bitmap command round-trips exactly; `beginBitmapFill`/
5
- // `lineBitmapStyle` resources serialize as an ordinal `ShapeBitmapReference` (see the type) rather
6
- // than the live `ImageResource`.
4
+ // restores. Every non-texture command round-trips exactly, with one exception the format cannot
5
+ // represent: JSON has no NaN or Infinity literal, so a non-finite coordinate is written as `null` and
6
+ // the document will not parse back. That is deliberate — the alternative is restoring a shape whose
7
+ // geometry silently differs from the one serialized. `beginTextureFill`/`lineTextureStyle` textures
8
+ // serialize as an ordinal `ShapeTextureReference` (see the type) rather than the live `Texture`.
7
9
  export function formatShapeJson(shape, options) {
8
10
  const commands = shape.data.commands;
9
11
  const entries = [];
10
- let bitmapOrdinal = 0;
12
+ let textureOrdinal = 0;
11
13
  let i = 0;
12
14
  while (i < commands.length) {
13
15
  const key = commands[i];
@@ -29,9 +31,9 @@ export function formatShapeJson(shape, options) {
29
31
  args.push(value);
30
32
  }
31
33
  else {
32
- // The only remaining object arg in the command registry is a live `ImageResource` bitmap;
34
+ // The only remaining object arg in the command registry is a live Texture;
33
35
  // it has no serializable id, so it becomes an ordinal reference resolved on parse.
34
- args.push({ bitmap: { index: bitmapOrdinal++ } });
36
+ args.push({ texture: { index: textureOrdinal++ } });
35
37
  }
36
38
  }
37
39
  entries.push({ key, args });
@@ -42,7 +44,10 @@ export function formatShapeJson(shape, options) {
42
44
  // Restores a `Shape` from a `formatShapeJson` string by replaying each command through the matching
43
45
  // `appendShape*` builder. Returns `null` for malformed JSON, a missing/mismatched `shapeFormat`
44
46
  // version tag, a non-array `commands` field, a malformed command entry, an unknown command key, or a
45
- // malformed argument. Bitmap-bearing commands whose reference cannot be resolved are dropped.
47
+ // malformed argument where malformed covers the argument *list* as well as each value: a count
48
+ // outside the command's arity, a value of the wrong positional type, or a non-finite number.
49
+ // Texture-bearing commands whose reference cannot be resolved are dropped rather than rejected, since
50
+ // an unresolved reference is a missing asset rather than a malformed document.
46
51
  export function parseShapeJson(text, options) {
47
52
  let root;
48
53
  try {
@@ -58,7 +63,7 @@ export function parseShapeJson(text, options) {
58
63
  const rawCommands = root.commands;
59
64
  if (!Array.isArray(rawCommands))
60
65
  return null;
61
- const resolveBitmap = options?.resolveBitmap;
66
+ const resolveTexture = options?.resolveTexture;
62
67
  const shape = createShape();
63
68
  for (const entry of rawCommands) {
64
69
  if (!isPlainObject(entry))
@@ -73,7 +78,7 @@ export function parseShapeJson(text, options) {
73
78
  const args = [];
74
79
  let drop = false;
75
80
  for (const raw of rawArgs) {
76
- const reconstructed = reconstructShapeCommandArg(raw, resolveBitmap);
81
+ const reconstructed = reconstructShapeCommandArg(raw, resolveTexture);
77
82
  if (reconstructed === MALFORMED_ARG)
78
83
  return null;
79
84
  if (reconstructed === DROP_COMMAND) {
@@ -84,13 +89,15 @@ export function parseShapeJson(text, options) {
84
89
  }
85
90
  if (drop)
86
91
  continue;
92
+ if (!isValidShapeCommandArgs(key, args))
93
+ return null;
87
94
  appender(shape, ...args);
88
95
  }
89
96
  return shape;
90
97
  }
91
98
  // Rebuilds a single command argument from its serialized form. Returns `MALFORMED_ARG` for an
92
- // unrecognized object shape and `DROP_COMMAND` when a bitmap reference cannot be resolved.
93
- function reconstructShapeCommandArg(value, resolveBitmap) {
99
+ // unrecognized object shape and `DROP_COMMAND` when a texture reference cannot be resolved.
100
+ function reconstructShapeCommandArg(value, resolveTexture) {
94
101
  if (value === null)
95
102
  return null;
96
103
  const type = typeof value;
@@ -100,8 +107,8 @@ function reconstructShapeCommandArg(value, resolveBitmap) {
100
107
  return value;
101
108
  if (!isPlainObject(value))
102
109
  return MALFORMED_ARG;
103
- if (isPlainObject(value.bitmap) && typeof value.bitmap.index === 'number') {
104
- const resolved = resolveBitmap?.({ index: value.bitmap.index }) ?? null;
110
+ if (isPlainObject(value.texture) && typeof value.texture.index === 'number') {
111
+ const resolved = resolveTexture?.({ index: value.texture.index }) ?? null;
105
112
  return resolved === null ? DROP_COMMAND : resolved;
106
113
  }
107
114
  if (typeof value.a === 'number' &&
@@ -114,6 +121,60 @@ function reconstructShapeCommandArg(value, resolveBitmap) {
114
121
  }
115
122
  return MALFORMED_ARG;
116
123
  }
124
+ // Checks a reconstructed argument list against the appender's declared shape. Without this the parser
125
+ // validated only that an entry *looked* like a command and then spread whatever it found: too few args
126
+ // left required parameters undefined, wrong-typed args wrote strings into numeric slots, and extra args
127
+ // were dropped without complaint — each producing a corrupt Shape rather than the documented null.
128
+ //
129
+ // Runs after reconstruction, so matrices are already Matrix values and textures already resolved, and
130
+ // after the drop check, so an unresolved texture is still a dropped command rather than a parse failure.
131
+ function isValidShapeCommandArgs(key, args) {
132
+ const spec = SHAPE_COMMAND_ARG_SPECS[key];
133
+ // Treating a missing spec as invalid is what makes the two tables self-checking: a key that gained
134
+ // an appender without a spec would make its own command unparseable, so the full-vocabulary
135
+ // round-trip test fails the moment they drift apart.
136
+ if (spec === undefined)
137
+ return false;
138
+ if (args.length < spec.required || args.length > spec.types.length)
139
+ return false;
140
+ for (let i = 0; i < args.length; i++) {
141
+ if (!isValidShapeCommandArg(args[i], spec.types[i]))
142
+ return false;
143
+ }
144
+ return true;
145
+ }
146
+ function isValidShapeCommandArg(value, type) {
147
+ switch (type) {
148
+ // Non-finite values are rejected here rather than passed through: JSON has no NaN or Infinity
149
+ // literal, so a NaN in a shape serializes as `null` and an out-of-range literal like 1e999 parses
150
+ // back as Infinity. Either one silently changes the geometry it describes.
151
+ case 'number':
152
+ return typeof value === 'number' && Number.isFinite(value);
153
+ case 'numbers':
154
+ return isFiniteNumberArray(value);
155
+ case 'numbersOrNull':
156
+ return value === null || isFiniteNumberArray(value);
157
+ case 'string':
158
+ return typeof value === 'string';
159
+ case 'boolean':
160
+ return typeof value === 'boolean';
161
+ case 'matrixOrNull':
162
+ return value === null || isMatrixValue(value);
163
+ // Already resolved by resolveTexture, which returns either a Texture or null; a null resolution
164
+ // dropped the command before reaching here, so anything left is the caller's own object.
165
+ case 'texture':
166
+ return typeof value === 'object' && value !== null;
167
+ }
168
+ }
169
+ function isFiniteNumberArray(value) {
170
+ if (!Array.isArray(value))
171
+ return false;
172
+ for (const entry of value) {
173
+ if (typeof entry !== 'number' || !Number.isFinite(entry))
174
+ return false;
175
+ }
176
+ return true;
177
+ }
117
178
  function isMatrixValue(value) {
118
179
  return (isPlainObject(value) &&
119
180
  typeof value.a === 'number' &&
@@ -132,11 +193,41 @@ function isSerializableScalarOrArray(value) {
132
193
  }
133
194
  // Sentinel returned when a command argument is structurally invalid; parse aborts to `null`.
134
195
  const MALFORMED_ARG = Symbol('shapeFormats.malformedArg');
135
- // Sentinel returned when a bitmap reference cannot be resolved; the owning command is dropped.
196
+ // Sentinel returned when a texture reference cannot be resolved; the owning command is dropped.
136
197
  const DROP_COMMAND = Symbol('shapeFormats.dropCommand');
137
- const SHAPE_JSON_FORMAT = 1;
198
+ const SHAPE_JSON_FORMAT = 2;
199
+ const GRADIENT_ARG_SPEC = {
200
+ required: 4,
201
+ types: ['string', 'numbers', 'numbers', 'numbers', 'matrixOrNull', 'string', 'string', 'number'],
202
+ };
203
+ const TEXTURE_ARG_SPEC = { required: 1, types: ['texture', 'matrixOrNull'] };
204
+ const SHAPE_COMMAND_ARG_SPECS = {
205
+ beginTextureFill: TEXTURE_ARG_SPEC,
206
+ beginFill: { required: 0, types: ['number', 'number'] },
207
+ beginGradientFill: GRADIENT_ARG_SPEC,
208
+ cubicCurveTo: { required: 6, types: ['number', 'number', 'number', 'number', 'number', 'number'] },
209
+ curveTo: { required: 4, types: ['number', 'number', 'number', 'number'] },
210
+ drawCircle: { required: 3, types: ['number', 'number', 'number'] },
211
+ drawEllipse: { required: 4, types: ['number', 'number', 'number', 'number'] },
212
+ drawPath: { required: 2, types: ['numbers', 'numbers', 'string'] },
213
+ drawRectangle: { required: 4, types: ['number', 'number', 'number', 'number'] },
214
+ drawRoundRectangle: {
215
+ required: 6,
216
+ types: ['number', 'number', 'number', 'number', 'number', 'number'],
217
+ },
218
+ drawTriangles: { required: 1, types: ['numbers', 'numbersOrNull', 'numbersOrNull', 'string'] },
219
+ endFill: { required: 0, types: [] },
220
+ lineTextureStyle: TEXTURE_ARG_SPEC,
221
+ lineGradientStyle: GRADIENT_ARG_SPEC,
222
+ lineStyle: {
223
+ required: 0,
224
+ types: ['number', 'number', 'number', 'boolean', 'string', 'string', 'string', 'number'],
225
+ },
226
+ lineTo: { required: 2, types: ['number', 'number'] },
227
+ moveTo: { required: 2, types: ['number', 'number'] },
228
+ };
138
229
  const SHAPE_COMMAND_APPENDERS = {
139
- beginBitmapFill: appendShapeBeginBitmapFill,
230
+ beginTextureFill: appendShapeBeginTextureFill,
140
231
  beginFill: appendShapeBeginFill,
141
232
  beginGradientFill: appendShapeBeginGradientFill,
142
233
  cubicCurveTo: appendShapeCubicCurveTo,
@@ -148,7 +239,7 @@ const SHAPE_COMMAND_APPENDERS = {
148
239
  drawRoundRectangle: appendShapeRoundRectangle,
149
240
  drawTriangles: appendShapeDrawTriangles,
150
241
  endFill: appendShapeEndFill,
151
- lineBitmapStyle: appendShapeLineBitmapStyle,
242
+ lineTextureStyle: appendShapeLineTextureStyle,
152
243
  lineGradientStyle: appendShapeLineGradientStyle,
153
244
  lineStyle: appendShapeLineStyle,
154
245
  lineTo: appendShapeLineTo,
@@ -1 +1 @@
1
- {"version":3,"file":"shapeJson.js","sourceRoot":"","sources":["../src/shapeJson.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shapeJson.js","sourceRoot":"","sources":["../src/shapeJson.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "name": "@flighthq/shape-formats",
3
- "version": "0.3.0-next.906.07cea63",
3
+ "version": "0.3.0",
4
+ "author": "Joshua Granick and other contributors",
5
+ "license": "MIT",
4
6
  "repository": {
5
7
  "type": "git",
6
8
  "url": "https://github.com/flighthq/flight.git",
@@ -36,9 +38,9 @@
36
38
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
37
39
  },
38
40
  "dependencies": {
39
- "@flighthq/geometry": "0.3.0-next.906.07cea63",
40
- "@flighthq/shape": "0.3.0-next.906.07cea63",
41
- "@flighthq/types": "0.3.0-next.906.07cea63"
41
+ "@flighthq/geometry": "0.3.0",
42
+ "@flighthq/shape": "0.3.0",
43
+ "@flighthq/types": "0.3.0"
42
44
  },
43
45
  "devDependencies": {
44
46
  "typescript": "^5.3.0"
@@ -1,19 +1,26 @@
1
1
  import { createMatrix } from '@flighthq/geometry/contract';
2
2
  import {
3
- appendShapeBeginBitmapFill,
3
+ appendShapeBeginTextureFill,
4
4
  appendShapeBeginFill,
5
5
  appendShapeBeginGradientFill,
6
+ appendShapeCircle,
6
7
  appendShapeCubicCurveTo,
7
8
  appendShapeCurveTo,
9
+ appendShapeDrawTriangles,
10
+ appendShapeEllipse,
8
11
  appendShapeEndFill,
12
+ appendShapeLineGradientStyle,
9
13
  appendShapeLineStyle,
14
+ appendShapeLineTextureStyle,
15
+ appendShapeRectangle,
16
+ appendShapeRoundRectangle,
10
17
  appendShapeLineTo,
11
18
  appendShapeMoveTo,
12
19
  appendShapePath,
13
20
  createShape,
14
21
  getShapeCommandCount,
15
22
  } from '@flighthq/shape/contract';
16
- import type { ImageResource } from '@flighthq/types/contract';
23
+ import type { Texture } from '@flighthq/types/contract';
17
24
 
18
25
  import { formatShapeJson, parseShapeJson } from './shapeJson';
19
26
 
@@ -37,14 +44,31 @@ function createEveryNonBitmapCommandShape() {
37
44
  appendShapeCurveTo(shape, 150, 50, 100, 100);
38
45
  appendShapeCubicCurveTo(shape, 10, 10, 20, 20, 30, 30);
39
46
  appendShapePath(shape, [1, 2], [0, 0, 50, 50], 'evenOdd');
47
+ appendShapeCircle(shape, 5, 6, 7);
48
+ appendShapeEllipse(shape, 1, 2, 3, 4);
49
+ appendShapeRectangle(shape, 10, 11, 12, 13);
50
+ appendShapeRoundRectangle(shape, 1, 2, 3, 4, 5, 6);
51
+ appendShapeDrawTriangles(shape, [0, 0, 1, 0, 0, 1], [0, 1, 2], [0, 0, 1, 0, 0, 1], 'positive');
52
+ appendShapeDrawTriangles(shape, [0, 0, 1, 0, 0, 1], null, null, 'none');
53
+ appendShapeLineGradientStyle(
54
+ shape,
55
+ 'radial',
56
+ [0x112233ff, 0x445566ff],
57
+ [1, 0],
58
+ [0, 255],
59
+ null,
60
+ 'reflect',
61
+ 'linearRGB',
62
+ 0.5,
63
+ );
40
64
  appendShapeEndFill(shape);
41
65
  return shape;
42
66
  }
43
67
 
44
- // A minimal stand-in for a live ImageResource; the codec never inspects resource internals, only
68
+ // A minimal stand-in for a live Texture; the codec never inspects texture internals, only
45
69
  // swaps the object for an ordinal reference and back.
46
- function createFakeBitmap(): ImageResource {
47
- return { width: 4, height: 4 } as unknown as ImageResource;
70
+ function createFakeTexture(): Texture {
71
+ return {} as Texture;
48
72
  }
49
73
 
50
74
  describe('formatShapeJson', () => {
@@ -52,7 +76,7 @@ describe('formatShapeJson', () => {
52
76
  const shape = createShape();
53
77
  appendShapeBeginFill(shape, 0x112233ff, 1);
54
78
  const parsed = JSON.parse(formatShapeJson(shape));
55
- expect(parsed.shapeFormat).toBe(1);
79
+ expect(parsed.shapeFormat).toBe(2);
56
80
  expect(Array.isArray(parsed.commands)).toBe(true);
57
81
  expect(parsed.commands[0]).toEqual({ key: 'beginFill', args: [0x112233ff, 1] });
58
82
  });
@@ -64,14 +88,12 @@ describe('formatShapeJson', () => {
64
88
  expect(parsed.commands[0].args[4]).toEqual({ a: 2, b: 0, c: 0, d: 3, tx: 5, ty: 7 });
65
89
  });
66
90
 
67
- it('serializes a bitmap resource as an ordinal reference, never the resource', () => {
91
+ it('serializes a texture as an ordinal reference, never the texture', () => {
68
92
  const shape = createShape();
69
- appendShapeBeginBitmapFill(shape, createFakeBitmap(), null, true, false);
93
+ appendShapeBeginTextureFill(shape, createFakeTexture(), null);
70
94
  const parsed = JSON.parse(formatShapeJson(shape));
71
- expect(parsed.commands[0].args[0]).toEqual({ bitmap: { index: 0 } });
95
+ expect(parsed.commands[0].args[0]).toEqual({ texture: { index: 0 } });
72
96
  expect(parsed.commands[0].args[1]).toBeNull();
73
- expect(parsed.commands[0].args[2]).toBe(true);
74
- expect(parsed.commands[0].args[3]).toBe(false);
75
97
  });
76
98
 
77
99
  it('honors the space option for pretty-printing', () => {
@@ -82,7 +104,7 @@ describe('formatShapeJson', () => {
82
104
  });
83
105
 
84
106
  describe('parseShapeJson', () => {
85
- it('round-trips every non-bitmap command losslessly', () => {
107
+ it('round-trips every non-texture command losslessly', () => {
86
108
  const shape = createEveryNonBitmapCommandShape();
87
109
  const json = formatShapeJson(shape);
88
110
  const restored = parseShapeJson(json);
@@ -100,7 +122,7 @@ describe('parseShapeJson', () => {
100
122
  });
101
123
 
102
124
  it('returns null for a mismatched version tag', () => {
103
- expect(parseShapeJson(JSON.stringify({ shapeFormat: 2, commands: [] }))).toBeNull();
125
+ expect(parseShapeJson(JSON.stringify({ shapeFormat: 3, commands: [] }))).toBeNull();
104
126
  });
105
127
 
106
128
  it('returns null when the top level is not an object', () => {
@@ -108,40 +130,40 @@ describe('parseShapeJson', () => {
108
130
  });
109
131
 
110
132
  it('returns null for an unknown command key', () => {
111
- const json = JSON.stringify({ shapeFormat: 1, commands: [{ key: 'notACommand', args: [] }] });
133
+ const json = JSON.stringify({ shapeFormat: 2, commands: [{ key: 'notACommand', args: [] }] });
112
134
  expect(parseShapeJson(json)).toBeNull();
113
135
  });
114
136
 
115
137
  it('returns null for a malformed argument object', () => {
116
- const json = JSON.stringify({ shapeFormat: 1, commands: [{ key: 'beginFill', args: [{ nonsense: true }, 1] }] });
138
+ const json = JSON.stringify({ shapeFormat: 2, commands: [{ key: 'beginFill', args: [{ nonsense: true }, 1] }] });
117
139
  expect(parseShapeJson(json)).toBeNull();
118
140
  });
119
141
 
120
- it('round-trips a bitmap fill through the resolver', () => {
121
- const bitmap = createFakeBitmap();
142
+ it('round-trips a bitmap fill through the texture resolver', () => {
143
+ const texture = createFakeTexture();
122
144
  const shape = createShape();
123
- appendShapeBeginBitmapFill(shape, bitmap, createMatrix(1, 0, 0, 1, 3, 4), true, false);
145
+ appendShapeBeginTextureFill(shape, texture, createMatrix(1, 0, 0, 1, 3, 4));
124
146
  appendShapeMoveTo(shape, 5, 6);
125
147
 
126
148
  const seen: number[] = [];
127
149
  const restored = parseShapeJson(formatShapeJson(shape), {
128
- resolveBitmap: (reference) => {
150
+ resolveTexture: (reference) => {
129
151
  seen.push(reference.index);
130
- return bitmap;
152
+ return texture;
131
153
  },
132
154
  });
133
155
 
134
156
  expect(restored).not.toBeNull();
135
157
  expect(seen).toEqual([0]);
136
158
  expect(getShapeCommandCount(restored!)).toBe(2);
137
- expect(restored!.data.commands[0]).toBe('beginBitmapFill');
138
- expect(restored!.data.commands[2]).toBe(bitmap);
159
+ expect(restored!.data.commands[0]).toBe('beginTextureFill');
160
+ expect(restored!.data.commands[2]).toBe(texture);
139
161
  });
140
162
 
141
163
  it('drops a bitmap fill when no resolver is supplied and keeps the rest intact', () => {
142
164
  const shape = createShape();
143
165
  appendShapeBeginFill(shape, 0xffffffff, 1);
144
- appendShapeBeginBitmapFill(shape, createFakeBitmap(), null, true, false);
166
+ appendShapeBeginTextureFill(shape, createFakeTexture(), null);
145
167
  appendShapeLineTo(shape, 9, 9);
146
168
 
147
169
  const restored = parseShapeJson(formatShapeJson(shape));
@@ -153,12 +175,110 @@ describe('parseShapeJson', () => {
153
175
 
154
176
  it('drops a bitmap fill when the resolver returns null', () => {
155
177
  const shape = createShape();
156
- appendShapeBeginBitmapFill(shape, createFakeBitmap(), null, true, false);
178
+ appendShapeBeginTextureFill(shape, createFakeTexture(), null);
157
179
  appendShapeEndFill(shape);
158
180
 
159
- const restored = parseShapeJson(formatShapeJson(shape), { resolveBitmap: () => null });
181
+ const restored = parseShapeJson(formatShapeJson(shape), { resolveTexture: () => null });
160
182
  expect(restored).not.toBeNull();
161
183
  expect(getShapeCommandCount(restored!)).toBe(1);
162
184
  expect(restored!.data.commands[0]).toBe('endFill');
163
185
  });
164
186
  });
187
+
188
+ describe('parseShapeJson argument validation', () => {
189
+ function document(commands: readonly unknown[]): string {
190
+ return JSON.stringify({ shapeFormat: 2, commands });
191
+ }
192
+
193
+ // Every rejection below used to build a Shape instead. The parser checked that an entry looked like
194
+ // a command and then spread whatever it found straight into the appender, so a bad document produced
195
+ // corrupt geometry rather than the null its own contract documents.
196
+ it('rejects a command with too few arguments', () => {
197
+ expect(parseShapeJson(document([{ key: 'moveTo', args: [1] }]))).toBeNull();
198
+ });
199
+
200
+ it('rejects a command with too many arguments', () => {
201
+ expect(parseShapeJson(document([{ key: 'moveTo', args: [1, 2, 3] }]))).toBeNull();
202
+ });
203
+
204
+ it('rejects a string where a number is expected', () => {
205
+ expect(parseShapeJson(document([{ key: 'moveTo', args: ['1', '2'] }]))).toBeNull();
206
+ });
207
+
208
+ it('rejects a number where a string is expected', () => {
209
+ expect(parseShapeJson(document([{ key: 'drawPath', args: [[1], [0, 0], 7] }]))).toBeNull();
210
+ });
211
+
212
+ it('rejects a number where an array is expected', () => {
213
+ expect(parseShapeJson(document([{ key: 'drawPath', args: [1, [0, 0], 'evenOdd'] }]))).toBeNull();
214
+ });
215
+
216
+ it('rejects a non-numeric entry inside a numeric array', () => {
217
+ expect(parseShapeJson(document([{ key: 'drawPath', args: [[1], [0, 'x'], 'evenOdd'] }]))).toBeNull();
218
+ });
219
+
220
+ // JSON has no NaN or Infinity literal: a NaN coordinate serializes as `null`, and an out-of-range
221
+ // literal parses back as Infinity. Both silently change the geometry, so both are refused.
222
+ it('rejects a null where a number is expected, which is how NaN survives JSON', () => {
223
+ expect(parseShapeJson(document([{ key: 'moveTo', args: [null, 5] }]))).toBeNull();
224
+ });
225
+
226
+ it('rejects an out-of-range literal that parses as Infinity', () => {
227
+ expect(parseShapeJson('{"shapeFormat":2,"commands":[{"key":"moveTo","args":[1e999,2]}]}')).toBeNull();
228
+ });
229
+
230
+ it('rejects a non-finite entry inside a numeric array', () => {
231
+ expect(
232
+ parseShapeJson('{"shapeFormat":2,"commands":[{"key":"drawPath","args":[[1],[1e999,0],"evenOdd"]}]}'),
233
+ ).toBeNull();
234
+ });
235
+
236
+ it('accepts a command that omits its optional trailing arguments', () => {
237
+ const restored = parseShapeJson(
238
+ document([
239
+ { key: 'lineStyle', args: [] },
240
+ { key: 'endFill', args: [] },
241
+ ]),
242
+ );
243
+ expect(restored).not.toBeNull();
244
+ expect(getShapeCommandCount(restored!)).toBe(2);
245
+ });
246
+
247
+ it('accepts a null matrix in an optional matrix position', () => {
248
+ const restored = parseShapeJson(
249
+ document([{ key: 'beginGradientFill', args: ['linear', [1], [1], [0], null, 'pad', 'rgb', 0] }]),
250
+ );
251
+ expect(restored).not.toBeNull();
252
+ });
253
+
254
+ it('rejects a non-matrix object in a matrix position', () => {
255
+ expect(
256
+ parseShapeJson(
257
+ document([{ key: 'beginGradientFill', args: ['linear', [1], [1], [0], { a: 1 }, 'pad', 'rgb', 0] }]),
258
+ ),
259
+ ).toBeNull();
260
+ });
261
+
262
+ // A texture command still drops rather than failing the parse: an unresolved reference is a missing
263
+ // asset, not a malformed document, and that distinction predates this validation.
264
+ it('drops rather than rejects a texture command whose reference does not resolve', () => {
265
+ const shape = createShape();
266
+ appendShapeBeginTextureFill(shape, createFakeTexture(), null);
267
+ appendShapeEndFill(shape);
268
+ const restored = parseShapeJson(formatShapeJson(shape), { resolveTexture: () => null });
269
+ expect(restored).not.toBeNull();
270
+ expect(getShapeCommandCount(restored!)).toBe(1);
271
+ });
272
+
273
+ // The two tables are indexed by the same key set and are read together on every command, so a key
274
+ // in the appender table with no arg spec would make its command unparseable — isValidShapeCommandArgs
275
+ // treats a missing spec as invalid. Round-tripping a shape that exercises the whole non-texture
276
+ // vocabulary therefore *is* the consistency check: a forgotten spec turns this null.
277
+ it('parses every command the serializer can emit, proving each has an argument spec', () => {
278
+ const shape = createEveryNonBitmapCommandShape();
279
+ const expected = getShapeCommandCount(shape);
280
+ const restored = parseShapeJson(formatShapeJson(shape));
281
+ expect(restored).not.toBeNull();
282
+ expect(getShapeCommandCount(restored!)).toBe(expected);
283
+ });
284
+ });