Skip to content

Commit 29e3778

Browse files
authored
feat(schema-compiler): Yaml - report error on misconfiguration (object instead of array) (#6407)
1 parent 00e41bf commit 29e3778

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

packages/cubejs-schema-compiler/src/compiler/YamlCompiler.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { CubeSymbols } from './CubeSymbols';
1010
import { DataSchemaCompiler } from './DataSchemaCompiler';
1111
import { nonStringFields } from './CubeValidator';
1212
import { CubeDictionary } from './CubeDictionary';
13+
import { ErrorReporter } from './ErrorReporter';
1314

1415
type EscapeStateStack = {
1516
inFormattedStr?: boolean;
@@ -24,11 +25,11 @@ export class YamlCompiler {
2425
public constructor(private cubeSymbols: CubeSymbols, private cubeDictionary: CubeDictionary) {
2526
}
2627

27-
public compileYamlFile(file, errorsReport, cubes, contexts, exports, asyncModules, toCompile, compiledFiles) {
28+
public compileYamlFile(file, errorsReport: ErrorReporter, cubes, contexts, exports, asyncModules, toCompile, compiledFiles) {
2829
if (!file.content.trim()) {
2930
return;
3031
}
31-
32+
3233
const yamlObj = YAML.load(file.content);
3334
for (const key of Object.keys(yamlObj)) {
3435
if (key === 'cubes') {
@@ -47,7 +48,7 @@ export class YamlCompiler {
4748
}
4849
}
4950

50-
private transpileAndPrepareJsFile(file, methodFn, cubeObj, errorsReport) {
51+
private transpileAndPrepareJsFile(file, methodFn, cubeObj, errorsReport: ErrorReporter) {
5152
const yamlAst = this.transformYamlCubeObj(cubeObj, errorsReport);
5253

5354
const cubeOrViewCall = t.callExpression(t.identifier(methodFn), [t.stringLiteral(cubeObj.name), yamlAst]);
@@ -59,7 +60,7 @@ export class YamlCompiler {
5960
};
6061
}
6162

62-
private transformYamlCubeObj(cubeObj, errorsReport) {
63+
private transformYamlCubeObj(cubeObj, errorsReport: ErrorReporter) {
6364
cubeObj = this.camelizeObj(cubeObj);
6465
cubeObj.measures = this.yamlArrayToObj(cubeObj.measures || [], 'measure', errorsReport);
6566
cubeObj.dimensions = this.yamlArrayToObj(cubeObj.dimensions || [], 'dimension', errorsReport);
@@ -220,14 +221,21 @@ export class YamlCompiler {
220221
return ast.program.body[0]?.expression;
221222
}
222223

223-
private yamlArrayToObj(yamlArray, memberType, errorsReport) {
224-
return yamlArray.map(({ name, ...rest }) => {
224+
private yamlArrayToObj(yamlArray, memberType: string, errorsReport: ErrorReporter) {
225+
if (!Array.isArray(yamlArray)) {
226+
errorsReport.error(`${memberType}s must be defined as array`);
227+
return {};
228+
}
229+
230+
const remapped = yamlArray.map(({ name, ...rest }) => {
225231
if (!name) {
226232
errorsReport.error(`name isn't defined for ${memberType}: ${YAML.stringify(rest)}`);
227233
return {};
228234
} else {
229235
return { [name]: rest };
230236
}
231-
}).reduce((a, b) => ({ ...a, ...b }), {});
237+
});
238+
239+
return remapped.reduce((a, b) => ({ ...a, ...b }), {});
232240
}
233241
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { prepareCompiler, prepareYamlCompiler } from './PrepareCompiler';
2+
import { createCubeSchema } from './utils';
3+
4+
describe('Yaml Schema Testing', () => {
5+
it('members must be defined as arrays', async () => {
6+
const { compiler } = prepareYamlCompiler(
7+
`
8+
cubes:
9+
- name: Products
10+
sql: "select * from tbl"
11+
dimensions:
12+
name: Title
13+
sql: name
14+
type: string
15+
`
16+
);
17+
18+
try {
19+
await compiler.compile();
20+
21+
throw new Error('compile must return an error');
22+
} catch (e: any) {
23+
expect(e.message).toContain('dimensions must be defined as array');
24+
}
25+
});
26+
});

0 commit comments

Comments
 (0)