Skip to content

Commit bde250a

Browse files
authored
Merge pull request #180 from eviltester/codex/import-trim-options
[codex] add import trim options
2 parents 16e77d2 + 57983c1 commit bde250a

37 files changed

Lines changed: 882 additions & 4 deletions

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,11 +298,17 @@ Supported options:
298298
- `-o, --outputfile` write output to file instead of stdout
299299
- `-t, --testMode` enable diagnostics mode and generate one row
300300
- `--unsafe-faker-expressions` allow expression-style faker args (disabled by default)
301+
- `--trim-input` trim whitespace from every imported field value before amend processing
302+
- `--trim-input-fields` comma-separated imported field names to trim before amend processing
301303

302304
Amend existing data with a schema:
303305

304306
`anywaydata amend --schema-file schema.txt --data-file input.csv --input-format csv -f json -o amended.json`
305307

308+
Trim imported input values during amend:
309+
310+
`anywaydata amend --schema-file schema.txt --data-file input.csv --input-format csv --trim-input-fields Name,Email -f json`
311+
306312
Pairwise note:
307313

308314
- when `--pairwise` is enabled, `--numberOfLines` is accepted but ignored (the pairwise engine determines row count)
@@ -370,6 +376,7 @@ Amend imported data endpoint:
370376
`POST http://localhost:3000/v1/generate/amend`
371377

372378
- JSON body fields: `textSpec` (required), `inputData` (required raw text), `inputFormat` (required), `rowCount` (optional, defaults to input row count), `outputFormat` (optional), `responseFormat` (optional), `stream` (optional and ignored)
379+
- amend trim controls: `trimInput` trims all imported field values; `trimInputFieldsCsv` trims only the listed imported field names
373380
- `rowCount` must be `<=` imported row count
374381
- response returns the full resulting dataset after amendment
375382

@@ -499,6 +506,8 @@ Inputs:
499506
- `outputFormat` (required string e.g. `csv`, `json`, `jsonl`, `xml`, `sql`)
500507
- `options` (optional object)
501508
- `seed` (optional number)
509+
- `trimInput` (optional boolean for `amend_data_from_spec`)
510+
- `trimInputFieldsCsv` (optional string for `amend_data_from_spec`)
502511

503512
Discoverability support:
504513

apps/api/src/api-service.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ export function createApiService({
211211
outputFormat = 'csv',
212212
options,
213213
seed,
214+
trimInput,
215+
trimInputFieldsCsv,
214216
unsafeFakerExpressions,
215217
stream,
216218
} = payload;
@@ -242,6 +244,8 @@ export function createApiService({
242244
outputFormat: concreteOutputFormat,
243245
options: effectiveOptions,
244246
seed: parsedSeed.seed,
247+
trimInput: parseBooleanFlag(trimInput),
248+
trimInputFieldsCsv,
245249
unsafeFakerExpressions: unsafeFakerExpressions || false,
246250
stream,
247251
});

apps/api/src/openapi.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,16 @@ const openApiDocument = {
418418
outputFormat: { type: 'string', default: 'csv' },
419419
options: { type: 'object' },
420420
seed: { type: 'number' },
421+
trimInput: {
422+
type: 'boolean',
423+
default: false,
424+
description: 'Trim whitespace from every imported input field value before amend processing.',
425+
},
426+
trimInputFieldsCsv: {
427+
type: 'string',
428+
description:
429+
'Comma-separated imported field names whose values should be trimmed before amend processing.',
430+
},
421431
unsafeFakerExpressions: { type: 'boolean', default: false },
422432
responseFormat: { type: 'string', enum: ['rows', 'rendered', 'all', 'raw'], default: 'rows' },
423433
stream: { type: 'boolean', description: 'Accepted for compatibility and ignored for amend mode.' },

apps/api/src/tests/generate/v1-generate-amend.spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,21 @@ test.describe('POST /v1/generate/amend', () => {
4141
expect(Array.isArray(body.diagnostics)).toBe(false);
4242
expect(typeof body.diagnostics).toBe('object');
4343
});
44+
45+
test('amend trimInputFieldsCsv trims only listed imported columns', async ({ request }) => {
46+
const response = await request.post(apiUrl('/v1/generate/amend'), {
47+
data: {
48+
textSpec: 'Status\nActive',
49+
inputData: '"Name","Role"\n" Alice "," Engineer "',
50+
inputFormat: 'csv',
51+
rowCount: 0,
52+
outputFormat: 'json',
53+
trimInputFieldsCsv: 'Name',
54+
},
55+
});
56+
57+
expect(response.status()).toBe(200);
58+
const body = await response.json();
59+
expect(body.rows).toEqual([['Alice', ' Engineer ', '']]);
60+
});
4461
});

apps/api/src/tests/health/health-endpoints.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ test.describe('Health and docs endpoints', () => {
2424
expect(body.openapi).toBe('3.0.3');
2525
expect(body.paths['/v1/generate']).toBeTruthy();
2626
expect(body.paths['/v1/generate/amend']).toBeTruthy();
27+
expect(
28+
body.paths['/v1/generate/amend'].post.requestBody.content['application/json'].schema.properties.trimInput
29+
).toBeTruthy();
30+
expect(
31+
body.paths['/v1/generate/amend'].post.requestBody.content['application/json'].schema.properties.trimInputFieldsCsv
32+
).toBeTruthy();
2733
});
2834

