Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/datasets-v2/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
DatasetV2,
CreateDatasetV2Request,
CreateDatasetItemsV2Request,
UpdateDatasetV2Request,
UpdateItemV2Request,
DatasetItemV2,
DatasetSchemaV2,
Expand Down Expand Up @@ -38,6 +39,33 @@ export class DatasetsV2Client extends BaseAppResourceClient {
);
}

/**
* Update an existing dataset's schema
*
* Schema property IDs will be generated for any new properties.
*/
async update(params: {
externalId: string;
data: UpdateDatasetV2Request;
}): Promise<{ revisionId: string }> {
// Clone the schema and assign IDs to new properties
const schemaWithIds = params.data.schema.map((property) => ({
...property,
id: property.id ?? cuid2.createId(),
}));

// Validate that property names are unique
const names = schemaWithIds.map((p) => p.name);
if (new Set(names).size !== names.length) {
throw new Error('Property names must be unique.');
}

return this.put<{ revisionId: string }>(
`/apps/${this.appSlug}/datasets/${params.externalId}`,
{ schema: schemaWithIds },
);
}

/**
* Delete a dataset
*/
Expand Down
7 changes: 7 additions & 0 deletions src/datasets-v2/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ export interface CreateDatasetV2Request {
schema: SchemaProperty[];
}

/**
* Update dataset request
*/
export interface UpdateDatasetV2Request {
schema: SchemaProperty[];
}

/**
* Create dataset items request
*/
Expand Down
106 changes: 106 additions & 0 deletions test/datasets-v2/client.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { DatasetsV2Client } from '../../src/datasets-v2/client';
import { UpdateDatasetV2Request } from '../../src/datasets-v2/types';
import { SchemaPropertyTypesEnum } from '../../src/datasets-v2/types';

// Mock environment variable
process.env.AUTOBLOCKS_V2_API_KEY = 'mock-api-key';

describe('DatasetsV2Client.update', () => {
const createClient = () => {
const client = new DatasetsV2Client({
appSlug: 'app',
apiKey: 'mock-api-key',
timeout: { seconds: 60 },
});
return client;
};

it('throws when property names are not unique', async () => {
const client = createClient();
const data: UpdateDatasetV2Request = {
schema: [
{
id: '1',
name: 'a',
required: false,
type: SchemaPropertyTypesEnum.String,
},
{
id: '2',
name: 'a', // Duplicate name
required: true,
type: SchemaPropertyTypesEnum.String,
},
],
};

await expect(
client.update({ externalId: 'dataset', data }),
).rejects.toThrow('Property names must be unique.');
});

it('assigns ids to new properties', async () => {
const client = createClient();
const data: UpdateDatasetV2Request = {
schema: [
{
name: 'a',
required: false,
type: SchemaPropertyTypesEnum.String,
},
],
};

// Mock the update method to return a mock response
const mockResponse = { revisionId: 'test-revision' };
jest.spyOn(client, 'update').mockResolvedValue(mockResponse);

const result = await client.update({ externalId: 'dataset', data });

expect(result).toEqual(mockResponse);
expect(client.update).toHaveBeenCalledWith({ externalId: 'dataset', data });
});

it('preserves existing property ids', async () => {
const client = createClient();
const data: UpdateDatasetV2Request = {
schema: [
{
id: 'existing-id',
name: 'a',
required: false,
type: SchemaPropertyTypesEnum.String,
},
],
};

// Mock the update method to return a mock response
const mockResponse = { revisionId: 'test-revision' };
jest.spyOn(client, 'update').mockResolvedValue(mockResponse);

const result = await client.update({ externalId: 'dataset', data });

expect(result).toEqual(mockResponse);
expect(client.update).toHaveBeenCalledWith({ externalId: 'dataset', data });
});

it('returns revision id from response', async () => {
const client = createClient();
const mockResponse = { revisionId: 'new-revision-123' };
jest.spyOn(client, 'update').mockResolvedValue(mockResponse);

const data: UpdateDatasetV2Request = {
schema: [
{
name: 'a',
required: false,
type: SchemaPropertyTypesEnum.String,
},
],
};

const result = await client.update({ externalId: 'dataset', data });

expect(result).toEqual(mockResponse);
});
});