Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -525,3 +525,153 @@ describe('map', () => {
});
});
});

describe('header', () => {
describe('.command()', () => {
test('can create a generic header command', () => {
const node = Builder.header.command({
name: 'custom_header',
args: [Builder.expression.literal.integer(42)],
});

expect(node).toMatchObject({
type: 'header-command',
name: 'custom_header',
args: [
{
type: 'literal',
literalType: 'integer',
value: 42,
},
],
});
});

test('can create a header command with no args', () => {
const node = Builder.header.command({
name: 'some_command',
});

expect(node).toMatchObject({
type: 'header-command',
name: 'some_command',
args: [],
});
});
});

describe('.command.set()', () => {
test('can create a SET command with single assignment', () => {
const node = Builder.header.command.set([
Builder.expression.func.binary('=', [
Builder.identifier('setting1'),
Builder.expression.literal.string('value1'),
]),
]);

expect(node).toMatchObject({
type: 'header-command',
name: 'set',
args: [
{
type: 'function',
name: '=',
subtype: 'binary-expression',
args: [
{
type: 'identifier',
name: 'setting1',
},
{
type: 'literal',
literalType: 'keyword',
valueUnquoted: 'value1',
},
],
},
],
});
});

test('can create a SET command with multiple assignments', () => {
const node = Builder.header.command.set([
Builder.expression.func.binary('=', [
Builder.identifier('setting1'),
Builder.expression.literal.string('value1'),
]),
Builder.expression.func.binary('=', [
Builder.identifier('setting2'),
Builder.expression.literal.integer(42),
]),
]);

expect(node).toMatchObject({
type: 'header-command',
name: 'set',
args: [
{
type: 'function',
name: '=',
args: [
{
type: 'identifier',
name: 'setting1',
},
{
type: 'literal',
literalType: 'keyword',
valueUnquoted: 'value1',
},
],
},
{
type: 'function',
name: '=',
args: [
{
type: 'identifier',
name: 'setting2',
},
{
type: 'literal',
literalType: 'integer',
value: 42,
},
],
},
],
});
});

test('can create a SET command with integer value', () => {
const node = Builder.header.command.set([
Builder.expression.func.binary('=', [
Builder.identifier('timeout'),
Builder.expression.literal.integer(30),
]),
]);

expect(node).toMatchObject({
type: 'header-command',
name: 'set',
args: [
{
type: 'function',
name: '=',
args: [
{
type: 'identifier',
name: 'timeout',
},
{
type: 'literal',
literalType: 'integer',
value: 30,
},
],
},
],
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import type {
ESQLMapEntry,
ESQLTimeDurationLiteral,
ESQLDatePeriodLiteral,
ESQLAstHeaderCommand,
ESQLAstSetHeaderCommand,
} from '../types';
import type { AstNodeParserFields, AstNodeTemplate, PartialFields } from './types';

Expand Down Expand Up @@ -641,4 +643,46 @@ export namespace Builder {
}
};
}

export namespace header {
export interface HeaderCommandBuilder {
<Name extends string>(
template: PartialFields<AstNodeTemplate<ESQLAstHeaderCommand<Name>>, 'args'>,
fromParser?: Partial<AstNodeParserFields>
): ESQLAstHeaderCommand<Name>;

set: (
args: ESQLAstSetHeaderCommand['args'],
template?: Omit<PartialFields<AstNodeTemplate<ESQLAstSetHeaderCommand>, 'args'>, 'name'>,
fromParser?: Partial<AstNodeParserFields>
) => ESQLAstSetHeaderCommand;
}

// eslint-disable-next-line @typescript-eslint/no-shadow
export const command: HeaderCommandBuilder = Object.assign(
<Name extends string>(
template: PartialFields<AstNodeTemplate<ESQLAstHeaderCommand<Name>>, 'args'>,
fromParser?: Partial<AstNodeParserFields>
): ESQLAstHeaderCommand<Name> => {
return {
...template,
...Builder.parserFields(fromParser),
args: template.args ?? [],
type: 'header-command',
};
},
{
set: (
args: ESQLAstSetHeaderCommand['args'],
template?: Omit<PartialFields<AstNodeTemplate<ESQLAstSetHeaderCommand>, 'args'>, 'name'>,
fromParser?: Partial<AstNodeParserFields>
): ESQLAstSetHeaderCommand => {
return Builder.header.command(
{ args, ...template, name: 'set' },
fromParser
) as ESQLAstSetHeaderCommand;
},
}
);
}
}
Loading