@appsemble/utils 0.20.18 → 0.20.20

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.
@@ -1827,4 +1827,89 @@ describe('validateAppDefinition', () => {
1827
1827
  new ValidationError('Unexpected error: Boom!', null, undefined, []),
1828
1828
  ]);
1829
1829
  });
1830
+
1831
+ it('should prevent block with layout float to be used in a dialog action', async () => {
1832
+ const app = createTestApp();
1833
+ (app.pages[0] as BasicPageDefinition).blocks.push({
1834
+ type: 'test',
1835
+ version: '1.2.3',
1836
+ actions: {
1837
+ onClick: {
1838
+ type: 'dialog',
1839
+ blocks: [
1840
+ {
1841
+ type: 'test',
1842
+ version: '1.2.3',
1843
+ },
1844
+ ],
1845
+ },
1846
+ },
1847
+ });
1848
+ const result = await validateAppDefinition(app, () => [
1849
+ {
1850
+ name: '@appsemble/test',
1851
+ version: '1.2.3',
1852
+ files: [],
1853
+ languages: [],
1854
+ layout: 'float',
1855
+ actions: {
1856
+ onClick: {},
1857
+ },
1858
+ },
1859
+ ]);
1860
+ expect(result.valid).toBe(false);
1861
+ expect(result.errors).toStrictEqual([
1862
+ new ValidationError(
1863
+ 'block with layout type: "float" is not allowed in a dialog action',
1864
+ '1.2.3',
1865
+ undefined,
1866
+ ['pages', 0, 'blocks', 0, 'actions', 'onClick', 'type'],
1867
+ ),
1868
+ ]);
1869
+ });
1870
+
1871
+ it('should check app definition for blocks that have their layout manually set to float', async () => {
1872
+ const app = createTestApp();
1873
+ (app.pages[0] as BasicPageDefinition).blocks.push({
1874
+ type: 'test',
1875
+ version: '1.2.3',
1876
+ actions: {
1877
+ onClick: {
1878
+ type: 'dialog',
1879
+ blocks: [
1880
+ {
1881
+ type: 'test',
1882
+ version: '1.2.3',
1883
+ layout: 'float',
1884
+ },
1885
+ ],
1886
+ },
1887
+ },
1888
+ });
1889
+ const result = await validateAppDefinition(app, () => [
1890
+ {
1891
+ name: '@appsemble/test',
1892
+ version: '1.2.3',
1893
+ files: [],
1894
+ languages: [],
1895
+ layout: 'hidden',
1896
+ actions: {
1897
+ onClick: {},
1898
+ },
1899
+ },
1900
+ ]);
1901
+ expect(result.valid).toBe(false);
1902
+ expect(result.errors).toStrictEqual([
1903
+ new ValidationError(
1904
+ 'block with layout type: "float" is not allowed in a dialog action',
1905
+ {
1906
+ layout: 'float',
1907
+ type: 'test',
1908
+ version: '1.2.3',
1909
+ },
1910
+ undefined,
1911
+ ['pages', 0, 'blocks', 0, 'actions', 'onClick', 'type'],
1912
+ ),
1913
+ ]);
1914
+ });
1830
1915
  });
package/validation.ts CHANGED
@@ -134,20 +134,13 @@ function validateResourceSchemas(definition: AppDefinition, report: Report): voi
134
134
 
135
135
  function validateBlocks(
136
136
  definition: AppDefinition,
137
- blockVersions: BlockManifest[],
137
+ blockVersions: Map<string, Map<string, BlockManifest>>,
138
138
  report: Report,
139
139
  ): void {
140
- const blockVersionMap = new Map<string, Map<string, BlockManifest>>();
141
- for (const version of blockVersions) {
142
- if (!blockVersionMap.has(version.name)) {
143
- blockVersionMap.set(version.name, new Map());
144
- }
145
- blockVersionMap.get(version.name).set(version.version, version);
146
- }
147
140
  iterApp(definition, {
148
141
  onBlock(block, path) {
149
142
  const type = normalizeBlockName(block.type);
150
- const versions = blockVersionMap.get(type);
143
+ const versions = blockVersions.get(type);
151
144
  if (!versions) {
152
145
  report(block.type, 'is not a known block type', [...path, 'type']);
153
146
  return;
@@ -602,7 +595,11 @@ function validateActions(definition: AppDefinition, report: Report): void {
602
595
  });
603
596
  }
604
597
 
605
- function validateEvents(definition: AppDefinition, report: Report): void {
598
+ function validateEvents(
599
+ definition: AppDefinition,
600
+ blockVersions: Map<string, Map<string, BlockManifest>>,
601
+ report: Report,
602
+ ): void {
606
603
  const indexMap = new Map<
607
604
  number,
608
605
  {
@@ -636,6 +633,32 @@ function validateEvents(definition: AppDefinition, report: Report): void {
636
633
 
637
634
  iterApp(definition, {
638
635
  onAction(action, path) {
636
+ if (action.type === 'dialog') {
637
+ for (const block of action.blocks) {
638
+ const versions = blockVersions.get(normalizeBlockName(block.type));
639
+ const version = versions.get(block.version);
640
+ if (version.layout === 'float') {
641
+ report(
642
+ block.version,
643
+ 'block with layout type: "'
644
+ .concat(version.layout)
645
+ .concat('" is not allowed in a dialog action'),
646
+ [...path, 'type'],
647
+ );
648
+ }
649
+
650
+ if (block.layout === 'float') {
651
+ report(
652
+ block,
653
+ 'block with layout type: "'
654
+ .concat(block.layout)
655
+ .concat('" is not allowed in a dialog action'),
656
+ [...path, 'type'],
657
+ );
658
+ }
659
+ }
660
+ return;
661
+ }
639
662
  if (action.type !== 'event') {
640
663
  return;
641
664
  }
@@ -710,9 +733,17 @@ export async function validateAppDefinition(
710
733
  if (!definition) {
711
734
  return result;
712
735
  }
713
-
714
736
  const blocks = getAppBlocks(definition);
715
737
  const blockVersions = await getBlockVersions(blocks);
738
+
739
+ const blockVersionMap = new Map<string, Map<string, BlockManifest>>();
740
+ for (const version of blockVersions) {
741
+ if (!blockVersionMap.has(version.name)) {
742
+ blockVersionMap.set(version.name, new Map());
743
+ }
744
+ blockVersionMap.get(version.name).set(version.version, version);
745
+ }
746
+
716
747
  const report: Report = (instance, message, path) => {
717
748
  result.errors.push(new ValidationError(message, instance, undefined, path));
718
749
  };
@@ -725,9 +756,9 @@ export async function validateAppDefinition(
725
756
  validateResourceReferences(definition, report);
726
757
  validateResourceSchemas(definition, report);
727
758
  validateSecurity(definition, report);
728
- validateBlocks(definition, blockVersions, report);
759
+ validateBlocks(definition, blockVersionMap, report);
729
760
  validateActions(definition, report);
730
- validateEvents(definition, report);
761
+ validateEvents(definition, blockVersionMap, report);
731
762
  } catch (error) {
732
763
  report(null, `Unexpected error: ${error instanceof Error ? error.message : error}`, []);
733
764
  }