2935
test('GET /v1/docs serves Swagger UI html', async ({ request }) => {

apps/cli/src/cli-options.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ export function parseCliOptions(argvInput = process.argv) {
1111
.option('schema-file', { type: 'string', describe: 'Schema file path for amend command' })
1212
.option('data-file', { type: 'string', describe: 'Input data file path for amend command' })
1313
.option('input-format', { type: 'string', describe: 'Input data format for amend command (e.g. csv, json)' })
14+
.option('trim-input', {
15+
type: 'boolean',
16+
default: false,
17+
describe: 'Trim whitespace from every imported input field value before amend processing',
18+
})
19+
.option('trim-input-fields', {
20+
type: 'string',
21+
describe: 'Comma-separated imported field names whose values should be trimmed before amend processing',
22+
})
1423
.option('n', {
1524
alias: 'numberOfLines',
1625
type: 'number',
@@ -93,5 +102,7 @@ export function parseCliOptions(argvInput = process.argv) {
93102
bom: parsed.bom === true,
94103
unsafeFakerExpressions: parsed['unsafe-faker-expressions'] === true,
95104
pairwise: parsed.pairwise === true,
105+
trimInput: command === 'amend' && parsed['trim-input'] === true,
106+
trimInputFieldsCsv: command === 'amend' ? parsed['trim-input-fields'] || '' : '',
96107
};
97108
}

apps/cli/src/run-cli.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ export async function runCliCommand({ options, platform }) {
9595
rowCount: options.rowCount,
9696
outputFormat,
9797
options: formatterOptions,
98+
trimInput: options.trimInput === true,
99+
trimInputFieldsCsv: options.trimInputFieldsCsv || '',
98100
unsafeFakerExpressions: options.unsafeFakerExpressions,
99101
stream: options.shouldStream,
100102
});

apps/cli/src/tests/cli-options.test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ test('amend command options are parsed', () => {
5252
'data.csv',
5353
'--input-format',
5454
'csv',
55+
'--trim-input',
56+
'--trim-input-fields',
57+
'Name,Role',
5558
'-n',
5659
'3',
5760
'-f',
@@ -63,6 +66,8 @@ test('amend command options are parsed', () => {
6366
expect(opts.inputFormat).toBe('csv');
6467
expect(opts.rowCount).toBe(3);
6568
expect(opts.shouldStream).toBe(false);
69+
expect(opts.trimInput).toBe(true);
70+
expect(opts.trimInputFieldsCsv).toBe('Name,Role');
6671
});
6772

6873
test('export encoding flags are parsed', () => {

apps/cli/src/tests/integration.cli-params.test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,33 @@ test('amend command applies schema to existing data', async () => {
205205
expect(JSON.parse(result.stdout.trim())).toEqual([{ Name: 'Bob' }, { Name: 'Eve' }]);
206206
});
207207

208+
test('amend command trim flags affect imported input values before amend processing', async () => {
209+
const schemaPath = tempFile('trim-schema');
210+
const dataPath = tempFile('trim-data');
211+
await fs.writeFile(schemaPath, 'Status\nActive', 'utf8');
212+
await fs.writeFile(dataPath, '"Name","Role"\n" Alice "," Engineer "', 'utf8');
213+
214+
const result = runCli([
215+
'amend',
216+
'--schema-file',
217+
schemaPath,
218+
'--data-file',
219+
dataPath,
220+
'--input-format',
221+
'csv',
222+
'--trim-input-fields',
223+
'Name',
224+
'-n',
225+
'0',
226+
'-f',
227+
'json',
228+
'--show-progress',
229+
'false',
230+
]);
231+
expect(result.status).toBe(0);
232+
expect(JSON.parse(result.stdout.trim())).toEqual([{ Name: 'Alice', Role: ' Engineer ', Status: '' }]);
233+
});
234+
208235
test('amend command fixture flow: CSV input to DSV output on stdout', async () => {
209236
const schemaPath = path.join(amendFixturesDir, 'schema.txt');
210237
const dataPath = path.join(amendFixturesDir, 'input.csv');

apps/mcp/src/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,15 @@ function handleRequest(request) {
328328
outputFormat: { type: 'string', enum: SUPPORTED_FORMATS },
329329
options: GENERATE_OPTIONS_SCHEMA,
330330
seed: { type: 'number' },
331+
trimInput: {
332+
type: 'boolean',
333+
description: 'Trim whitespace from every imported input field value before amend processing.',
334+
},
335+
trimInputFieldsCsv: {
336+
type: 'string',
337+
description:
338+
'Comma-separated imported field names whose values should be trimmed before amend processing.',
339+
},
331340
stream: {
332341
type: 'boolean',
333342
description: 'Accepted for compatibility and ignored for amend operation (always buffered).',

0 commit comments

Comments
 (0)