From cc6f62229ed066c326de86ec16c447ab03ffc0a7 Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Tue, 19 Dec 2023 08:44:27 +0100 Subject: [PATCH 01/22] Start pre mode Signed-off-by: Alexis Rico --- .changeset/pre.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .changeset/pre.json diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 000000000..80aba5e0e --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,17 @@ +{ + "mode": "pre", + "tag": "next", + "initialVersions": { + "@xata.io/cli": "0.15.3", + "@xata.io/client": "0.28.2", + "@xata.io/codegen": "0.28.2", + "@xata.io/importer": "1.1.3", + "@xata.io/plugin-client-cache": "0.1.39", + "@xata.io/plugin-client-cloudflare": "0.0.38", + "@xata.io/drizzle": "0.0.13", + "@xata.io/kysely": "0.1.13", + "@xata.io/netlify": "0.1.23", + "@xata.io/plugin-client-opentelemetry": "0.2.37" + }, + "changesets": [] +} From a33e0623754650832dd94255e701d17a3f186672 Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Tue, 19 Dec 2023 10:27:46 +0100 Subject: [PATCH 02/22] Init version 1.0 Signed-off-by: Alexis Rico --- .changeset/violet-worms-develop.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .changeset/violet-worms-develop.md diff --git a/.changeset/violet-worms-develop.md b/.changeset/violet-worms-develop.md new file mode 100644 index 000000000..353605dbd --- /dev/null +++ b/.changeset/violet-worms-develop.md @@ -0,0 +1,14 @@ +--- +'@xata.io/cli': major +'@xata.io/client': major +'@xata.io/codegen': major +'@xata.io/importer': major +'@xata.io/plugin-client-cache': major +'@xata.io/plugin-client-cloudflare': major +'@xata.io/drizzle': major +'@xata.io/kysely': major +'@xata.io/netlify': major +'@xata.io/plugin-client-opentelemetry': major +--- + +Version 1.0 From a0ea12b582361348fae717792585da426e719df0 Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Tue, 9 Jan 2024 08:59:44 +0100 Subject: [PATCH 03/22] Make XataApiClient to use ES Proxies (#1287) --- .changeset/light-cycles-repair.md | 5 + cli/src/base.ts | 36 +- cli/src/commands/branch/create.ts | 5 +- cli/src/commands/branch/delete.ts | 2 +- cli/src/commands/branch/list.ts | 2 +- cli/src/commands/dbs/delete.ts | 2 +- cli/src/commands/dbs/list.ts | 4 +- cli/src/commands/dbs/rename.ts | 5 +- cli/src/commands/diff/index.ts | 18 +- cli/src/commands/import/csv.ts | 14 +- cli/src/commands/init/index.ts | 4 +- cli/src/commands/pull/index.ts | 20 +- cli/src/commands/push/index.ts | 37 +- cli/src/commands/random-data/index.ts | 8 +- cli/src/commands/rebase/index.ts | 13 +- cli/src/commands/schema/edit.ts | 7 +- cli/src/commands/schema/upload.ts | 12 +- cli/src/commands/workspace/create.ts | 2 +- cli/src/commands/workspace/delete.ts | 2 +- cli/src/migrations/pgroll.ts | 8 +- packages/client/src/api/client.test.ts | 26 + packages/client/src/api/client.ts | 2028 +----------------------- packages/client/src/util/types.ts | 8 + test/integration/query.test.ts | 14 +- test/integration/smoke.test.ts | 95 +- test/utils/setup.ts | 21 +- 26 files changed, 255 insertions(+), 2143 deletions(-) create mode 100644 .changeset/light-cycles-repair.md create mode 100644 packages/client/src/api/client.test.ts diff --git a/.changeset/light-cycles-repair.md b/.changeset/light-cycles-repair.md new file mode 100644 index 000000000..61c123457 --- /dev/null +++ b/.changeset/light-cycles-repair.md @@ -0,0 +1,5 @@ +--- +"@xata.io/client": major +--- + +Make XataApiClient to use ES Proxies diff --git a/cli/src/base.ts b/cli/src/base.ts index d0fdb46b9..93860bf55 100644 --- a/cli/src/base.ts +++ b/cli/src/base.ts @@ -281,7 +281,7 @@ export abstract class BaseCommand extends Command { message: 'New workspace name' }); if (!name) return this.error('No workspace name provided'); - const workspace = await xata.api.workspaces.createWorkspace({ data: { name } }); + const workspace = await xata.api.workspaces.createWorkspace({ body: { name } }); return workspace.id; } else if (workspaces.workspaces.length === 1) { const workspace = workspaces.workspaces[0].id; @@ -309,7 +309,9 @@ export abstract class BaseCommand extends Command { options: { allowCreate?: boolean } = {} ): Promise<{ name: string; region: string }> { const xata = await this.getXataClient(); - const { databases: dbs = [] } = await xata.api.database.getDatabaseList({ workspace }); + const { databases: dbs = [] } = await xata.api.databases.getDatabaseList({ + pathParams: { workspaceId: workspace } + }); if (dbs.length > 0) { const choices = dbs.map((db) => ({ @@ -355,7 +357,9 @@ export abstract class BaseCommand extends Command { } = {} ): Promise { const xata = await this.getXataClient(); - const { branches = [] } = await xata.api.branches.getBranchList({ workspace, region, database }); + const { branches = [] } = await xata.api.branch.getBranchList({ + pathParams: { workspace, region, dbName: database } + }); const EMPTY_CHOICE = '$empty'; const CREATE_CHOICE = '$create'; @@ -421,7 +425,7 @@ export abstract class BaseCommand extends Command { ); if (!name) return this.error('No database name provided'); - const { regions } = await xata.api.database.listRegions({ workspace }); + const { regions } = await xata.api.databases.listRegions({ pathParams: { workspaceId: workspace } }); const { region } = await this.prompt( { type: 'select', @@ -434,7 +438,10 @@ export abstract class BaseCommand extends Command { ); if (!region) return this.error('No region selected'); - const result = await xata.api.database.createDatabase({ workspace, database: name, data: { region } }); + const result = await xata.api.databases.createDatabase({ + pathParams: { workspaceId: workspace, dbName: name }, + body: { region } + }); return { name: result.databaseName, region }; } @@ -455,9 +462,12 @@ export abstract class BaseCommand extends Command { }); if (!from) { - await xata.api.branches.createBranch({ workspace, region, database, branch: name }); + await xata.api.branch.createBranch({ pathParams: { workspace, region, dbBranchName: `${database}:${name}` } }); } else { - await xata.api.branches.createBranch({ workspace, region, database, branch: name, from }); + await xata.api.branch.createBranch({ + pathParams: { workspace, region, dbBranchName: `${database}:${name}` }, + body: { from } + }); } return name; @@ -566,11 +576,8 @@ export abstract class BaseCommand extends Command { async deploySchema(workspace: string, region: string, database: string, branch: string, schema: Schemas.Schema) { const xata = await this.getXataClient(); const compare = await xata.api.migrations.compareBranchWithUserSchema({ - workspace, - region, - database, - branch, - schema + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { schema } }); if (compare.edits.operations.length === 0) { @@ -587,7 +594,10 @@ export abstract class BaseCommand extends Command { }); if (!confirm) return this.exit(1); - await xata.api.migrations.applyBranchSchemaEdit({ workspace, region, database, branch, edits: compare.edits }); + await xata.api.migrations.applyBranchSchemaEdit({ + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { edits: compare.edits } + }); } } diff --git a/cli/src/commands/branch/create.ts b/cli/src/commands/branch/create.ts index 3dac4c9c4..6d25500b7 100644 --- a/cli/src/commands/branch/create.ts +++ b/cli/src/commands/branch/create.ts @@ -32,7 +32,10 @@ export default class BranchCreate extends BaseCommand { const { from } = flags; try { - const result = await xata.api.branches.createBranch({ workspace, region, database, branch, from }); + const result = await xata.api.branch.createBranch({ + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { from } + }); if (this.jsonEnabled()) return result; diff --git a/cli/src/commands/branch/delete.ts b/cli/src/commands/branch/delete.ts index 1f865dfed..1b230a658 100644 --- a/cli/src/commands/branch/delete.ts +++ b/cli/src/commands/branch/delete.ts @@ -37,7 +37,7 @@ export default class BranchDelete extends BaseCommand { if (!confirm) return this.exit(1); if (confirm !== branch) return this.error('The branch name did not match'); - await xata.api.branches.deleteBranch({ workspace, region, database, branch }); + await xata.api.branch.deleteBranch({ pathParams: { workspace, region, dbBranchName: `${database}:${branch}` } }); if (this.jsonEnabled()) return {}; diff --git a/cli/src/commands/branch/list.ts b/cli/src/commands/branch/list.ts index 2c32536e3..f1d3c603c 100644 --- a/cli/src/commands/branch/list.ts +++ b/cli/src/commands/branch/list.ts @@ -19,7 +19,7 @@ export default class BranchList extends BaseCommand { const { workspace, region, database } = await this.getParsedDatabaseURL(flags.db); const xata = await this.getXataClient(); - const { branches } = await xata.api.branches.getBranchList({ workspace, region, database }); + const { branches } = await xata.api.branch.getBranchList({ pathParams: { workspace, region, dbName: database } }); if (this.jsonEnabled()) return branches; diff --git a/cli/src/commands/dbs/delete.ts b/cli/src/commands/dbs/delete.ts index 708a92bd4..a7a3302ff 100644 --- a/cli/src/commands/dbs/delete.ts +++ b/cli/src/commands/dbs/delete.ts @@ -39,7 +39,7 @@ export default class DatabasesDelete extends BaseCommand if (!confirm) return this.exit(1); if (confirm !== database) return this.error('The database name did not match'); - await xata.api.database.deleteDatabase({ workspace, database }); + await xata.api.databases.deleteDatabase({ pathParams: { workspaceId: workspace, dbName: database } }); if (this.jsonEnabled()) return {}; diff --git a/cli/src/commands/dbs/list.ts b/cli/src/commands/dbs/list.ts index bbcfdf8d5..104f7c5bf 100644 --- a/cli/src/commands/dbs/list.ts +++ b/cli/src/commands/dbs/list.ts @@ -25,7 +25,9 @@ export default class DatabasesList extends BaseCommand { (await this.getWorkspace()); const xata = await this.getXataClient(); - const { databases: dbs = [] } = await xata.api.database.getDatabaseList({ workspace }); + const { databases: dbs = [] } = await xata.api.databases.getDatabaseList({ + pathParams: { workspaceId: workspace } + }); if (this.jsonEnabled()) return dbs; diff --git a/cli/src/commands/dbs/rename.ts b/cli/src/commands/dbs/rename.ts index 0ce21e160..244ae83d2 100644 --- a/cli/src/commands/dbs/rename.ts +++ b/cli/src/commands/dbs/rename.ts @@ -43,7 +43,10 @@ export default class DatabasesRename extends BaseCommand if (!confirm) return this.exit(1); if (confirm !== database) return this.error('The database name did not match'); - await xata.api.database.renameDatabase({ workspace, database, newName }); + await xata.api.databases.renameDatabase({ + pathParams: { workspaceId: workspace, dbName: database }, + body: { newName } + }); if (this.jsonEnabled()) return {}; diff --git a/cli/src/commands/diff/index.ts b/cli/src/commands/diff/index.ts index a171ed9a6..e3d6ca7d4 100644 --- a/cli/src/commands/diff/index.ts +++ b/cli/src/commands/diff/index.ts @@ -2,6 +2,7 @@ import { Args } from '@oclif/core'; import { BaseCommand } from '../../base.js'; import { getLocalMigrationFiles } from '../../migrations/files.js'; import { buildMigrationDiff } from '../../utils/diff.js'; +import compact from 'lodash.compact'; export default class Diff extends BaseCommand { static description = 'Compare two local or remote branches'; @@ -34,24 +35,17 @@ export default class Diff extends BaseCommand { this.info(`Diff command is experimental, use with caution`); const localMigrationFiles = await getLocalMigrationFiles(); - const schemaOperations = localMigrationFiles.flatMap((migrationFile) => migrationFile.operations); + const schemaOperations = compact(localMigrationFiles.flatMap((migrationFile) => migrationFile.operations)); const apiRequest = args.branch && args.base ? xata.api.migrations.compareBranchSchemas({ - workspace, - region, - database, - branch: args.branch, - compare: args.base + pathParams: { workspace, region, dbBranchName: `${database}:${args.branch}`, branchName: args.base }, + body: {} }) : xata.api.migrations.compareBranchWithUserSchema({ - workspace, - region, - database, - branch, - schema: { tables: [] }, - schemaOperations: schemaOperations as any + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { schema: { tables: [] }, schemaOperations } }); const { diff --git a/cli/src/commands/import/csv.ts b/cli/src/commands/import/csv.ts index 5ee9d6fbc..762d78b64 100644 --- a/cli/src/commands/import/csv.ts +++ b/cli/src/commands/import/csv.ts @@ -218,12 +218,10 @@ export default class ImportCSV extends BaseCommand { { name: table, columns: columns.filter((c) => c.name !== 'id') } ] }; + const { edits } = await xata.api.migrations.compareBranchWithUserSchema({ - workspace, - region, - database, - branch: 'main', - schema: newSchema + pathParams: { workspace, region, dbBranchName: `${database}:main` }, + body: { schema: newSchema } }); if (edits.operations.length > 0) { const destructiveOperations = edits.operations @@ -263,7 +261,11 @@ export default class ImportCSV extends BaseCommand { if (!applyMigrations) { process.exit(1); } - await xata.api.migrations.applyBranchSchemaEdit({ workspace, region, database, branch, edits }); + + await xata.api.migrations.applyBranchSchemaEdit({ + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { edits } + }); } } } diff --git a/cli/src/commands/init/index.ts b/cli/src/commands/init/index.ts index a26e643f3..8cf58939d 100644 --- a/cli/src/commands/init/index.ts +++ b/cli/src/commands/init/index.ts @@ -187,7 +187,7 @@ export default class Init extends BaseCommand { if (this.projectConfig?.codegen?.output) { const { schema: currentSchema } = await ( await this.getXataClient() - ).api.branches.getBranchDetails({ workspace, database, region, branch }); + ).api.branch.getBranchDetails({ pathParams: { workspace, region, dbBranchName: `${database}:${branch}` } }); const hasTables = currentSchema?.tables && currentSchema?.tables.length > 0; const hasColumns = currentSchema?.tables.some((t) => t.columns.length > 0); @@ -434,7 +434,7 @@ export default class Init extends BaseCommand { let retries = 0; while (retries++ < maxRetries) { try { - await xata.api.branches.getBranchList({ workspace, region, database }); + await xata.api.branch.getBranchList({ pathParams: { workspace, region, dbName: database } }); return; } catch (err) { if (err instanceof Error && err.message.includes('Invalid API key')) { diff --git a/cli/src/commands/pull/index.ts b/cli/src/commands/pull/index.ts index 0c51b45b0..0f43064fe 100644 --- a/cli/src/commands/pull/index.ts +++ b/cli/src/commands/pull/index.ts @@ -53,22 +53,18 @@ export default class Pull extends BaseCommand { let logs: Schemas.MigrationHistoryItem[] | Schemas.Commit[] = []; if (isBranchPgRollEnabled(details)) { - const { migrations } = await xata.api.branches.pgRollMigrationHistory({ - workspace, - region, - database, - branch + const { migrations } = await xata.api.branch.pgRollMigrationHistory({ + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` } }); logs = migrations; } else { const data = await xata.api.migrations.getBranchSchemaHistory({ - workspace, - region, - database, - branch, - // TODO: Fix pagination in the API to start from last known migration and not from the beginning - // Also paginate until we get all migrations - page: { size: 200 } + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { + // TODO: Fix pagination in the API to start from last known migration and not from the beginning + // Also paginate until we get all migrations + page: { size: 200 } + } }); logs = data.logs; } diff --git a/cli/src/commands/push/index.ts b/cli/src/commands/push/index.ts index 4a2d3fb96..70f016906 100644 --- a/cli/src/commands/push/index.ts +++ b/cli/src/commands/push/index.ts @@ -49,22 +49,18 @@ export default class Push extends BaseCommand { let logs: Schemas.MigrationHistoryItem[] | Schemas.Commit[] = []; if (isBranchPgRollEnabled(details)) { - const { migrations } = await xata.api.branches.pgRollMigrationHistory({ - workspace, - region, - database, - branch + const { migrations } = await xata.api.branch.pgRollMigrationHistory({ + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` } }); logs = migrations; } else { const data = await xata.api.migrations.getBranchSchemaHistory({ - workspace, - region, - database, - branch, - // TODO: Fix pagination in the API to start from last known migration and not from the beginning - // Also paginate until we get all migrations - page: { size: 200 } + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { + // TODO: Fix pagination in the API to start from last known migration and not from the beginning + // Also paginate until we get all migrations + page: { size: 200 } + } }); logs = data.logs; } @@ -107,13 +103,9 @@ export default class Push extends BaseCommand { .flatMap((migration) => PgRollMigrationDefinition.parse(migration)); for (const migration of migrationsToPush) { try { - await xata.api.branches.applyMigration({ - workspace, - region, - database, - branch, - // @ts-expect-error Backend API spec doesn't know all pgroll migrations yet - migration + await xata.api.branch.applyMigration({ + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: migration }); } catch (e) { this.log(`Failed to push ${migration} with ${e}. Stopping.`); @@ -123,11 +115,8 @@ export default class Push extends BaseCommand { } else { // TODO: Check for errors and print them await xata.api.migrations.pushBranchMigrations({ - workspace, - region, - database, - branch, - migrations: newMigrations as Schemas.MigrationObject[] + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { migrations: newMigrations as Schemas.MigrationObject[] } }); } diff --git a/cli/src/commands/random-data/index.ts b/cli/src/commands/random-data/index.ts index 49c34bbb0..be7e434a1 100644 --- a/cli/src/commands/random-data/index.ts +++ b/cli/src/commands/random-data/index.ts @@ -52,12 +52,8 @@ export default class RandomData extends BaseCommand { const records = generateRandomData(table, totalRecords); await xata.api.records.bulkInsertTableRecords({ - workspace, - region, - database, - branch, - table: table.name, - records + pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table.name }, + body: { records: records as any[] } }); this.info( diff --git a/cli/src/commands/rebase/index.ts b/cli/src/commands/rebase/index.ts index 20d7c9824..c23aba2e6 100644 --- a/cli/src/commands/rebase/index.ts +++ b/cli/src/commands/rebase/index.ts @@ -37,13 +37,12 @@ export default class Rebase extends BaseCommand { this.info(`Rebase command is experimental, use with caution`); const { logs } = await xata.api.migrations.getBranchSchemaHistory({ - workspace, - region, - database, - branch, - // TODO: Fix pagination in the API to start from last known migration and not from the beginning - // Also paginate until we get all migrations - page: { size: 200 } + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { + // TODO: Fix pagination in the API to start from last known migration and not from the beginning + // Also paginate until we get all migrations + page: { size: 200 } + } }); const remoteMigrationFiles = commitToMigrationFile(logs); diff --git a/cli/src/commands/schema/edit.ts b/cli/src/commands/schema/edit.ts index eddb5f20b..3d2ef7277 100644 --- a/cli/src/commands/schema/edit.ts +++ b/cli/src/commands/schema/edit.ts @@ -807,11 +807,8 @@ vectorDimension: \${vectorDimension} } await xata.api.migrations.applyBranchSchemaEdit({ - workspace, - region, - database, - branch, - edits + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { edits } }); this.success('Migration completed!'); diff --git a/cli/src/commands/schema/upload.ts b/cli/src/commands/schema/upload.ts index ca9d016f2..e91e83487 100644 --- a/cli/src/commands/schema/upload.ts +++ b/cli/src/commands/schema/upload.ts @@ -49,11 +49,8 @@ export default class UploadSchema extends BaseCommand { } const { edits } = await xata.api.migrations.compareBranchWithUserSchema({ - workspace, - region, - database, - branch, - schema + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { schema } }); if (edits.operations.length === 0) { @@ -72,6 +69,9 @@ export default class UploadSchema extends BaseCommand { }); if (!confirm) return this.exit(1); - await xata.api.migrations.applyBranchSchemaEdit({ workspace, region, database, branch, edits }); + await xata.api.migrations.applyBranchSchemaEdit({ + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, + body: { edits } + }); } } diff --git a/cli/src/commands/workspace/create.ts b/cli/src/commands/workspace/create.ts index 0c7bf3541..de24b4960 100644 --- a/cli/src/commands/workspace/create.ts +++ b/cli/src/commands/workspace/create.ts @@ -26,7 +26,7 @@ export default class WorkspaceCreate extends BaseCommand const xata = await this.getXataClient(); - const result = await xata.api.workspaces.createWorkspace({ data: { name: workspace } }); + const result = await xata.api.workspaces.createWorkspace({ body: { name: workspace } }); if (this.jsonEnabled()) return result; diff --git a/cli/src/commands/workspace/delete.ts b/cli/src/commands/workspace/delete.ts index 02763e73a..719f2bd9b 100644 --- a/cli/src/commands/workspace/delete.ts +++ b/cli/src/commands/workspace/delete.ts @@ -35,7 +35,7 @@ export default class WorkspaceDelete extends BaseCommand if (!confirm) return this.exit(1); if (confirm !== workspace) return this.error('The workspace name did not match'); - await xata.api.workspaces.deleteWorkspace({ workspace }); + await xata.api.workspaces.deleteWorkspace({ pathParams: { workspaceId: workspace } }); if (this.jsonEnabled()) return {}; diff --git a/cli/src/migrations/pgroll.ts b/cli/src/migrations/pgroll.ts index 591a5d39e..4028d220c 100644 --- a/cli/src/migrations/pgroll.ts +++ b/cli/src/migrations/pgroll.ts @@ -79,10 +79,14 @@ export async function getBranchDetailsWithPgRoll( xata: XataClient, { workspace, region, database, branch }: { workspace: string; region: string; database: string; branch: string } ): Promise { - const details = await xata.api.branches.getBranchDetails({ workspace, region, database, branch }); + const details = await xata.api.branch.getBranchDetails({ + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` } + }); if (isBranchPgRollEnabled(details)) { - const pgroll = await xata.api.migrations.getSchema({ workspace, region, database, branch }); + const pgroll = await xata.api.migrations.getSchema({ + pathParams: { workspace, region, dbBranchName: `${database}:${branch}` } + }); return { ...details, diff --git a/packages/client/src/api/client.test.ts b/packages/client/src/api/client.test.ts new file mode 100644 index 000000000..b6ac59138 --- /dev/null +++ b/packages/client/src/api/client.test.ts @@ -0,0 +1,26 @@ +import { describe, expect, test } from 'vitest'; +import { XataApiClient } from './client'; +import { operationsByTag } from './components'; + +const xata = new XataApiClient({ apiKey: 'fake-api-key' }); + +describe('API Proxy types', () => { + test('returns functions for all defined namespace operations', () => { + for (const namespace of Object.keys(operationsByTag)) { + const operationsInNamespace = operationsByTag[namespace as keyof typeof operationsByTag]; + for (const operation of Object.keys(operationsInNamespace)) { + expect(operationsInNamespace[operation as keyof typeof operationsInNamespace]).toBeInstanceOf(Function); + } + } + }); + + test('returns undefined for undefined namespaces', () => { + // @ts-expect-error Not a valid namespace + expect(xata.undefinedNamespace).toBeUndefined(); + }); + + test('returns undefined for undefined namespace operations', () => { + // @ts-expect-error Not a valid operation + expect(xata.authentication.undefinedOperation).toBeUndefined(); + }); +}); diff --git a/packages/client/src/api/client.ts b/packages/client/src/api/client.ts index cd7ddc9e6..67eb2c989 100644 --- a/packages/client/src/api/client.ts +++ b/packages/client/src/api/client.ts @@ -1,14 +1,11 @@ import { defaultTrace, TraceFunction } from '../schema/tracing'; import { getAPIKey } from '../util/environment'; import { FetchImpl, getFetchImplementation } from '../util/fetch'; +import { RequiredKeys } from '../util/types'; import { generateUUID } from '../util/uuid'; -import type * as Components from './components'; -import type * as Types from './components'; import { operationsByTag } from './components'; import type { FetcherExtraProps } from './fetcher'; import { getHostUrl, HostProvider } from './providers'; -import type * as Responses from './responses'; -import type * as Schemas from './schemas'; export type ApiExtraProps = Omit; @@ -21,1961 +18,72 @@ export interface XataApiClientOptions { xataAgentExtra?: Record; } -export class XataApiClient { - #extraProps: ApiExtraProps; - #namespaces: Partial<{ - user: UserApi; - authentication: AuthenticationApi; - workspaces: WorkspaceApi; - invites: InvitesApi; - database: DatabaseApi; - branches: BranchApi; - migrations: MigrationsApi; - migrationRequests: MigrationRequestsApi; - tables: TableApi; - records: RecordsApi; - files: FilesApi; - searchAndFilter: SearchAndFilterApi; - }> = {}; - - constructor(options: XataApiClientOptions = {}) { - const provider = options.host ?? 'production'; - const apiKey = options.apiKey ?? getAPIKey(); - const trace = options.trace ?? defaultTrace; - const clientID = generateUUID(); - - if (!apiKey) { - throw new Error('Could not resolve a valid apiKey'); - } - - this.#extraProps = { - apiUrl: getHostUrl(provider, 'main'), - workspacesApiUrl: getHostUrl(provider, 'workspaces'), - fetch: getFetchImplementation(options.fetch), - apiKey, - trace, - clientName: options.clientName, - xataAgentExtra: options.xataAgentExtra, - clientID - }; - } - - public get user() { - if (!this.#namespaces.user) this.#namespaces.user = new UserApi(this.#extraProps); - return this.#namespaces.user; - } - - public get authentication() { - if (!this.#namespaces.authentication) this.#namespaces.authentication = new AuthenticationApi(this.#extraProps); - return this.#namespaces.authentication; - } - - public get workspaces() { - if (!this.#namespaces.workspaces) this.#namespaces.workspaces = new WorkspaceApi(this.#extraProps); - return this.#namespaces.workspaces; - } - - public get invites() { - if (!this.#namespaces.invites) this.#namespaces.invites = new InvitesApi(this.#extraProps); - return this.#namespaces.invites; - } - - public get database() { - if (!this.#namespaces.database) this.#namespaces.database = new DatabaseApi(this.#extraProps); - return this.#namespaces.database; - } - - public get branches() { - if (!this.#namespaces.branches) this.#namespaces.branches = new BranchApi(this.#extraProps); - return this.#namespaces.branches; - } - - public get migrations() { - if (!this.#namespaces.migrations) this.#namespaces.migrations = new MigrationsApi(this.#extraProps); - return this.#namespaces.migrations; - } - - public get migrationRequests() { - if (!this.#namespaces.migrationRequests) - this.#namespaces.migrationRequests = new MigrationRequestsApi(this.#extraProps); - return this.#namespaces.migrationRequests; - } - - public get tables() { - if (!this.#namespaces.tables) this.#namespaces.tables = new TableApi(this.#extraProps); - return this.#namespaces.tables; - } - - public get records() { - if (!this.#namespaces.records) this.#namespaces.records = new RecordsApi(this.#extraProps); - return this.#namespaces.records; - } - - public get files() { - if (!this.#namespaces.files) this.#namespaces.files = new FilesApi(this.#extraProps); - return this.#namespaces.files; - } - - public get searchAndFilter() { - if (!this.#namespaces.searchAndFilter) this.#namespaces.searchAndFilter = new SearchAndFilterApi(this.#extraProps); - return this.#namespaces.searchAndFilter; - } -} - -class UserApi { - constructor(private extraProps: ApiExtraProps) {} - - public getUser(): Promise { - return operationsByTag.users.getUser({ ...this.extraProps }); - } - - public updateUser({ user }: { user: Schemas.User }): Promise { - return operationsByTag.users.updateUser({ body: user, ...this.extraProps }); - } - - public deleteUser(): Promise { - return operationsByTag.users.deleteUser({ ...this.extraProps }); - } -} - -class AuthenticationApi { - constructor(private extraProps: ApiExtraProps) {} - - public getUserAPIKeys(): Promise { - return operationsByTag.authentication.getUserAPIKeys({ ...this.extraProps }); - } - - public createUserAPIKey({ name }: { name: Schemas.APIKeyName }): Promise { - return operationsByTag.authentication.createUserAPIKey({ - pathParams: { keyName: name }, - ...this.extraProps - }); - } - - public deleteUserAPIKey({ name }: { name: Schemas.APIKeyName }): Promise { - return operationsByTag.authentication.deleteUserAPIKey({ - pathParams: { keyName: name }, - ...this.extraProps - }); - } -} - -class WorkspaceApi { - constructor(private extraProps: ApiExtraProps) {} - - public getWorkspacesList(): Promise { - return operationsByTag.workspaces.getWorkspacesList({ ...this.extraProps }); - } - - public createWorkspace({ data }: { data: Schemas.WorkspaceMeta }): Promise { - return operationsByTag.workspaces.createWorkspace({ - body: data, - ...this.extraProps - }); - } - - public getWorkspace({ workspace }: { workspace: Schemas.WorkspaceID }): Promise { - return operationsByTag.workspaces.getWorkspace({ - pathParams: { workspaceId: workspace }, - ...this.extraProps - }); - } - - public updateWorkspace({ - workspace, - update - }: { - workspace: Schemas.WorkspaceID; - update: Schemas.WorkspaceMeta; - }): Promise { - return operationsByTag.workspaces.updateWorkspace({ - pathParams: { workspaceId: workspace }, - body: update, - ...this.extraProps - }); - } - - public deleteWorkspace({ workspace }: { workspace: Schemas.WorkspaceID }): Promise { - return operationsByTag.workspaces.deleteWorkspace({ - pathParams: { workspaceId: workspace }, - ...this.extraProps - }); - } - - public getWorkspaceMembersList({ workspace }: { workspace: Schemas.WorkspaceID }): Promise { - return operationsByTag.workspaces.getWorkspaceMembersList({ - pathParams: { workspaceId: workspace }, - ...this.extraProps - }); - } - - public updateWorkspaceMemberRole({ - workspace, - user, - role - }: { - workspace: Schemas.WorkspaceID; - user: Schemas.UserID; - role: Schemas.Role; - }): Promise { - return operationsByTag.workspaces.updateWorkspaceMemberRole({ - pathParams: { workspaceId: workspace, userId: user }, - body: { role }, - ...this.extraProps - }); - } - - public removeWorkspaceMember({ - workspace, - user - }: { - workspace: Schemas.WorkspaceID; - user: Schemas.UserID; - }): Promise { - return operationsByTag.workspaces.removeWorkspaceMember({ - pathParams: { workspaceId: workspace, userId: user }, - ...this.extraProps - }); - } -} - -class InvitesApi { - constructor(private extraProps: ApiExtraProps) {} - - public inviteWorkspaceMember({ - workspace, - email, - role - }: { - workspace: Schemas.WorkspaceID; - email: string; - role: Schemas.Role; - }): Promise { - return operationsByTag.invites.inviteWorkspaceMember({ - pathParams: { workspaceId: workspace }, - body: { email, role }, - ...this.extraProps - }); - } - - public updateWorkspaceMemberInvite({ - workspace, - invite, - role - }: { - workspace: Schemas.WorkspaceID; - invite: Schemas.InviteID; - role: Schemas.Role; - }): Promise { - return operationsByTag.invites.updateWorkspaceMemberInvite({ - pathParams: { workspaceId: workspace, inviteId: invite }, - body: { role }, - ...this.extraProps - }); - } - - public cancelWorkspaceMemberInvite({ - workspace, - invite - }: { - workspace: Schemas.WorkspaceID; - invite: Schemas.InviteID; - }): Promise { - return operationsByTag.invites.cancelWorkspaceMemberInvite({ - pathParams: { workspaceId: workspace, inviteId: invite }, - ...this.extraProps - }); - } - - public acceptWorkspaceMemberInvite({ - workspace, - key - }: { - workspace: Schemas.WorkspaceID; - key: Schemas.InviteKey; - }): Promise { - return operationsByTag.invites.acceptWorkspaceMemberInvite({ - pathParams: { workspaceId: workspace, inviteKey: key }, - ...this.extraProps - }); - } - - public resendWorkspaceMemberInvite({ - workspace, - invite - }: { - workspace: Schemas.WorkspaceID; - invite: Schemas.InviteID; - }): Promise { - return operationsByTag.invites.resendWorkspaceMemberInvite({ - pathParams: { workspaceId: workspace, inviteId: invite }, - ...this.extraProps - }); - } -} - -class BranchApi { - constructor(private extraProps: ApiExtraProps) {} - - public getBranchList({ - workspace, - region, - database - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - }): Promise { - return operationsByTag.branch.getBranchList({ - pathParams: { workspace, region, dbName: database }, - ...this.extraProps - }); - } - - public getBranchDetails({ - workspace, - region, - database, - branch - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - }): Promise { - return operationsByTag.branch.getBranchDetails({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - ...this.extraProps - }); - } - - public createBranch({ - workspace, - region, - database, - branch, - from, - metadata - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - from?: string; - metadata?: Schemas.BranchMetadata; - }): Promise { - return operationsByTag.branch.createBranch({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: { from, metadata }, - ...this.extraProps - }); - } - - public deleteBranch({ - workspace, - region, - database, - branch - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - }): Promise { - return operationsByTag.branch.deleteBranch({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - ...this.extraProps - }); - } - - public copyBranch({ - workspace, - region, - database, - branch, - destinationBranch, - limit - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - destinationBranch: Schemas.BranchName; - limit?: number; - }): Promise { - return operationsByTag.branch.copyBranch({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: { destinationBranch, limit }, - ...this.extraProps - }); - } - - public updateBranchMetadata({ - workspace, - region, - database, - branch, - metadata - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - metadata: Schemas.BranchMetadata; - }): Promise { - return operationsByTag.branch.updateBranchMetadata({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: metadata, - ...this.extraProps - }); - } - - public getBranchMetadata({ - workspace, - region, - database, - branch - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - }): Promise { - return operationsByTag.branch.getBranchMetadata({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - ...this.extraProps - }); - } - - public getBranchStats({ - workspace, - region, - database, - branch - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - }): Promise { - return operationsByTag.branch.getBranchStats({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - ...this.extraProps - }); - } - - public getGitBranchesMapping({ - workspace, - region, - database - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - }): Promise { - return operationsByTag.branch.getGitBranchesMapping({ - pathParams: { workspace, region, dbName: database }, - ...this.extraProps - }); - } - - public addGitBranchesEntry({ - workspace, - region, - database, - gitBranch, - xataBranch - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - gitBranch: string; - xataBranch: Schemas.BranchName; - }): Promise { - return operationsByTag.branch.addGitBranchesEntry({ - pathParams: { workspace, region, dbName: database }, - body: { gitBranch, xataBranch }, - ...this.extraProps - }); - } - - public removeGitBranchesEntry({ - workspace, - region, - database, - gitBranch - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - gitBranch: string; - }): Promise { - return operationsByTag.branch.removeGitBranchesEntry({ - pathParams: { workspace, region, dbName: database }, - queryParams: { gitBranch }, - ...this.extraProps - }); - } - - public resolveBranch({ - workspace, - region, - database, - gitBranch, - fallbackBranch - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - gitBranch?: string; - fallbackBranch?: string; - }): Promise { - return operationsByTag.branch.resolveBranch({ - pathParams: { workspace, region, dbName: database }, - queryParams: { gitBranch, fallbackBranch }, - ...this.extraProps - }); - } - - public pgRollMigrationHistory({ - workspace, - region, - database, - branch - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - }): Promise { - return operationsByTag.migrations.getMigrationHistory({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - ...this.extraProps - }); - } - - public applyMigration({ - workspace, - region, - database, - branch, - migration - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - migration: Schemas.Migration; - }): Promise { - return operationsByTag.migrations.applyMigration({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: migration, - ...this.extraProps - }); - } -} - -class TableApi { - constructor(private extraProps: ApiExtraProps) {} - - public createTable({ - workspace, - region, - database, - branch, - table - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - }): Promise { - return operationsByTag.table.createTable({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - ...this.extraProps - }); - } - - public deleteTable({ - workspace, - region, - database, - branch, - table - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - }): Promise { - return operationsByTag.table.deleteTable({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - ...this.extraProps - }); - } - - public updateTable({ - workspace, - region, - database, - branch, - table, - update - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - update: Types.UpdateTableRequestBody; - }): Promise { - return operationsByTag.table.updateTable({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - body: update, - ...this.extraProps - }); - } - - public getTableSchema({ - workspace, - region, - database, - branch, - table - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - }): Promise { - return operationsByTag.table.getTableSchema({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - ...this.extraProps - }); - } - - public setTableSchema({ - workspace, - region, - database, - branch, - table, - schema - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - schema: Types.SetTableSchemaRequestBody; - }): Promise { - return operationsByTag.table.setTableSchema({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - body: schema, - ...this.extraProps - }); - } - - public getTableColumns({ - workspace, - region, - database, - branch, - table - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - }): Promise { - return operationsByTag.table.getTableColumns({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - ...this.extraProps - }); - } - - public addTableColumn({ - workspace, - region, - database, - branch, - table, - column - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - column: Schemas.Column; - }): Promise { - return operationsByTag.table.addTableColumn({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - body: column, - ...this.extraProps - }); - } - - public getColumn({ - workspace, - region, - database, - branch, - table, - column - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - column: Schemas.ColumnName; - }): Promise { - return operationsByTag.table.getColumn({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table, columnName: column }, - ...this.extraProps - }); - } - - public updateColumn({ - workspace, - region, - database, - branch, - table, - column, - update - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - column: Schemas.ColumnName; - update: Types.UpdateColumnRequestBody; - }): Promise { - return operationsByTag.table.updateColumn({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table, columnName: column }, - body: update, - ...this.extraProps - }); - } - - public deleteColumn({ - workspace, - region, - database, - branch, - table, - column - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - column: Schemas.ColumnName; - }): Promise { - return operationsByTag.table.deleteColumn({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table, columnName: column }, - ...this.extraProps - }); - } -} - -class RecordsApi { - constructor(private extraProps: ApiExtraProps) {} - - public insertRecord({ - workspace, - region, - database, - branch, - table, - record, - columns - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - record: Record; - columns?: Schemas.ColumnsProjection; - }): Promise { - return operationsByTag.records.insertRecord({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - queryParams: { columns }, - body: record, - ...this.extraProps - }); - } - - public getRecord({ - workspace, - region, - database, - branch, - table, - id, - columns - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - id: Schemas.RecordID; - columns?: Schemas.ColumnsProjection; - }): Promise { - return operationsByTag.records.getRecord({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table, recordId: id }, - queryParams: { columns }, - ...this.extraProps - }); - } - - public insertRecordWithID({ - workspace, - region, - database, - branch, - table, - id, - record, - columns, - createOnly, - ifVersion - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - id: Schemas.RecordID; - record: Record; - columns?: Schemas.ColumnsProjection; - createOnly?: boolean; - ifVersion?: number; - }): Promise { - return operationsByTag.records.insertRecordWithID({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table, recordId: id }, - queryParams: { columns, createOnly, ifVersion }, - body: record, - ...this.extraProps - }); - } - - public updateRecordWithID({ - workspace, - region, - database, - branch, - table, - id, - record, - columns, - ifVersion - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - id: Schemas.RecordID; - record: Record; - columns?: Schemas.ColumnsProjection; - ifVersion?: number; - }): Promise { - return operationsByTag.records.updateRecordWithID({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table, recordId: id }, - queryParams: { columns, ifVersion }, - body: record, - ...this.extraProps - }); - } - - public upsertRecordWithID({ - workspace, - region, - database, - branch, - table, - id, - record, - columns, - ifVersion - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - id: Schemas.RecordID; - record: Record; - columns?: Schemas.ColumnsProjection; - ifVersion?: number; - }): Promise { - return operationsByTag.records.upsertRecordWithID({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table, recordId: id }, - queryParams: { columns, ifVersion }, - body: record, - ...this.extraProps - }); - } - - public deleteRecord({ - workspace, - region, - database, - branch, - table, - id, - columns - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - id: Schemas.RecordID; - columns?: Schemas.ColumnsProjection; - }): Promise { - return operationsByTag.records.deleteRecord({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table, recordId: id }, - queryParams: { columns }, - ...this.extraProps - }); - } - - public bulkInsertTableRecords({ - workspace, - region, - database, - branch, - table, - records, - columns - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - records: Record[]; - columns?: Schemas.ColumnsProjection; - }): Promise { - return operationsByTag.records.bulkInsertTableRecords({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - queryParams: { columns }, - body: { records }, - ...this.extraProps - }); - } - - public branchTransaction({ - workspace, - region, - database, - branch, - operations - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - operations: Schemas.TransactionOperation[]; - }): Promise { - return operationsByTag.records.branchTransaction({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: { operations }, - ...this.extraProps - }); - } -} - -class FilesApi { - constructor(private extraProps: ApiExtraProps) {} - - public getFileItem({ - workspace, - region, - database, - branch, - table, - record, - column, - fileId - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - record: Schemas.RecordID; - column: Schemas.ColumnName; - fileId: string; - }): Promise { - return operationsByTag.files.getFileItem({ - pathParams: { - workspace, - region, - dbBranchName: `${database}:${branch}`, - tableName: table, - recordId: record, - columnName: column, - fileId - }, - ...this.extraProps - }); - } - - public putFileItem({ - workspace, - region, - database, - branch, - table, - record, - column, - fileId, - file - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - record: Schemas.RecordID; - column: Schemas.ColumnName; - fileId: string; - file: any; - }): Promise { - return operationsByTag.files.putFileItem({ - pathParams: { - workspace, - region, - dbBranchName: `${database}:${branch}`, - tableName: table, - recordId: record, - columnName: column, - fileId - }, - // @ts-ignore - body: file, - ...this.extraProps - }); - } - - public deleteFileItem({ - workspace, - region, - database, - branch, - table, - record, - column, - fileId - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - record: Schemas.RecordID; - column: Schemas.ColumnName; - fileId: string; - }): Promise { - return operationsByTag.files.deleteFileItem({ - pathParams: { - workspace, - region, - dbBranchName: `${database}:${branch}`, - tableName: table, - recordId: record, - columnName: column, - fileId - }, - ...this.extraProps - }); - } - - public getFile({ - workspace, - region, - database, - branch, - table, - record, - column - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - record: Schemas.RecordID; - column: Schemas.ColumnName; - }): Promise { - return operationsByTag.files.getFile({ - pathParams: { - workspace, - region, - dbBranchName: `${database}:${branch}`, - tableName: table, - recordId: record, - columnName: column - }, - ...this.extraProps - }); - } - - public putFile({ - workspace, - region, - database, - branch, - table, - record, - column, - file - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - record: Schemas.RecordID; - column: Schemas.ColumnName; - file: Blob; - }): Promise { - return operationsByTag.files.putFile({ - pathParams: { - workspace, - region, - dbBranchName: `${database}:${branch}`, - tableName: table, - recordId: record, - columnName: column - }, - body: file, - ...this.extraProps - }); - } - - public deleteFile({ - workspace, - region, - database, - branch, - table, - record, - column - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - record: Schemas.RecordID; - column: Schemas.ColumnName; - }): Promise { - return operationsByTag.files.deleteFile({ - pathParams: { - workspace, - region, - dbBranchName: `${database}:${branch}`, - tableName: table, - recordId: record, - columnName: column - }, - ...this.extraProps - }); - } - - public fileAccess({ - workspace, - region, - fileId, - verify - }: { - workspace: Schemas.WorkspaceID; - region: string; - fileId: string; - verify?: Schemas.FileSignature; - }): Promise { - return operationsByTag.files.fileAccess({ - pathParams: { - workspace, - region, - fileId - }, - queryParams: { verify }, - ...this.extraProps - }); - } -} - -class SearchAndFilterApi { - constructor(private extraProps: ApiExtraProps) {} - - public queryTable({ - workspace, - region, - database, - branch, - table, - filter, - sort, - page, - columns, - consistency - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - filter?: Schemas.FilterExpression; - sort?: Schemas.SortExpression; - page?: Schemas.PageConfig; - columns?: Schemas.ColumnsProjection; - consistency?: 'strong' | 'eventual'; - }): Promise { - return operationsByTag.searchAndFilter.queryTable({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - body: { filter, sort, page, columns, consistency }, - ...this.extraProps - }); - } - - public searchTable({ - workspace, - region, - database, - branch, - table, - query, - fuzziness, - target, - prefix, - filter, - highlight, - boosters - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - query: string; - fuzziness?: Schemas.FuzzinessExpression; - target?: Schemas.TargetExpression; - prefix?: Schemas.PrefixExpression; - filter?: Schemas.FilterExpression; - highlight?: Schemas.HighlightExpression; - boosters?: Schemas.BoosterExpression[]; - }): Promise { - return operationsByTag.searchAndFilter.searchTable({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - body: { query, fuzziness, target, prefix, filter, highlight, boosters }, - ...this.extraProps - }); - } - - public searchBranch({ - workspace, - region, - database, - branch, - tables, - query, - fuzziness, - prefix, - highlight - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - tables?: ( - | string - | { - table: string; - filter?: Schemas.FilterExpression; - target?: Schemas.TargetExpression; - boosters?: Schemas.BoosterExpression[]; +type UserProps = { + headers?: Record; +}; + +type XataApiProxy = { + [Tag in keyof typeof operationsByTag]: { + [Method in keyof (typeof operationsByTag)[Tag]]: (typeof operationsByTag)[Tag][Method] extends infer Operation extends ( + ...args: any + ) => any + ? Omit[0], keyof ApiExtraProps> extends infer Params + ? RequiredKeys extends never + ? (params?: Params & UserProps) => ReturnType + : (params: Params & UserProps) => ReturnType + : never + : never; + }; +}; + +const buildApiClient = () => + class { + constructor(options: XataApiClientOptions = {}) { + const provider = options.host ?? 'production'; + const apiKey = options.apiKey ?? getAPIKey(); + const trace = options.trace ?? defaultTrace; + const clientID = generateUUID(); + + if (!apiKey) { + throw new Error('Could not resolve a valid apiKey'); + } + + const extraProps: ApiExtraProps = { + apiUrl: getHostUrl(provider, 'main'), + workspacesApiUrl: getHostUrl(provider, 'workspaces'), + fetch: getFetchImplementation(options.fetch), + apiKey, + trace, + clientName: options.clientName, + xataAgentExtra: options.xataAgentExtra, + clientID + }; + + return new Proxy(this, { + get: (_target, namespace: keyof typeof operationsByTag) => { + if (operationsByTag[namespace] === undefined) { + return undefined; + } + + return new Proxy( + {}, + { + get: (_target, operation: keyof (typeof operationsByTag)[keyof typeof operationsByTag]) => { + if (operationsByTag[namespace][operation] === undefined) { + return undefined; + } + + const method = operationsByTag[namespace][operation] as any; + + return async (params: Record) => { + return await method({ ...params, ...extraProps }); + }; + } + } + ); } - )[]; - query: string; - fuzziness?: Schemas.FuzzinessExpression; - prefix?: Schemas.PrefixExpression; - highlight?: Schemas.HighlightExpression; - }): Promise { - return operationsByTag.searchAndFilter.searchBranch({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: { tables, query, fuzziness, prefix, highlight }, - ...this.extraProps - }); - } - - public vectorSearchTable({ - workspace, - region, - database, - branch, - table, - queryVector, - column, - similarityFunction, - size, - filter - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - queryVector: number[]; - column: string; - similarityFunction?: string; - size?: number; - filter?: Schemas.FilterExpression; - }): Promise { - return operationsByTag.searchAndFilter.vectorSearchTable({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - body: { queryVector, column, similarityFunction, size, filter }, - ...this.extraProps - }); - } - - public askTable({ - workspace, - region, - database, - branch, - table, - options - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - options: Components.AskTableRequestBody; - }): Promise { - return operationsByTag.searchAndFilter.askTable({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - body: { ...options }, - ...this.extraProps - }); - } - - public askTableSession({ - workspace, - region, - database, - branch, - table, - sessionId, - message - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - sessionId: string; - message: string; - }): Promise { - return operationsByTag.searchAndFilter.askTableSession({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table, sessionId }, - body: { message }, - ...this.extraProps - }); - } - - public summarizeTable({ - workspace, - region, - database, - branch, - table, - filter, - columns, - summaries, - sort, - summariesFilter, - page, - consistency - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - filter?: Schemas.FilterExpression; - columns?: Schemas.ColumnsProjection; - summaries?: Schemas.SummaryExpressionList; - sort?: Schemas.SortExpression; - summariesFilter?: Schemas.FilterExpression; - page?: { size?: number }; - consistency?: 'strong' | 'eventual'; - }): Promise { - return operationsByTag.searchAndFilter.summarizeTable({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - body: { filter, columns, summaries, sort, summariesFilter, page, consistency }, - ...this.extraProps - }); - } - - public aggregateTable({ - workspace, - region, - database, - branch, - table, - filter, - aggs - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - table: Schemas.TableName; - filter?: Schemas.FilterExpression; - aggs?: Schemas.AggExpressionMap; - }): Promise { - return operationsByTag.searchAndFilter.aggregateTable({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, tableName: table }, - body: { filter, aggs }, - ...this.extraProps - }); - } -} - -class MigrationRequestsApi { - constructor(private extraProps: ApiExtraProps) {} - - public queryMigrationRequests({ - workspace, - region, - database, - filter, - sort, - page, - columns - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - filter?: Schemas.FilterExpression; - sort?: Schemas.SortExpression; - page?: Schemas.PageConfig; - columns?: Schemas.ColumnsProjection; - }): Promise { - return operationsByTag.migrationRequests.queryMigrationRequests({ - pathParams: { workspace, region, dbName: database }, - body: { filter, sort, page, columns }, - ...this.extraProps - }); - } - - public createMigrationRequest({ - workspace, - region, - database, - migration - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - migration: Components.CreateMigrationRequestRequestBody; - }): Promise { - return operationsByTag.migrationRequests.createMigrationRequest({ - pathParams: { workspace, region, dbName: database }, - body: migration, - ...this.extraProps - }); - } - - public getMigrationRequest({ - workspace, - region, - database, - migrationRequest - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - migrationRequest: Schemas.MigrationRequestNumber; - }): Promise { - return operationsByTag.migrationRequests.getMigrationRequest({ - pathParams: { workspace, region, dbName: database, mrNumber: migrationRequest }, - ...this.extraProps - }); - } - - public updateMigrationRequest({ - workspace, - region, - database, - migrationRequest, - update - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - migrationRequest: Schemas.MigrationRequestNumber; - update: Components.UpdateMigrationRequestRequestBody; - }): Promise { - return operationsByTag.migrationRequests.updateMigrationRequest({ - pathParams: { workspace, region, dbName: database, mrNumber: migrationRequest }, - body: update, - ...this.extraProps - }); - } - - public listMigrationRequestsCommits({ - workspace, - region, - database, - migrationRequest, - page - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - migrationRequest: Schemas.MigrationRequestNumber; - page?: { after?: string; before?: string; size?: number }; - }): Promise { - return operationsByTag.migrationRequests.listMigrationRequestsCommits({ - pathParams: { workspace, region, dbName: database, mrNumber: migrationRequest }, - body: { page }, - ...this.extraProps - }); - } - - public compareMigrationRequest({ - workspace, - region, - database, - migrationRequest - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - migrationRequest: Schemas.MigrationRequestNumber; - }): Promise { - return operationsByTag.migrationRequests.compareMigrationRequest({ - pathParams: { workspace, region, dbName: database, mrNumber: migrationRequest }, - ...this.extraProps - }); - } - - public getMigrationRequestIsMerged({ - workspace, - region, - database, - migrationRequest - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - migrationRequest: Schemas.MigrationRequestNumber; - }): Promise { - return operationsByTag.migrationRequests.getMigrationRequestIsMerged({ - pathParams: { workspace, region, dbName: database, mrNumber: migrationRequest }, - ...this.extraProps - }); - } - - public mergeMigrationRequest({ - workspace, - region, - database, - migrationRequest - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - migrationRequest: Schemas.MigrationRequestNumber; - }): Promise { - return operationsByTag.migrationRequests.mergeMigrationRequest({ - pathParams: { workspace, region, dbName: database, mrNumber: migrationRequest }, - ...this.extraProps - }); - } -} - -class MigrationsApi { - constructor(private extraProps: ApiExtraProps) {} - - public getBranchMigrationHistory({ - workspace, - region, - database, - branch, - limit, - startFrom - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - limit?: number; - startFrom?: string; - }): Promise { - return operationsByTag.migrations.getBranchMigrationHistory({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: { limit, startFrom }, - ...this.extraProps - }); - } - - public getBranchMigrationPlan({ - workspace, - region, - database, - branch, - schema - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - schema: Schemas.Schema; - }): Promise { - return operationsByTag.migrations.getBranchMigrationPlan({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: schema, - ...this.extraProps - }); - } - - public executeBranchMigrationPlan({ - workspace, - region, - database, - branch, - plan - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - plan: Types.ExecuteBranchMigrationPlanRequestBody; - }): Promise { - return operationsByTag.migrations.executeBranchMigrationPlan({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: plan, - ...this.extraProps - }); - } - - public getBranchSchemaHistory({ - workspace, - region, - database, - branch, - page - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - page?: { after?: string; before?: string; size?: number }; - }): Promise { - return operationsByTag.migrations.getBranchSchemaHistory({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: { page }, - ...this.extraProps - }); - } - - public compareBranchWithUserSchema({ - workspace, - region, - database, - branch, - schema, - schemaOperations, - branchOperations - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - schema: Schemas.Schema; - schemaOperations?: Schemas.MigrationOp[]; - branchOperations?: Schemas.MigrationOp[]; - }): Promise { - return operationsByTag.migrations.compareBranchWithUserSchema({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: { schema, schemaOperations, branchOperations }, - ...this.extraProps - }); - } - - public compareBranchSchemas({ - workspace, - region, - database, - branch, - compare, - sourceBranchOperations, - targetBranchOperations - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - compare: Schemas.BranchName; - sourceBranchOperations?: Schemas.MigrationOp[]; - targetBranchOperations?: Schemas.MigrationOp[]; - }): Promise { - return operationsByTag.migrations.compareBranchSchemas({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, branchName: compare }, - body: { sourceBranchOperations, targetBranchOperations }, - ...this.extraProps - }); - } - - public updateBranchSchema({ - workspace, - region, - database, - branch, - migration - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - migration: Schemas.Migration; - }): Promise { - return operationsByTag.migrations.updateBranchSchema({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: migration, - ...this.extraProps - }); - } - - public previewBranchSchemaEdit({ - workspace, - region, - database, - branch, - data - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - data: { edits?: Schemas.SchemaEditScript }; - }): Promise { - return operationsByTag.migrations.previewBranchSchemaEdit({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: data, - ...this.extraProps - }); - } - - public applyBranchSchemaEdit({ - workspace, - region, - database, - branch, - edits - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - edits: Schemas.SchemaEditScript; - }): Promise { - return operationsByTag.migrations.applyBranchSchemaEdit({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: { edits }, - ...this.extraProps - }); - } - - public pushBranchMigrations({ - workspace, - region, - database, - branch, - migrations - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - migrations: Schemas.MigrationObject[]; - }): Promise { - return operationsByTag.migrations.pushBranchMigrations({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: { migrations }, - ...this.extraProps - }); - } - - public getSchema({ - workspace, - region, - database, - branch - }: { - workspace: Schemas.WorkspaceID; - region: string; - database: Schemas.DBName; - branch: Schemas.BranchName; - }): Promise { - return operationsByTag.migrations.getSchema({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - ...this.extraProps - }); - } -} - -class DatabaseApi { - constructor(private extraProps: ApiExtraProps) {} - - public getDatabaseList({ workspace }: { workspace: Schemas.WorkspaceID }): Promise { - return operationsByTag.databases.getDatabaseList({ - pathParams: { workspaceId: workspace }, - ...this.extraProps - }); - } - - public createDatabase({ - workspace, - database, - data, - headers - }: { - workspace: Schemas.WorkspaceID; - database: Schemas.DBName; - data: Components.CreateDatabaseRequestBody; - headers?: Record; - }): Promise { - return operationsByTag.databases.createDatabase({ - pathParams: { workspaceId: workspace, dbName: database }, - body: data, - headers, - ...this.extraProps - }); - } - - public deleteDatabase({ - workspace, - database - }: { - workspace: Schemas.WorkspaceID; - database: Schemas.DBName; - }): Promise { - return operationsByTag.databases.deleteDatabase({ - pathParams: { workspaceId: workspace, dbName: database }, - ...this.extraProps - }); - } - - public getDatabaseMetadata({ - workspace, - database - }: { - workspace: Schemas.WorkspaceID; - database: Schemas.DBName; - }): Promise { - return operationsByTag.databases.getDatabaseMetadata({ - pathParams: { workspaceId: workspace, dbName: database }, - ...this.extraProps - }); - } - - public updateDatabaseMetadata({ - workspace, - database, - metadata - }: { - workspace: Schemas.WorkspaceID; - database: Schemas.DBName; - metadata: Schemas.DatabaseMetadata; - }): Promise { - return operationsByTag.databases.updateDatabaseMetadata({ - pathParams: { workspaceId: workspace, dbName: database }, - body: metadata, - ...this.extraProps - }); - } - - public renameDatabase({ - workspace, - database, - newName - }: { - workspace: Schemas.WorkspaceID; - database: Schemas.DBName; - newName: Schemas.DBName; - }): Promise { - return operationsByTag.databases.renameDatabase({ - pathParams: { workspaceId: workspace, dbName: database }, - body: { newName }, - ...this.extraProps - }); - } - - public getDatabaseGithubSettings({ - workspace, - database - }: { - workspace: Schemas.WorkspaceID; - database: Schemas.DBName; - }): Promise { - return operationsByTag.databases.getDatabaseGithubSettings({ - pathParams: { workspaceId: workspace, dbName: database }, - ...this.extraProps - }); - } - - public updateDatabaseGithubSettings({ - workspace, - database, - settings - }: { - workspace: Schemas.WorkspaceID; - database: Schemas.DBName; - settings: Schemas.DatabaseGithubSettings; - }): Promise { - return operationsByTag.databases.updateDatabaseGithubSettings({ - pathParams: { workspaceId: workspace, dbName: database }, - body: settings, - ...this.extraProps - }); - } - - public deleteDatabaseGithubSettings({ - workspace, - database - }: { - workspace: Schemas.WorkspaceID; - database: Schemas.DBName; - }): Promise { - return operationsByTag.databases.deleteDatabaseGithubSettings({ - pathParams: { workspaceId: workspace, dbName: database }, - ...this.extraProps - }); - } + }); + } + } as unknown as { new (options?: XataApiClientOptions): XataApiProxy }; - public listRegions({ workspace }: { workspace: Schemas.WorkspaceID }): Promise { - return operationsByTag.databases.listRegions({ - pathParams: { workspaceId: workspace }, - ...this.extraProps - }); - } -} +export class XataApiClient extends buildApiClient() {} diff --git a/packages/client/src/util/types.ts b/packages/client/src/util/types.ts index 95c0bc8c0..7fc3d8b63 100644 --- a/packages/client/src/util/types.ts +++ b/packages/client/src/util/types.ts @@ -65,3 +65,11 @@ type Narrowable = string | number | bigint | boolean; type Try = A1 extends A2 ? A1 : Catch; export type Narrow = Try>; + +export type RequiredKeys = { + [K in keyof T]-?: {} extends Pick ? never : K; +}[keyof T]; + +export type FlattenObject = { + [K in keyof T]: T[K]; +}[keyof T]; diff --git a/test/integration/query.test.ts b/test/integration/query.test.ts index 60af5c885..a1bb91d08 100644 --- a/test/integration/query.test.ts +++ b/test/integration/query.test.ts @@ -610,14 +610,12 @@ describe('integration tests', () => { }); test('Pagination default value', async () => { - await api.tables.createTable({ workspace, region, database, branch: 'main', table: 'planes' }); - await api.tables.setTableSchema({ - workspace, - region, - database, - branch: 'main', - table: 'planes', - schema: { columns: [{ name: 'name', type: 'string' }] } + await api.table.createTable({ + pathParams: { workspace, region, dbBranchName: `${database}:main`, tableName: 'planes' } + }); + await api.table.setTableSchema({ + pathParams: { workspace, region, dbBranchName: `${database}:main`, tableName: 'planes' }, + body: { columns: [{ name: 'name', type: 'string' }] } }); const planes = Array.from({ length: PAGINATION_DEFAULT_SIZE + 50 }, (_, index) => ({ name: `Plane ${index}` })); diff --git a/test/integration/smoke.test.ts b/test/integration/smoke.test.ts index c77ba8a6d..f7f2d59c6 100644 --- a/test/integration/smoke.test.ts +++ b/test/integration/smoke.test.ts @@ -22,7 +22,7 @@ describe('API Client Integration Tests', () => { test('Create, get and delete workspace with new apiKey', async () => { const workspaceName = getWorkspaceName(); - const newApiKey = await api.authentication.createUserAPIKey({ name: `${workspaceName}-key` }); + const newApiKey = await api.authentication.createUserAPIKey({ pathParams: { keyName: `${workspaceName}-key` } }); expect(newApiKey).toBeDefined(); expect(newApiKey.name).toBe(`${workspaceName}-key`); @@ -31,7 +31,7 @@ describe('API Client Integration Tests', () => { const newApi = new XataApiClient({ apiKey: newApiKey.key, host }); const { id: workspace, name } = await newApi.workspaces.createWorkspace({ - data: { name: workspaceName, slug: `${workspaceName}-slug` } + body: { name: workspaceName, slug: `${workspaceName}-slug` } }); await waitForReplication(newApi, workspace); @@ -41,57 +41,47 @@ describe('API Client Integration Tests', () => { console.log('Created workspace', workspace); - const foo = await newApi.workspaces.getWorkspace({ workspace }); + const foo = await newApi.workspaces.getWorkspace({ pathParams: { workspaceId: workspace } }); expect(foo.id).toBe(workspace); expect(foo.slug).toBe(`${workspaceName}-slug`); - const bar = await newApi.workspaces.getWorkspace({ workspace }); + const bar = await newApi.workspaces.getWorkspace({ pathParams: { workspaceId: workspace } }); expect(bar.id).toBe(workspace); expect(bar.slug).toBe(`${workspaceName}-slug`); - const { databaseName: database } = await newApi.database.createDatabase({ - workspace, - database: `data-${workspace}`, - data: { region } + const { databaseName: database } = await newApi.databases.createDatabase({ + pathParams: { workspaceId: workspace, dbName: `data-${workspace}` }, + body: { region } }); await waitForReplication(newApi, workspace, database); console.log('Created database', database); - await newApi.branches.createBranch({ workspace, region, database, branch: 'branch' }); - await newApi.tables.createTable({ workspace, region, database, branch: 'branch', table: 'table' }); - await newApi.tables.setTableSchema({ - workspace, - region, - database, - branch: 'branch', - table: 'table', - schema: { columns: [{ name: 'email', type: 'string' }] } + await newApi.branch.createBranch({ + pathParams: { workspace, region, dbBranchName: `${database}:branch` } + }); + await newApi.table.createTable({ + pathParams: { workspace, region, dbBranchName: `${database}:branch`, tableName: 'table' } + }); + await newApi.table.setTableSchema({ + pathParams: { workspace, region, dbBranchName: `${database}:branch`, tableName: 'table' }, + body: { columns: [{ name: 'email', type: 'string' }] } }); console.log('Created branch, table and schema'); const { id } = await newApi.records.insertRecord({ - workspace, - region, - database, - branch: 'branch', - table: 'table', - record: { email: 'example@foo.bar' } + pathParams: { workspace, region, dbBranchName: `${database}:branch`, tableName: 'table' }, + body: { email: 'example@foo.bar' } }); console.log('Created record', id); const record = await newApi.records.getRecord({ - workspace, - region, - database, - branch: 'branch', - table: 'table', - id + pathParams: { workspace, region, dbBranchName: `${database}:branch`, tableName: 'table', recordId: id } }); expect(record.id).toBeDefined(); @@ -100,24 +90,16 @@ describe('API Client Integration Tests', () => { await waitForSearchIndexing(newApi, workspace, database); const search = await newApi.searchAndFilter.searchTable({ - workspace, - region, - database, - branch: 'branch', - table: 'table', - query: 'example' + pathParams: { workspace, region, dbBranchName: `${database}:branch`, tableName: 'table' }, + body: { query: 'example' } }); expect(search.totalCount).toEqual(1); expect(search.records[0].id).toEqual(id); const failedSearch = await newApi.searchAndFilter.searchTable({ - workspace, - region, - database, - branch: 'branch', - table: 'table', - query: 'random' + pathParams: { workspace, region, dbBranchName: `${database}:branch`, tableName: 'table' }, + body: { query: 'random' } }); expect(failedSearch.totalCount).toEqual(0); @@ -125,37 +107,32 @@ describe('API Client Integration Tests', () => { console.log('Tested search successfully'); - await api.authentication.deleteUserAPIKey({ name: newApiKey.name }); + await api.authentication.deleteUserAPIKey({ pathParams: { keyName: newApiKey.name } }); await waitFailInReplication(newApi, workspace, database); await expect( newApi.records.getRecord({ - workspace, - region, - database, - branch: 'branch', - table: 'table', - id + pathParams: { workspace, region, dbBranchName: `${database}:branch`, tableName: 'table', recordId: id } }) ).rejects.toHaveProperty('message'); console.log('Deleted API key, record is no longer accessible'); - await api.workspaces.deleteWorkspace({ workspace }); - - await expect(api.workspaces.getWorkspace({ workspace })).rejects.toHaveProperty('message'); + await api.workspaces.deleteWorkspace({ pathParams: { workspaceId: workspace } }); - console.log('Deleted workspace, workspace is no longer accessible'); + await expect(api.workspaces.getWorkspace({ pathParams: { workspaceId: workspace } })).rejects.toHaveProperty( + 'message' + ); }); }); async function waitForReplication(api: XataApiClient, workspace: string, database?: string): Promise { try { if (database === undefined) { - await api.database.getDatabaseList({ workspace }); + await api.databases.getDatabaseList({ pathParams: { workspaceId: workspace } }); } else { - await api.branches.getBranchList({ workspace, database, region }); + await api.branch.getBranchList({ pathParams: { workspace, region, dbName: database } }); } } catch (error) { console.log(`Waiting for create ${database === undefined ? 'API key' : 'database'} replication to finish...`); @@ -166,7 +143,7 @@ async function waitForReplication(api: XataApiClient, workspace: string, databas async function waitFailInReplication(api: XataApiClient, workspace: string, database: string): Promise { try { - await api.branches.getBranchList({ workspace, database, region }); + await api.branch.getBranchList({ pathParams: { workspace, region, dbName: database } }); console.log(`Waiting for delete API key replication to finish...`); await new Promise((resolve) => setTimeout(resolve, 2000)); @@ -179,12 +156,8 @@ async function waitFailInReplication(api: XataApiClient, workspace: string, data async function waitForSearchIndexing(api: XataApiClient, workspace: string, database: string): Promise { try { const { aggs } = await api.searchAndFilter.aggregateTable({ - workspace, - database, - region, - branch: 'branch', - table: 'table', - aggs: { total: { count: '*' } } + pathParams: { workspace, region, dbBranchName: `${database}:branch`, tableName: 'table' }, + body: { aggs: { total: { count: '*' } } } }); if (aggs?.total === 1) { diff --git a/test/utils/setup.ts b/test/utils/setup.ts index 4aad29bc7..f12fcb50f 100644 --- a/test/utils/setup.ts +++ b/test/utils/setup.ts @@ -73,10 +73,9 @@ export async function setUpTestEnvironment( const id = Date.now().toString(36); const api = new XataApiClient({ apiKey, fetch, host, clientName: 'sdk-tests' }); - const { databaseName: database } = await api.database.createDatabase({ - workspace, - database: `sdk-integration-test-${prefix}-${id}`, - data: { region }, + const { databaseName: database } = await api.databases.createDatabase({ + pathParams: { workspaceId: workspace, dbName: `sdk-integration-test-${prefix}-${id}` }, + body: { region }, headers: { 'X-Xata-Files': 'true' } }); @@ -93,14 +92,14 @@ export async function setUpTestEnvironment( }; const { edits } = await api.migrations.compareBranchWithUserSchema({ - workspace, - region, - database, - branch: 'main', - schema + pathParams: { workspace, region, dbBranchName: `${database}:main` }, + body: { schema } }); - await api.migrations.applyBranchSchemaEdit({ workspace, region, database, branch: 'main', edits }); + await api.migrations.applyBranchSchemaEdit({ + pathParams: { workspace, region, dbBranchName: `${database}:main` }, + body: { edits } + }); let span: Span | undefined; @@ -110,7 +109,7 @@ export async function setUpTestEnvironment( }, afterAll: async () => { try { - await api.database.deleteDatabase({ workspace, database }); + await api.databases.deleteDatabase({ pathParams: { workspaceId: workspace, dbName: database } }); } catch (e) { // Ignore error, delete database during ES snapshot fails console.error('Delete database failed', e); From 1495b46e4c2871af6eae5743006d8a6db8bbeb8e Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Tue, 9 Apr 2024 15:27:14 +0200 Subject: [PATCH 04/22] Remove cache implementation (#1368) Signed-off-by: Alexis Rico --- .changeset/pre.json | 2 - .changeset/violet-worms-develop.md | 2 - .github/workflows/build-pr.yml | 2 - packages/client/src/client.ts | 5 - packages/client/src/plugins.ts | 2 - packages/client/src/schema/cache.test.ts | 96 ----- packages/client/src/schema/cache.ts | 53 --- packages/client/src/schema/index.ts | 1 - packages/client/src/schema/query.ts | 11 - packages/client/src/schema/repository.ts | 26 -- packages/plugin-client-cache/.npmignore | 5 - packages/plugin-client-cache/CHANGELOG.md | 389 ------------------ packages/plugin-client-cache/package.json | 33 -- .../plugin-client-cache/rollup.config.mjs | 29 -- packages/plugin-client-cache/src/index.ts | 1 - packages/plugin-client-cache/src/lru-cache.ts | 35 -- packages/plugin-client-cache/tsconfig.json | 22 - packages/plugin-client-cloudflare/.npmignore | 5 - .../plugin-client-cloudflare/CHANGELOG.md | 313 -------------- .../plugin-client-cloudflare/package.json | 28 -- .../rollup.config.mjs | 29 -- .../plugin-client-cloudflare/src/cache.ts | 88 ---- .../plugin-client-cloudflare/src/index.ts | 1 - .../plugin-client-cloudflare/tsconfig.json | 23 -- pnpm-lock.yaml | 24 -- test/integration/cache.test.ts | 113 ----- test/utils/setup.ts | 7 +- 27 files changed, 2 insertions(+), 1343 deletions(-) delete mode 100644 packages/client/src/schema/cache.test.ts delete mode 100644 packages/client/src/schema/cache.ts delete mode 100644 packages/plugin-client-cache/.npmignore delete mode 100644 packages/plugin-client-cache/CHANGELOG.md delete mode 100644 packages/plugin-client-cache/package.json delete mode 100644 packages/plugin-client-cache/rollup.config.mjs delete mode 100644 packages/plugin-client-cache/src/index.ts delete mode 100644 packages/plugin-client-cache/src/lru-cache.ts delete mode 100644 packages/plugin-client-cache/tsconfig.json delete mode 100644 packages/plugin-client-cloudflare/.npmignore delete mode 100644 packages/plugin-client-cloudflare/CHANGELOG.md delete mode 100644 packages/plugin-client-cloudflare/package.json delete mode 100644 packages/plugin-client-cloudflare/rollup.config.mjs delete mode 100644 packages/plugin-client-cloudflare/src/cache.ts delete mode 100644 packages/plugin-client-cloudflare/src/index.ts delete mode 100644 packages/plugin-client-cloudflare/tsconfig.json delete mode 100644 test/integration/cache.test.ts diff --git a/.changeset/pre.json b/.changeset/pre.json index 80aba5e0e..09815f51e 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -6,8 +6,6 @@ "@xata.io/client": "0.28.2", "@xata.io/codegen": "0.28.2", "@xata.io/importer": "1.1.3", - "@xata.io/plugin-client-cache": "0.1.39", - "@xata.io/plugin-client-cloudflare": "0.0.38", "@xata.io/drizzle": "0.0.13", "@xata.io/kysely": "0.1.13", "@xata.io/netlify": "0.1.23", diff --git a/.changeset/violet-worms-develop.md b/.changeset/violet-worms-develop.md index 353605dbd..2d58b8624 100644 --- a/.changeset/violet-worms-develop.md +++ b/.changeset/violet-worms-develop.md @@ -3,8 +3,6 @@ '@xata.io/client': major '@xata.io/codegen': major '@xata.io/importer': major -'@xata.io/plugin-client-cache': major -'@xata.io/plugin-client-cloudflare': major '@xata.io/drizzle': major '@xata.io/kysely': major '@xata.io/netlify': major diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 2fa8e0769..a57b29412 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -110,8 +110,6 @@ jobs: cat << EOF > .changeset/force-canary-build.md --- '@xata.io/plugin-client-opentelemetry': patch - '@xata.io/plugin-client-cloudflare': patch - '@xata.io/plugin-client-cache': patch '@xata.io/drizzle': patch '@xata.io/kysely': patch '@xata.io/pgroll': patch diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index c9ff2c343..aa365225e 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -2,7 +2,6 @@ import { ApiExtraProps, HostProvider, Schemas } from './api'; import { FilesPlugin, FilesPluginResult } from './files'; import { XataPlugin, XataPluginOptions } from './plugins'; import { BaseSchema, SchemaPlugin, SchemaPluginResult, XataRecord } from './schema'; -import { CacheImpl, SimpleCache } from './schema/cache'; import { defaultTrace, TraceFunction } from './schema/tracing'; import { SearchPlugin, SearchPluginResult } from './search'; import { SQLPlugin, SQLPluginResult } from './sql'; @@ -18,7 +17,6 @@ export type BaseClientOptions = { apiKey?: string; databaseURL?: string; branch?: string; - cache?: CacheImpl; trace?: TraceFunction; enableBrowser?: boolean; clientName?: string; @@ -49,7 +47,6 @@ export const buildClient = = {}>(plu const pluginOptions: XataPluginOptions = { ...this.#getFetchProps(safeOptions), - cache: safeOptions.cache, host: safeOptions.host, tables, branch: safeOptions.branch @@ -98,7 +95,6 @@ export const buildClient = = {}>(plu const fetch = getFetchImplementation(options?.fetch); const databaseURL = options?.databaseURL || getDatabaseURL(); const apiKey = options?.apiKey || getAPIKey(); - const cache = options?.cache ?? new SimpleCache({ defaultQueryTTL: 0 }); const trace = options?.trace ?? defaultTrace; const clientName = options?.clientName; const host = options?.host ?? 'production'; @@ -138,7 +134,6 @@ export const buildClient = = {}>(plu databaseURL, apiKey, branch, - cache, trace, host, clientID: generateUUID(), diff --git a/packages/client/src/plugins.ts b/packages/client/src/plugins.ts index 72a3f8cdc..f9f78cde1 100644 --- a/packages/client/src/plugins.ts +++ b/packages/client/src/plugins.ts @@ -1,12 +1,10 @@ import { ApiExtraProps, HostProvider, Schemas } from './api'; -import { CacheImpl } from './schema/cache'; export abstract class XataPlugin { abstract build(options: XataPluginOptions): unknown; } export type XataPluginOptions = ApiExtraProps & { - cache: CacheImpl; host: HostProvider; tables: Schemas.Table[]; branch: string; diff --git a/packages/client/src/schema/cache.test.ts b/packages/client/src/schema/cache.test.ts deleted file mode 100644 index 62b1f93c1..000000000 --- a/packages/client/src/schema/cache.test.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { describe, expect, test } from 'vitest'; -import { SimpleCache } from './cache'; - -const cache = new SimpleCache({ max: 5 }); - -describe('simple cache', () => { - test('no cache', async () => { - const noCache = new SimpleCache({ max: 0 }); - - await noCache.set('foo', 'bar'); - expect(await noCache.get('foo')).toBe(null); - }); - - test('useless cache', async () => { - const uselessCache = new SimpleCache({ max: 1 }); - - await uselessCache.set('foo', 'bar'); - expect(await uselessCache.get('foo')).toBe('bar'); - }); - - test('cache', async () => { - await cache.set('foo', 'bar'); - expect(await cache.get('foo')).toBe('bar'); - }); - - test('cache with delete', async () => { - await cache.set('foo', 'bar'); - await cache.delete('foo'); - expect(await cache.get('foo')).toBe(null); - }); - - test('cache with clear', async () => { - await cache.set('foo', 'bar'); - await cache.clear(); - expect(await cache.get('foo')).toBe(null); - }); - - test('cache with getAll', async () => { - await cache.set('foo', 'bar'); - await cache.set('bar', 'foo'); - expect(await cache.getAll()).toEqual({ foo: 'bar', bar: 'foo' }); - }); - - test('cache with getAll and delete', async () => { - await cache.set('foo', 'bar'); - await cache.set('bar', 'foo'); - await cache.delete('foo'); - expect(await cache.getAll()).toEqual({ bar: 'foo' }); - }); - - test('cache with getAll and clear', async () => { - await cache.set('foo', 'bar'); - await cache.set('bar', 'foo'); - await cache.clear(); - expect(await cache.getAll()).toEqual({}); - }); - - test('cache with max size', async () => { - await cache.set('foo', 'bar'); - await cache.set('bar', 'foo'); - await cache.set('baz', 'foo'); - await cache.set('qux', 'foo'); - await cache.set('quux', 'foo'); - await cache.set('corge', 'foo'); - await cache.set('grault', 'foo'); - expect(await cache.getAll()).toMatchInlineSnapshot(` - { - "baz": "foo", - "corge": "foo", - "grault": "foo", - "quux": "foo", - "qux": "foo", - } - `); - }); - - test('cache with max size, least recently used', async () => { - await cache.set('foo', 'bar'); - await cache.set('bar', 'foo'); - await cache.set('baz', 'foo'); - await cache.set('qux', 'foo'); - await cache.set('foo', 'bar'); - await cache.set('quux', 'foo'); - await cache.set('corge', 'foo'); - await cache.set('grault', 'foo'); - expect(await cache.getAll()).toMatchInlineSnapshot(` - { - "corge": "foo", - "foo": "bar", - "grault": "foo", - "quux": "foo", - "qux": "foo", - } - `); - }); -}); diff --git a/packages/client/src/schema/cache.ts b/packages/client/src/schema/cache.ts deleted file mode 100644 index 9dd098928..000000000 --- a/packages/client/src/schema/cache.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface CacheImpl { - defaultQueryTTL: number; - - getAll(): Promise>; - get: (key: string) => Promise; - set: (key: string, value: T) => Promise; - delete: (key: string) => Promise; - clear: () => Promise; -} - -export interface SimpleCacheOptions { - max?: number; - defaultQueryTTL?: number; -} - -export class SimpleCache implements CacheImpl { - #map: Map; - - capacity: number; - defaultQueryTTL: number; - - constructor(options: SimpleCacheOptions = {}) { - this.#map = new Map(); - this.capacity = options.max ?? 500; - this.defaultQueryTTL = options.defaultQueryTTL ?? 60 * 1000; - } - - async getAll(): Promise> { - return Object.fromEntries(this.#map); - } - - async get(key: string): Promise { - return (this.#map.get(key) ?? null) as T | null; - } - - async set(key: string, value: T): Promise { - await this.delete(key); - this.#map.set(key, value); - - if (this.#map.size > this.capacity) { - const leastRecentlyUsed = this.#map.keys().next().value; - await this.delete(leastRecentlyUsed); - } - } - - async delete(key: string): Promise { - this.#map.delete(key); - } - - async clear(): Promise { - return this.#map.clear(); - } -} diff --git a/packages/client/src/schema/index.ts b/packages/client/src/schema/index.ts index 2d0fe9102..49a3ccdcf 100644 --- a/packages/client/src/schema/index.ts +++ b/packages/client/src/schema/index.ts @@ -4,7 +4,6 @@ import { XataRecord } from './record'; import { Repository, RestRepository } from './repository'; export * from './ask'; -export * from './cache'; export { XataFile } from './files'; export type { XataArrayFile } from './files'; export * from './inference'; diff --git a/packages/client/src/schema/query.ts b/packages/client/src/schema/query.ts index 75165d9ff..deb416041 100644 --- a/packages/client/src/schema/query.ts +++ b/packages/client/src/schema/query.ts @@ -24,7 +24,6 @@ import { SummarizeExpression, SummarizeParams, SummarizeResult } from './summari type BaseOptions = { columns?: SelectableColumnWithObjectNotation[]; consistency?: 'strong' | 'eventual'; - cache?: number; fetchOptions?: Record; }; @@ -83,7 +82,6 @@ export class Query { - return new Query(this.#repository, this.#table, { cache: ttl }, this.#data); - } - /** * Retrieve next page of records * diff --git a/packages/client/src/schema/repository.ts b/packages/client/src/schema/repository.ts index 4c7db45ac..fb3d6fe59 100644 --- a/packages/client/src/schema/repository.ts +++ b/packages/client/src/schema/repository.ts @@ -36,7 +36,6 @@ import { generateUUID } from '../util/uuid'; import { VERSION } from '../version'; import { AggregationExpression, AggregationResult } from './aggregate'; import { AskOptions, AskResult } from './ask'; -import { CacheImpl } from './cache'; import { XataArrayFile, XataFile, parseInputFileEntry } from './files'; import { Filter, cleanFilter } from './filters'; import { parseJson, stringifyJson } from './json'; @@ -815,7 +814,6 @@ export class RestRepository #table: string; #getFetchProps: () => ApiExtraProps; #db: SchemaPluginResult; - #cache?: CacheImpl; #schemaTables?: Schemas.Table[]; #trace: TraceFunction; @@ -833,7 +831,6 @@ export class RestRepository this.#table = options.table; this.#db = options.db; - this.#cache = options.pluginOptions.cache; this.#schemaTables = options.schemaTables; this.#getFetchProps = () => ({ ...options.pluginOptions, sessionID: generateUUID() }); @@ -1852,9 +1849,6 @@ export class RestRepository async query(query: Query): Promise> { return this.#trace('query', async () => { - const cacheQuery = await this.#getCacheQuery(query); - if (cacheQuery) return new Page(query, cacheQuery.meta, cacheQuery.records); - const data = query.getQueryOptions(); const { meta, records: objects } = await queryTable({ @@ -1885,7 +1879,6 @@ export class RestRepository (data.columns as SelectableColumn[]) ?? ['*'] ) ); - await this.#setCacheQuery(query, meta, records); return new Page(query, meta, records); }); @@ -1963,25 +1956,6 @@ export class RestRepository } } - async #setCacheQuery(query: Query, meta: RecordsMetadata, records: XataRecord[]): Promise { - await this.#cache?.set(`query_${this.#table}:${query.key()}`, { date: new Date(), meta, records }); - } - - async #getCacheQuery( - query: Query - ): Promise<{ meta: RecordsMetadata; records: T[] } | null> { - const key = `query_${this.#table}:${query.key()}`; - const result = await this.#cache?.get<{ date: Date; meta: RecordsMetadata; records: T[] }>(key); - if (!result) return null; - - const defaultTTL = this.#cache?.defaultQueryTTL ?? -1; - const { cache: ttl = defaultTTL } = query.getQueryOptions(); - if (ttl < 0) return null; - - const hasExpired = result.date.getTime() + ttl < Date.now(); - return hasExpired ? null : result; - } - async #getSchemaTables(): Promise { if (this.#schemaTables) return this.#schemaTables; diff --git a/packages/plugin-client-cache/.npmignore b/packages/plugin-client-cache/.npmignore deleted file mode 100644 index c97b8ad26..000000000 --- a/packages/plugin-client-cache/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -src -tsconfig.json -rollup.config.mjs -.eslintrc.cjs -.gitignore diff --git a/packages/plugin-client-cache/CHANGELOG.md b/packages/plugin-client-cache/CHANGELOG.md deleted file mode 100644 index 91c89762b..000000000 --- a/packages/plugin-client-cache/CHANGELOG.md +++ /dev/null @@ -1,389 +0,0 @@ -# @xata.io/plugin-client-cache - -## 0.1.46 - -### Patch Changes - -- Updated dependencies [[`2140a24`](https://github.com/xataio/client-ts/commit/2140a24f32a94f36bab8c8268033c7dcf235dddc), [`d8032f2`](https://github.com/xataio/client-ts/commit/d8032f2e07bdcc653db1606796d27f08d397cdbe)]: - - @xata.io/client@0.29.4 - -## 0.1.45 - -### Patch Changes - -- Updated dependencies [[`02053fb`](https://github.com/xataio/client-ts/commit/02053fbb10479b8e9453691f957d3235762555aa), [`e27cb74`](https://github.com/xataio/client-ts/commit/e27cb74143aa9b6c654713878e5d3776858e5290)]: - - @xata.io/client@0.29.3 - -## 0.1.44 - -### Patch Changes - -- Updated dependencies [[`e8db1cd`](https://github.com/xataio/client-ts/commit/e8db1cd394ccbed32403548bf9d09a5c3973d850)]: - - @xata.io/client@0.29.2 - -## 0.1.43 - -### Patch Changes - -- Updated dependencies [[`d0f5d12`](https://github.com/xataio/client-ts/commit/d0f5d125e6c2f4c82f8a0a6b4a30d255c58e8326), [`212b53d`](https://github.com/xataio/client-ts/commit/212b53d07498def0d2ed8942691eff982e448969), [`9fd8c42`](https://github.com/xataio/client-ts/commit/9fd8c428d71b476f1951123c6cba5e803b983e54), [`368d4aa`](https://github.com/xataio/client-ts/commit/368d4aa16cd1cc1da93a142406c5d41bbc15b082)]: - - @xata.io/client@0.29.1 - -## 0.1.42 - -### Patch Changes - -- Updated dependencies [[`0ec026a`](https://github.com/xataio/client-ts/commit/0ec026a92bdb1a405cb9d90cb1d506ff159f98e8), [`6414bd3`](https://github.com/xataio/client-ts/commit/6414bd3d8bdb84961e68968df4b0b025503f0d72), [`27773df`](https://github.com/xataio/client-ts/commit/27773df5addf0013d1a7238ac490904e7aad2334)]: - - @xata.io/client@0.29.0 - -## 0.1.41 - -### Patch Changes - -- Updated dependencies [[`adc961b`](https://github.com/xataio/client-ts/commit/adc961b886b789010e6512c17cb2377eceab665a), [`6031a9d`](https://github.com/xataio/client-ts/commit/6031a9de63c264b7db5b031bb1795258c2bf8150)]: - - @xata.io/client@0.28.4 - -## 0.1.40 - -### Patch Changes - -- Updated dependencies [[`b7f3ec9`](https://github.com/xataio/client-ts/commit/b7f3ec9eabe3642929131e244bd774f4d3134482)]: - - @xata.io/client@0.28.3 - -## 0.1.39 - -### Patch Changes - -- Updated dependencies [[`c9178e1`](https://github.com/xataio/client-ts/commit/c9178e1e3f2268513e78dcfce396a99a8fca5dfb)]: - - @xata.io/client@0.28.2 - -## 0.1.38 - -### Patch Changes - -- Updated dependencies [[`9a7e3f5`](https://github.com/xataio/client-ts/commit/9a7e3f5029e53efc6750e9c86bab936427788209)]: - - @xata.io/client@0.28.1 - -## 0.1.37 - -### Patch Changes - -- Updated dependencies [[`e97d1999`](https://github.com/xataio/client-ts/commit/e97d1999f3c25f149213ceca81958e1674624e05)]: - - @xata.io/client@0.28.0 - -## 0.1.36 - -### Patch Changes - -- Updated dependencies [[`19c5dd47`](https://github.com/xataio/client-ts/commit/19c5dd47e3a032fcb19d990527b8faaa9326d97d), [`d282d18f`](https://github.com/xataio/client-ts/commit/d282d18f025094e0729ade6009b34fc0d34ebbba)]: - - @xata.io/client@0.27.0 - -## 0.1.35 - -### Patch Changes - -- Updated dependencies [[`302798e8`](https://github.com/xataio/client-ts/commit/302798e8d210c89f420a5c927e0f836a27dbaed9)]: - - @xata.io/client@0.26.9 - -## 0.1.34 - -### Patch Changes - -- Updated dependencies [[`fa2883b0`](https://github.com/xataio/client-ts/commit/fa2883b0639e48d68097401bf515c8cb95df5b4b), [`c04faece`](https://github.com/xataio/client-ts/commit/c04faece8830699d978e03c89f29e383e479e824), [`cb45cc9f`](https://github.com/xataio/client-ts/commit/cb45cc9f6829e1b555762e656cc1b0b2e977aaf9)]: - - @xata.io/client@0.26.8 - -## 0.1.33 - -### Patch Changes - -- Updated dependencies [[`0e1c50de`](https://github.com/xataio/client-ts/commit/0e1c50de5850db2dfbbdfff9d66eda3bf1322836), [`d093d363`](https://github.com/xataio/client-ts/commit/d093d363a51fc23c8513d51600bb3b31bbc45334)]: - - @xata.io/client@0.26.7 - -## 0.1.32 - -### Patch Changes - -- Updated dependencies [[`3330c9cf`](https://github.com/xataio/client-ts/commit/3330c9cf8d8db18b8e355a576e4afd589b6152bf), [`a738816d`](https://github.com/xataio/client-ts/commit/a738816d355f4415b0622bb5a23b4154f9855177)]: - - @xata.io/client@0.26.6 - -## 0.1.31 - -### Patch Changes - -- Updated dependencies [[`b9b9058f`](https://github.com/xataio/client-ts/commit/b9b9058f0bc81b660da45318c27191a62f041f21)]: - - @xata.io/client@0.26.5 - -## 0.1.30 - -### Patch Changes - -- Updated dependencies [[`7166797c`](https://github.com/xataio/client-ts/commit/7166797c28839198d20a9115d0414cebc2fed39b), [`b85df75f`](https://github.com/xataio/client-ts/commit/b85df75f2f466762a8b3d9824c9292c7e3db03fd)]: - - @xata.io/client@0.26.4 - -## 0.1.29 - -### Patch Changes - -- Updated dependencies [[`4910dce2`](https://github.com/xataio/client-ts/commit/4910dce29d3cc17d13aadf32e4eb476ffb571fad)]: - - @xata.io/client@0.26.3 - -## 0.1.28 - -### Patch Changes - -- Updated dependencies [[`22fccb51`](https://github.com/xataio/client-ts/commit/22fccb51709749c319897702c15749b74ce4b820)]: - - @xata.io/client@0.26.2 - -## 0.1.27 - -### Patch Changes - -- Updated dependencies [[`922e6e54`](https://github.com/xataio/client-ts/commit/922e6e54e8b31641770a36b6b4ff8f4fa65d304d), [`13f6f3e4`](https://github.com/xataio/client-ts/commit/13f6f3e4b1a2f925d50a5380b62ef1057f5c3893), [`f02fc165`](https://github.com/xataio/client-ts/commit/f02fc165bf6558e4377eb9f8e1d0f4222f004c70)]: - - @xata.io/client@0.26.1 - -## 0.1.26 - -### Patch Changes - -- Updated dependencies [[`6ec862f8`](https://github.com/xataio/client-ts/commit/6ec862f8f799eb692f62be79dd0b613b83a34780), [`0c0149ad`](https://github.com/xataio/client-ts/commit/0c0149ad1ee3f7c0fe9d31030552b022c907edb0)]: - - @xata.io/client@0.26.0 - -## 0.1.25 - -### Patch Changes - -- Updated dependencies [[`3b9e1984`](https://github.com/xataio/client-ts/commit/3b9e1984329cd0e9f885f6af4155cc85ab61ba41)]: - - @xata.io/client@0.25.3 - -## 0.1.24 - -### Patch Changes - -- Updated dependencies [[`9d1ace5f`](https://github.com/xataio/client-ts/commit/9d1ace5f12788755f3150449120b27cd030af3a9), [`f6665593`](https://github.com/xataio/client-ts/commit/f6665593c301dc9400834cbd68ae32b92bbdea5d)]: - - @xata.io/client@0.25.2 - -## 0.1.23 - -### Patch Changes - -- Updated dependencies [[`321c33ff`](https://github.com/xataio/client-ts/commit/321c33ff684c416a6cc813be2a970fd8f826b885)]: - - @xata.io/client@0.25.1 - -## 0.1.22 - -### Patch Changes - -- Updated dependencies [[`ac3b968f`](https://github.com/xataio/client-ts/commit/ac3b968f7ca476f2c82b1b2719d020fbd7164f38), [`aef9c834`](https://github.com/xataio/client-ts/commit/aef9c834a850494020e7585cb4ce67b446f9ccfc), [`bcce0d3b`](https://github.com/xataio/client-ts/commit/bcce0d3b0b53468937accd4fee3b5485c35f69ad), [`c1f2d264`](https://github.com/xataio/client-ts/commit/c1f2d2649e077cdffae97c90b9d2b1c75d6858fb), [`6c2c2630`](https://github.com/xataio/client-ts/commit/6c2c26308d4cbd25e7a9677c7d25c836396d4965)]: - - @xata.io/client@0.25.0 - -## 0.1.21 - -### Patch Changes - -- Updated dependencies [[`f01d1580`](https://github.com/xataio/client-ts/commit/f01d1580fc450cbf06eb8af85d68cf052fbe83a1), [`52290feb`](https://github.com/xataio/client-ts/commit/52290feb5bba57384cdc14e7722fb5d9883dc581)]: - - @xata.io/client@0.24.3 - -## 0.1.20 - -### Patch Changes - -- Updated dependencies [[`51561b52`](https://github.com/xataio/client-ts/commit/51561b52b56ad5ed9101d8faf12929891419cb2c)]: - - @xata.io/client@0.24.2 - -## 0.1.19 - -### Patch Changes - -- Updated dependencies [[`eaa774f5`](https://github.com/xataio/client-ts/commit/eaa774f542185ef92448155bcdff331686c4da9f)]: - - @xata.io/client@0.24.1 - -## 0.1.18 - -### Patch Changes - -- Updated dependencies [[`45aa2207`](https://github.com/xataio/client-ts/commit/45aa220728e98dd716a55a9a307474732a9b2bc1), [`f28080f0`](https://github.com/xataio/client-ts/commit/f28080f034f02704fe00d64b8f42e1127bde30c7), [`ac9c0604`](https://github.com/xataio/client-ts/commit/ac9c06042bb85105d9a38624676ce6ea5a27d488), [`c163b365`](https://github.com/xataio/client-ts/commit/c163b3658f23fb2eaad6243ebebc92624754099a)]: - - @xata.io/client@0.24.0 - -## 0.1.17 - -### Patch Changes - -- [#972](https://github.com/xataio/client-ts/pull/972) [`89375e76`](https://github.com/xataio/client-ts/commit/89375e76b790fed7e6a26bf3ac4ea9eaed1aecae) Thanks [@SferaDev](https://github.com/SferaDev)! - Add types to exports - -- Updated dependencies [[`20cc8c43`](https://github.com/xataio/client-ts/commit/20cc8c43e1659bf112ae2642948c84bfcf46a6ba), [`5099cbbd`](https://github.com/xataio/client-ts/commit/5099cbbd3065a60dcee2f1699afa1ee8ed5edb1c), [`89375e76`](https://github.com/xataio/client-ts/commit/89375e76b790fed7e6a26bf3ac4ea9eaed1aecae), [`5eaee932`](https://github.com/xataio/client-ts/commit/5eaee932b828907ae352d7c0d0584e860845434b), [`109b8790`](https://github.com/xataio/client-ts/commit/109b8790849532d9c442e7c03c67792aeafebd88)]: - - @xata.io/client@0.23.5 - -## 0.1.16 - -### Patch Changes - -- Updated dependencies [[`470cc71f`](https://github.com/xataio/client-ts/commit/470cc71f7c5c8b9fd50f789e157d2b2eecd0b3e8)]: - - @xata.io/client@0.23.4 - -## 0.1.15 - -### Patch Changes - -- Updated dependencies [[`344b0d68`](https://github.com/xataio/client-ts/commit/344b0d687962d569872d1e90d59818d28df7579c)]: - - @xata.io/client@0.23.3 - -## 0.1.14 - -### Patch Changes - -- Updated dependencies [[`c477c177`](https://github.com/xataio/client-ts/commit/c477c17795c01cbf945be413217944a5a38655a5), [`ecdc6553`](https://github.com/xataio/client-ts/commit/ecdc6553d4628289e88953ab6296b80f60e8f757)]: - - @xata.io/client@0.23.2 - -## 0.1.13 - -### Patch Changes - -- Updated dependencies [[`3026d708`](https://github.com/xataio/client-ts/commit/3026d70847830fd0f2024413d823380ff323806c)]: - - @xata.io/client@0.23.1 - -## 0.1.12 - -### Patch Changes - -- Updated dependencies [[`5838113f`](https://github.com/xataio/client-ts/commit/5838113fca042163b44d7cc7cc1686d5ef89b302)]: - - @xata.io/client@0.23.0 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies [[`22e7dd29`](https://github.com/xataio/client-ts/commit/22e7dd29f7a51dccc087d5fd7fff32084c7733af), [`07fc879d`](https://github.com/xataio/client-ts/commit/07fc879d3f778536e39588e66d7a18b5a9d52ebe), [`58a1c24e`](https://github.com/xataio/client-ts/commit/58a1c24e5d30025dce243eecce44f09d4f65ed66), [`c2c6e244`](https://github.com/xataio/client-ts/commit/c2c6e24459b1acc07f0414066258071fbcf7dde9)]: - - @xata.io/client@0.22.4 - -## 0.1.10 - -### Patch Changes - -- Updated dependencies [[`4210b8c3`](https://github.com/xataio/client-ts/commit/4210b8c3c4169ba781a56deed7ba09c99788db1f)]: - - @xata.io/client@0.22.3 - -## 0.1.9 - -### Patch Changes - -- Updated dependencies [[`72e13bf9`](https://github.com/xataio/client-ts/commit/72e13bf99d0ebefef91c984a995a28b0e8ca2a8f)]: - - @xata.io/client@0.22.2 - -## 0.1.8 - -### Patch Changes - -- Updated dependencies [[`4cafde72`](https://github.com/xataio/client-ts/commit/4cafde728e4e9e5e83812d475d9980397ae78362), [`639710a5`](https://github.com/xataio/client-ts/commit/639710a52132f260bf3a26560a21ae2193abb71d)]: - - @xata.io/client@0.22.1 - -## 0.1.7 - -### Patch Changes - -- Updated dependencies [[`b2a4def4`](https://github.com/xataio/client-ts/commit/b2a4def4baf3eb18cd323895635e0bccb7f876f4), [`379e6144`](https://github.com/xataio/client-ts/commit/379e61446b21e7cbadd7fc59267736c6845ec566)]: - - @xata.io/client@0.22.0 - -## 0.1.6 - -### Patch Changes - -- [#828](https://github.com/xataio/client-ts/pull/828) [`039e35bf`](https://github.com/xataio/client-ts/commit/039e35bf9f01149f39bca39e1867908ca3468bb5) Thanks [@SferaDev](https://github.com/SferaDev)! - Add branded types to serializer - -- Updated dependencies [[`039e35bf`](https://github.com/xataio/client-ts/commit/039e35bf9f01149f39bca39e1867908ca3468bb5), [`039e35bf`](https://github.com/xataio/client-ts/commit/039e35bf9f01149f39bca39e1867908ca3468bb5)]: - - @xata.io/client@0.21.6 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies [[`b131040a`](https://github.com/xataio/client-ts/commit/b131040a2d142c4e71a2e586fbf05cd9295af9a1), [`7ea810dc`](https://github.com/xataio/client-ts/commit/7ea810dc083ec284447e3bd27bd0465f887481e6), [`d124cbfb`](https://github.com/xataio/client-ts/commit/d124cbfb93d3d591e79bbe9e94c4b6304d825e71), [`d124cbfb`](https://github.com/xataio/client-ts/commit/d124cbfb93d3d591e79bbe9e94c4b6304d825e71), [`fb5ccdf9`](https://github.com/xataio/client-ts/commit/fb5ccdf9fa95c37d54fbc5d9c0bb45872c831609), [`7da604d2`](https://github.com/xataio/client-ts/commit/7da604d27990e20ecadba6122434fca563e6a8c9), [`4ae00036`](https://github.com/xataio/client-ts/commit/4ae00036b53c6c89e02a1fcfdd992f1a3c22892c), [`bdae6668`](https://github.com/xataio/client-ts/commit/bdae6668fb571d29f1b1068a54f6866a80d9b174), [`9486bdcc`](https://github.com/xataio/client-ts/commit/9486bdccc0af567bc5f2e8f91592b0143c539c45), [`9486bdcc`](https://github.com/xataio/client-ts/commit/9486bdccc0af567bc5f2e8f91592b0143c539c45)]: - - @xata.io/client@0.21.0 - -## 0.1.4 - -### Patch Changes - -- Updated dependencies [[`6cbeaa0`](https://github.com/xataio/client-ts/commit/6cbeaa00050b5aa99ab7c98052a906487263e026), [`a5a9aa5`](https://github.com/xataio/client-ts/commit/a5a9aa59987faa1d3d701d7431b8a96031e01ac7), [`c64b2eb`](https://github.com/xataio/client-ts/commit/c64b2eb9add70e75d419d418ab9608caac0dbfa1), [`485b217`](https://github.com/xataio/client-ts/commit/485b217079c4b2091d697e68622c48eddd130ceb), [`4d7499c`](https://github.com/xataio/client-ts/commit/4d7499ccbb135691350334fd8022f7a5da41c5f2)]: - - @xata.io/client@0.20.0 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies [[`f80f051`](https://github.com/xataio/client-ts/commit/f80f05118dd0588861b8229114a469f016ef77ac), [`c14f431`](https://github.com/xataio/client-ts/commit/c14f431db020036ab2b059bcc52a5d56b321c8e7), [`2e341e5`](https://github.com/xataio/client-ts/commit/2e341e5c6140f9c4ddd74e479049992c26c43ea2), [`c8def01`](https://github.com/xataio/client-ts/commit/c8def013e9e2d5b634cdb2850f757a0b3e9e0a6d), [`f2f749f`](https://github.com/xataio/client-ts/commit/f2f749f4c64246a303da8d4a617773fc55c1d021), [`f2f749f`](https://github.com/xataio/client-ts/commit/f2f749f4c64246a303da8d4a617773fc55c1d021)]: - - @xata.io/client@0.19.0 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies [[`330b076`](https://github.com/xataio/client-ts/commit/330b076a0781e3576c82afab76e3fb2a64f2e041), [`c3dfb4b`](https://github.com/xataio/client-ts/commit/c3dfb4babc990634b9e9747616ed93223178a2e7), [`699beb4`](https://github.com/xataio/client-ts/commit/699beb4bbf21cffa001d3f88a03246980e30250b), [`74b17aa`](https://github.com/xataio/client-ts/commit/74b17aaedc0dbdd79bfdcb182b2e70b61f98f5a5), [`83f20cd`](https://github.com/xataio/client-ts/commit/83f20cdbe53706c16016c4db3f318e679b24ec86), [`addfcc6`](https://github.com/xataio/client-ts/commit/addfcc67fca663defdd340111ea09c9188bad3ab), [`eb7ba59`](https://github.com/xataio/client-ts/commit/eb7ba594be2a1f0ab90956836bbeb912e188a46d), [`f1a0742`](https://github.com/xataio/client-ts/commit/f1a0742a04e1aefab14f46371a04a41069faec01)]: - - @xata.io/client@0.18.0 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies [[`26e91d1`](https://github.com/xataio/client-ts/commit/26e91d1d84df082dedd7159271fc7c27ec87fefe), [`3332d43`](https://github.com/xataio/client-ts/commit/3332d43121367f61c8d87dfb7da2af65bd1c278f)]: - - @xata.io/client@0.17.0 - -## 0.1.0 - -### Minor Changes - -- [#485](https://github.com/xataio/client-ts/pull/485) [`7e04a3d`](https://github.com/xataio/client-ts/commit/7e04a3d1c51958a44f687a0036ead8bb3f5a2dfb) Thanks [@SferaDev](https://github.com/SferaDev)! - Remove record cache - -### Patch Changes - -- Updated dependencies [[`6a96ea5`](https://github.com/xataio/client-ts/commit/6a96ea5da4c5b7ca9a99b57ebbce8d6766b5d4d8), [`43f2560`](https://github.com/xataio/client-ts/commit/43f25605ddd0d2fd514a1542a14389d28955c500), [`a9cbb26`](https://github.com/xataio/client-ts/commit/a9cbb263fbca47cb91a827db252d95a5bb4079a6), [`7e04a3d`](https://github.com/xataio/client-ts/commit/7e04a3d1c51958a44f687a0036ead8bb3f5a2dfb)]: - - @xata.io/client@0.16.0 - -## 0.0.8 - -### Patch Changes - -- Updated dependencies [[`e923d11`](https://github.com/xataio/client-ts/commit/e923d11fe357519dc4ca3ae722670e6e70ccd1c6), [`599b52c`](https://github.com/xataio/client-ts/commit/599b52c3090222eedef85d1ad1e907874cd3e801)]: - - @xata.io/client@0.15.0 - -## 0.0.7 - -### Patch Changes - -- Updated dependencies [[`7547b7e`](https://github.com/xataio/client-ts/commit/7547b7edbc9a95c6620784cc5348316f27502c73), [`8812380`](https://github.com/xataio/client-ts/commit/881238062b5eeac2dc8b9ba156720e0acc22c5c5), [`0584a5b`](https://github.com/xataio/client-ts/commit/0584a5b207a21dbc36ddc1d44b276f1d5bb60dc5), [`8d8a912`](https://github.com/xataio/client-ts/commit/8d8a9129e36452266c4c12fe35b421f66e572498), [`e99010c`](https://github.com/xataio/client-ts/commit/e99010c9ab9d355abadcfbcf98b5a3fcc80c307a), [`c4be404`](https://github.com/xataio/client-ts/commit/c4be404a3ecb34df9b1ef4501c92f5bdc221f19c)]: - - @xata.io/client@0.14.0 - -## 0.0.6 - -### Patch Changes - -- Updated dependencies [[`c9f34ad`](https://github.com/xataio/client-ts/commit/c9f34ad37d75203083a1dec2fac2b03e096521af), [`5f82e43`](https://github.com/xataio/client-ts/commit/5f82e4394010f40dcbf3faf2d0bdb58a6fc1c37a)]: - - @xata.io/client@0.13.0 - -## 0.0.5 - -### Patch Changes - -- Updated dependencies [[`db3c88e`](https://github.com/xataio/client-ts/commit/db3c88e1f2bee6d308afb8d6e95b7c090a87e7a7), [`1cde95f`](https://github.com/xataio/client-ts/commit/1cde95f05a6b9fbf0564ea05400140f0cef41a3a), [`57bf0e2`](https://github.com/xataio/client-ts/commit/57bf0e2e049ed0498683ff42d287983f295342b7)]: - - @xata.io/client@0.12.0 - -## 0.0.4 - -### Patch Changes - -- Updated dependencies [[`505257c`](https://github.com/xataio/client-ts/commit/505257c0c42ca0c8beaf5c0f638037c576dcc43c), [`ff7e5c6`](https://github.com/xataio/client-ts/commit/ff7e5c6f211913196d8c28600d7a7675ed261688), [`bf64cb8`](https://github.com/xataio/client-ts/commit/bf64cb885d55a0271e966314384324f02ded084e), [`ce07601`](https://github.com/xataio/client-ts/commit/ce07601e4ddf9f75e20249d479dc04a63795ca96), [`bc64c28`](https://github.com/xataio/client-ts/commit/bc64c28fbfbb000c7190ac8092e2ef6a261df86f), [`12f1ce3`](https://github.com/xataio/client-ts/commit/12f1ce362f6cda27dfdb3afab0800282bddc8b5e), [`a73a2a2`](https://github.com/xataio/client-ts/commit/a73a2a2014c44cf88eaef42196ba1dba9d516b4a)]: - - @xata.io/client@0.11.0 - -## 0.0.3 - -### Patch Changes - -- Updated dependencies [[`6d76275`](https://github.com/xataio/client-ts/commit/6d7627555a404a4c2da42f4187df6f8300f9a46f), [`d1ec0df`](https://github.com/xataio/client-ts/commit/d1ec0df14834088a816919bfc68216f3f9b2d9ef), [`1864742`](https://github.com/xataio/client-ts/commit/18647428d8608841de514c3784fb711c39dccc6d), [`1af6f1a`](https://github.com/xataio/client-ts/commit/1af6f1aaa1123e77a895961581c87f06a88db698), [`be4eda8`](https://github.com/xataio/client-ts/commit/be4eda8f73037d97fef7de28b56d7471dd867875), [`99be734`](https://github.com/xataio/client-ts/commit/99be734827576d888aa12a579ed1983a0a8a8e83)]: - - @xata.io/client@0.10.0 - -## 0.0.2 - -### Patch Changes - -- [#247](https://github.com/xataio/client-ts/pull/247) [`53b4ad6`](https://github.com/xataio/client-ts/commit/53b4ad670c9f35387e4d0e26aec5ce0dfd340d07) Thanks [@SferaDev](https://github.com/SferaDev)! - Initial release - -- Updated dependencies [[`2fc2788`](https://github.com/xataio/client-ts/commit/2fc2788e583c047ffb2cd693f053f60ce608149c), [`a96da7c`](https://github.com/xataio/client-ts/commit/a96da7c8b548604ed25001390992531537675a44), [`e8d595f`](https://github.com/xataio/client-ts/commit/e8d595f54efe126b39c78cc771a5d69c551f4fba), [`c4dcd11`](https://github.com/xataio/client-ts/commit/c4dcd110d8f9dc3a7e4510f2f00257c9109e51fa), [`2848894`](https://github.com/xataio/client-ts/commit/284889446bbac5d6737086bf01a588d97b841730)]: - - @xata.io/client@0.9.0 diff --git a/packages/plugin-client-cache/package.json b/packages/plugin-client-cache/package.json deleted file mode 100644 index deadc8b68..000000000 --- a/packages/plugin-client-cache/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "@xata.io/plugin-client-cache", - "version": "0.1.46", - "description": "", - "main": "./dist/index.cjs", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "import": "./dist/index.mjs", - "require": "./dist/index.cjs", - "types": "./dist/index.d.ts" - } - }, - "scripts": { - "build": "rimraf dist && rollup -c", - "tsc": "tsc --noEmit" - }, - "author": "", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/xataio/client-ts/issues" - }, - "dependencies": { - "@xata.io/client": "workspace:*" - }, - "devDependencies": { - "lru-cache": "^10.2.0" - }, - "peerDependencies": { - "lru-cache": "^7" - } -} diff --git a/packages/plugin-client-cache/rollup.config.mjs b/packages/plugin-client-cache/rollup.config.mjs deleted file mode 100644 index 9c57e2aa4..000000000 --- a/packages/plugin-client-cache/rollup.config.mjs +++ /dev/null @@ -1,29 +0,0 @@ -import dts from 'rollup-plugin-dts'; -import esbuild from 'rollup-plugin-esbuild'; - -export default [ - { - input: 'src/index.ts', - plugins: [esbuild()], - output: [ - { - file: `dist/index.cjs`, - format: 'cjs', - sourcemap: true - }, - { - file: `dist/index.mjs`, - format: 'es', - sourcemap: true - } - ] - }, - { - input: 'src/index.ts', - plugins: [dts()], - output: { - file: `dist/index.d.ts`, - format: 'es' - } - } -]; diff --git a/packages/plugin-client-cache/src/index.ts b/packages/plugin-client-cache/src/index.ts deleted file mode 100644 index 43558e57f..000000000 --- a/packages/plugin-client-cache/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './lru-cache'; diff --git a/packages/plugin-client-cache/src/lru-cache.ts b/packages/plugin-client-cache/src/lru-cache.ts deleted file mode 100644 index eee419c94..000000000 --- a/packages/plugin-client-cache/src/lru-cache.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { LRUCache as LRU } from 'lru-cache'; -import { CacheImpl } from '@xata.io/client'; - -export type LRUCacheOptions = Partial>; - -export class LRUCache implements CacheImpl { - #cache: LRU; - defaultQueryTTL: number; - - constructor(options: LRUCacheOptions = {}) { - this.#cache = new LRU({ max: 500, ...options }); - this.defaultQueryTTL = options.ttl ?? 60 * 1000; - } - - async getAll(): Promise> { - const entries = this.#cache.dump().map(([key, { value }]) => [key, value]); - return Object.fromEntries(entries); - } - - async get(key: string): Promise { - return this.#cache.get(key) ?? null; - } - - async set(key: string, value: T): Promise { - this.#cache.set(key, value); - } - - async delete(key: string): Promise { - this.#cache.delete(key); - } - - async clear(): Promise { - this.#cache.clear(); - } -} diff --git a/packages/plugin-client-cache/tsconfig.json b/packages/plugin-client-cache/tsconfig.json deleted file mode 100644 index 654c56dd1..000000000 --- a/packages/plugin-client-cache/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "target": "es2020", - "lib": ["esnext"], - "allowJs": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true, - "module": "es2020", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": false, - "outDir": "dist", - "declaration": true - }, - "include": ["src"], - "exclude": ["node_modules"] -} diff --git a/packages/plugin-client-cloudflare/.npmignore b/packages/plugin-client-cloudflare/.npmignore deleted file mode 100644 index c97b8ad26..000000000 --- a/packages/plugin-client-cloudflare/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -src -tsconfig.json -rollup.config.mjs -.eslintrc.cjs -.gitignore diff --git a/packages/plugin-client-cloudflare/CHANGELOG.md b/packages/plugin-client-cloudflare/CHANGELOG.md deleted file mode 100644 index 1dffd216d..000000000 --- a/packages/plugin-client-cloudflare/CHANGELOG.md +++ /dev/null @@ -1,313 +0,0 @@ -# @xata.io/plugin-client-cloudflare - -## 0.0.45 - -### Patch Changes - -- Updated dependencies [[`2140a24`](https://github.com/xataio/client-ts/commit/2140a24f32a94f36bab8c8268033c7dcf235dddc), [`d8032f2`](https://github.com/xataio/client-ts/commit/d8032f2e07bdcc653db1606796d27f08d397cdbe)]: - - @xata.io/client@0.29.4 - -## 0.0.44 - -### Patch Changes - -- Updated dependencies [[`02053fb`](https://github.com/xataio/client-ts/commit/02053fbb10479b8e9453691f957d3235762555aa), [`e27cb74`](https://github.com/xataio/client-ts/commit/e27cb74143aa9b6c654713878e5d3776858e5290)]: - - @xata.io/client@0.29.3 - -## 0.0.43 - -### Patch Changes - -- Updated dependencies [[`e8db1cd`](https://github.com/xataio/client-ts/commit/e8db1cd394ccbed32403548bf9d09a5c3973d850)]: - - @xata.io/client@0.29.2 - -## 0.0.42 - -### Patch Changes - -- Updated dependencies [[`d0f5d12`](https://github.com/xataio/client-ts/commit/d0f5d125e6c2f4c82f8a0a6b4a30d255c58e8326), [`212b53d`](https://github.com/xataio/client-ts/commit/212b53d07498def0d2ed8942691eff982e448969), [`9fd8c42`](https://github.com/xataio/client-ts/commit/9fd8c428d71b476f1951123c6cba5e803b983e54), [`368d4aa`](https://github.com/xataio/client-ts/commit/368d4aa16cd1cc1da93a142406c5d41bbc15b082)]: - - @xata.io/client@0.29.1 - -## 0.0.41 - -### Patch Changes - -- Updated dependencies [[`0ec026a`](https://github.com/xataio/client-ts/commit/0ec026a92bdb1a405cb9d90cb1d506ff159f98e8), [`6414bd3`](https://github.com/xataio/client-ts/commit/6414bd3d8bdb84961e68968df4b0b025503f0d72), [`27773df`](https://github.com/xataio/client-ts/commit/27773df5addf0013d1a7238ac490904e7aad2334)]: - - @xata.io/client@0.29.0 - -## 0.0.40 - -### Patch Changes - -- Updated dependencies [[`adc961b`](https://github.com/xataio/client-ts/commit/adc961b886b789010e6512c17cb2377eceab665a), [`6031a9d`](https://github.com/xataio/client-ts/commit/6031a9de63c264b7db5b031bb1795258c2bf8150)]: - - @xata.io/client@0.28.4 - -## 0.0.39 - -### Patch Changes - -- Updated dependencies [[`b7f3ec9`](https://github.com/xataio/client-ts/commit/b7f3ec9eabe3642929131e244bd774f4d3134482)]: - - @xata.io/client@0.28.3 - -## 0.0.38 - -### Patch Changes - -- Updated dependencies [[`c9178e1`](https://github.com/xataio/client-ts/commit/c9178e1e3f2268513e78dcfce396a99a8fca5dfb)]: - - @xata.io/client@0.28.2 - -## 0.0.37 - -### Patch Changes - -- Updated dependencies [[`9a7e3f5`](https://github.com/xataio/client-ts/commit/9a7e3f5029e53efc6750e9c86bab936427788209)]: - - @xata.io/client@0.28.1 - -## 0.0.36 - -### Patch Changes - -- Updated dependencies [[`e97d1999`](https://github.com/xataio/client-ts/commit/e97d1999f3c25f149213ceca81958e1674624e05)]: - - @xata.io/client@0.28.0 - -## 0.0.35 - -### Patch Changes - -- Updated dependencies [[`19c5dd47`](https://github.com/xataio/client-ts/commit/19c5dd47e3a032fcb19d990527b8faaa9326d97d), [`d282d18f`](https://github.com/xataio/client-ts/commit/d282d18f025094e0729ade6009b34fc0d34ebbba)]: - - @xata.io/client@0.27.0 - -## 0.0.34 - -### Patch Changes - -- Updated dependencies [[`302798e8`](https://github.com/xataio/client-ts/commit/302798e8d210c89f420a5c927e0f836a27dbaed9)]: - - @xata.io/client@0.26.9 - -## 0.0.33 - -### Patch Changes - -- Updated dependencies [[`fa2883b0`](https://github.com/xataio/client-ts/commit/fa2883b0639e48d68097401bf515c8cb95df5b4b), [`c04faece`](https://github.com/xataio/client-ts/commit/c04faece8830699d978e03c89f29e383e479e824), [`cb45cc9f`](https://github.com/xataio/client-ts/commit/cb45cc9f6829e1b555762e656cc1b0b2e977aaf9)]: - - @xata.io/client@0.26.8 - -## 0.0.32 - -### Patch Changes - -- Updated dependencies [[`0e1c50de`](https://github.com/xataio/client-ts/commit/0e1c50de5850db2dfbbdfff9d66eda3bf1322836), [`d093d363`](https://github.com/xataio/client-ts/commit/d093d363a51fc23c8513d51600bb3b31bbc45334)]: - - @xata.io/client@0.26.7 - -## 0.0.31 - -### Patch Changes - -- Updated dependencies [[`3330c9cf`](https://github.com/xataio/client-ts/commit/3330c9cf8d8db18b8e355a576e4afd589b6152bf), [`a738816d`](https://github.com/xataio/client-ts/commit/a738816d355f4415b0622bb5a23b4154f9855177)]: - - @xata.io/client@0.26.6 - -## 0.0.30 - -### Patch Changes - -- Updated dependencies [[`b9b9058f`](https://github.com/xataio/client-ts/commit/b9b9058f0bc81b660da45318c27191a62f041f21)]: - - @xata.io/client@0.26.5 - -## 0.0.29 - -### Patch Changes - -- Updated dependencies [[`7166797c`](https://github.com/xataio/client-ts/commit/7166797c28839198d20a9115d0414cebc2fed39b), [`b85df75f`](https://github.com/xataio/client-ts/commit/b85df75f2f466762a8b3d9824c9292c7e3db03fd)]: - - @xata.io/client@0.26.4 - -## 0.0.28 - -### Patch Changes - -- Updated dependencies [[`4910dce2`](https://github.com/xataio/client-ts/commit/4910dce29d3cc17d13aadf32e4eb476ffb571fad)]: - - @xata.io/client@0.26.3 - -## 0.0.27 - -### Patch Changes - -- Updated dependencies [[`22fccb51`](https://github.com/xataio/client-ts/commit/22fccb51709749c319897702c15749b74ce4b820)]: - - @xata.io/client@0.26.2 - -## 0.0.26 - -### Patch Changes - -- Updated dependencies [[`922e6e54`](https://github.com/xataio/client-ts/commit/922e6e54e8b31641770a36b6b4ff8f4fa65d304d), [`13f6f3e4`](https://github.com/xataio/client-ts/commit/13f6f3e4b1a2f925d50a5380b62ef1057f5c3893), [`f02fc165`](https://github.com/xataio/client-ts/commit/f02fc165bf6558e4377eb9f8e1d0f4222f004c70)]: - - @xata.io/client@0.26.1 - -## 0.0.25 - -### Patch Changes - -- Updated dependencies [[`6ec862f8`](https://github.com/xataio/client-ts/commit/6ec862f8f799eb692f62be79dd0b613b83a34780), [`0c0149ad`](https://github.com/xataio/client-ts/commit/0c0149ad1ee3f7c0fe9d31030552b022c907edb0)]: - - @xata.io/client@0.26.0 - -## 0.0.24 - -### Patch Changes - -- Updated dependencies [[`3b9e1984`](https://github.com/xataio/client-ts/commit/3b9e1984329cd0e9f885f6af4155cc85ab61ba41)]: - - @xata.io/client@0.25.3 - -## 0.0.23 - -### Patch Changes - -- Updated dependencies [[`9d1ace5f`](https://github.com/xataio/client-ts/commit/9d1ace5f12788755f3150449120b27cd030af3a9), [`f6665593`](https://github.com/xataio/client-ts/commit/f6665593c301dc9400834cbd68ae32b92bbdea5d)]: - - @xata.io/client@0.25.2 - -## 0.0.22 - -### Patch Changes - -- Updated dependencies [[`321c33ff`](https://github.com/xataio/client-ts/commit/321c33ff684c416a6cc813be2a970fd8f826b885)]: - - @xata.io/client@0.25.1 - -## 0.0.21 - -### Patch Changes - -- Updated dependencies [[`ac3b968f`](https://github.com/xataio/client-ts/commit/ac3b968f7ca476f2c82b1b2719d020fbd7164f38), [`aef9c834`](https://github.com/xataio/client-ts/commit/aef9c834a850494020e7585cb4ce67b446f9ccfc), [`bcce0d3b`](https://github.com/xataio/client-ts/commit/bcce0d3b0b53468937accd4fee3b5485c35f69ad), [`c1f2d264`](https://github.com/xataio/client-ts/commit/c1f2d2649e077cdffae97c90b9d2b1c75d6858fb), [`6c2c2630`](https://github.com/xataio/client-ts/commit/6c2c26308d4cbd25e7a9677c7d25c836396d4965)]: - - @xata.io/client@0.25.0 - -## 0.0.20 - -### Patch Changes - -- Updated dependencies [[`f01d1580`](https://github.com/xataio/client-ts/commit/f01d1580fc450cbf06eb8af85d68cf052fbe83a1), [`52290feb`](https://github.com/xataio/client-ts/commit/52290feb5bba57384cdc14e7722fb5d9883dc581)]: - - @xata.io/client@0.24.3 - -## 0.0.19 - -### Patch Changes - -- Updated dependencies [[`51561b52`](https://github.com/xataio/client-ts/commit/51561b52b56ad5ed9101d8faf12929891419cb2c)]: - - @xata.io/client@0.24.2 - -## 0.0.18 - -### Patch Changes - -- Updated dependencies [[`eaa774f5`](https://github.com/xataio/client-ts/commit/eaa774f542185ef92448155bcdff331686c4da9f)]: - - @xata.io/client@0.24.1 - -## 0.0.17 - -### Patch Changes - -- Updated dependencies [[`45aa2207`](https://github.com/xataio/client-ts/commit/45aa220728e98dd716a55a9a307474732a9b2bc1), [`f28080f0`](https://github.com/xataio/client-ts/commit/f28080f034f02704fe00d64b8f42e1127bde30c7), [`ac9c0604`](https://github.com/xataio/client-ts/commit/ac9c06042bb85105d9a38624676ce6ea5a27d488), [`c163b365`](https://github.com/xataio/client-ts/commit/c163b3658f23fb2eaad6243ebebc92624754099a)]: - - @xata.io/client@0.24.0 - -## 0.0.16 - -### Patch Changes - -- [#972](https://github.com/xataio/client-ts/pull/972) [`89375e76`](https://github.com/xataio/client-ts/commit/89375e76b790fed7e6a26bf3ac4ea9eaed1aecae) Thanks [@SferaDev](https://github.com/SferaDev)! - Add types to exports - -- Updated dependencies [[`20cc8c43`](https://github.com/xataio/client-ts/commit/20cc8c43e1659bf112ae2642948c84bfcf46a6ba), [`5099cbbd`](https://github.com/xataio/client-ts/commit/5099cbbd3065a60dcee2f1699afa1ee8ed5edb1c), [`89375e76`](https://github.com/xataio/client-ts/commit/89375e76b790fed7e6a26bf3ac4ea9eaed1aecae), [`5eaee932`](https://github.com/xataio/client-ts/commit/5eaee932b828907ae352d7c0d0584e860845434b), [`109b8790`](https://github.com/xataio/client-ts/commit/109b8790849532d9c442e7c03c67792aeafebd88)]: - - @xata.io/client@0.23.5 - -## 0.0.15 - -### Patch Changes - -- Updated dependencies [[`470cc71f`](https://github.com/xataio/client-ts/commit/470cc71f7c5c8b9fd50f789e157d2b2eecd0b3e8)]: - - @xata.io/client@0.23.4 - -## 0.0.14 - -### Patch Changes - -- Updated dependencies [[`344b0d68`](https://github.com/xataio/client-ts/commit/344b0d687962d569872d1e90d59818d28df7579c)]: - - @xata.io/client@0.23.3 - -## 0.0.13 - -### Patch Changes - -- Updated dependencies [[`c477c177`](https://github.com/xataio/client-ts/commit/c477c17795c01cbf945be413217944a5a38655a5), [`ecdc6553`](https://github.com/xataio/client-ts/commit/ecdc6553d4628289e88953ab6296b80f60e8f757)]: - - @xata.io/client@0.23.2 - -## 0.0.12 - -### Patch Changes - -- Updated dependencies [[`3026d708`](https://github.com/xataio/client-ts/commit/3026d70847830fd0f2024413d823380ff323806c)]: - - @xata.io/client@0.23.1 - -## 0.0.11 - -### Patch Changes - -- Updated dependencies [[`5838113f`](https://github.com/xataio/client-ts/commit/5838113fca042163b44d7cc7cc1686d5ef89b302)]: - - @xata.io/client@0.23.0 - -## 0.0.10 - -### Patch Changes - -- Updated dependencies [[`22e7dd29`](https://github.com/xataio/client-ts/commit/22e7dd29f7a51dccc087d5fd7fff32084c7733af), [`07fc879d`](https://github.com/xataio/client-ts/commit/07fc879d3f778536e39588e66d7a18b5a9d52ebe), [`58a1c24e`](https://github.com/xataio/client-ts/commit/58a1c24e5d30025dce243eecce44f09d4f65ed66), [`c2c6e244`](https://github.com/xataio/client-ts/commit/c2c6e24459b1acc07f0414066258071fbcf7dde9)]: - - @xata.io/client@0.22.4 - -## 0.0.9 - -### Patch Changes - -- Updated dependencies [[`4210b8c3`](https://github.com/xataio/client-ts/commit/4210b8c3c4169ba781a56deed7ba09c99788db1f)]: - - @xata.io/client@0.22.3 - -## 0.0.8 - -### Patch Changes - -- Updated dependencies [[`72e13bf9`](https://github.com/xataio/client-ts/commit/72e13bf99d0ebefef91c984a995a28b0e8ca2a8f)]: - - @xata.io/client@0.22.2 - -## 0.0.7 - -### Patch Changes - -- Updated dependencies [[`4cafde72`](https://github.com/xataio/client-ts/commit/4cafde728e4e9e5e83812d475d9980397ae78362), [`639710a5`](https://github.com/xataio/client-ts/commit/639710a52132f260bf3a26560a21ae2193abb71d)]: - - @xata.io/client@0.22.1 - -## 0.0.6 - -### Patch Changes - -- Updated dependencies [[`b2a4def4`](https://github.com/xataio/client-ts/commit/b2a4def4baf3eb18cd323895635e0bccb7f876f4), [`379e6144`](https://github.com/xataio/client-ts/commit/379e61446b21e7cbadd7fc59267736c6845ec566)]: - - @xata.io/client@0.22.0 - -## 0.0.5 - -### Patch Changes - -- [#779](https://github.com/xataio/client-ts/pull/779) [`d17755f4`](https://github.com/xataio/client-ts/commit/d17755f4e804927d37be26f6404b14282cca7740) Thanks [@SferaDev](https://github.com/SferaDev)! - Do not throw error if limit reached - -- Updated dependencies [[`6c96da45`](https://github.com/xataio/client-ts/commit/6c96da4533500ec236547f47310e99461d5457e8)]: - - @xata.io/client@0.21.3 - -## 0.0.4 - -### Patch Changes - -- Updated dependencies [[`b131040a`](https://github.com/xataio/client-ts/commit/b131040a2d142c4e71a2e586fbf05cd9295af9a1), [`7ea810dc`](https://github.com/xataio/client-ts/commit/7ea810dc083ec284447e3bd27bd0465f887481e6), [`d124cbfb`](https://github.com/xataio/client-ts/commit/d124cbfb93d3d591e79bbe9e94c4b6304d825e71), [`d124cbfb`](https://github.com/xataio/client-ts/commit/d124cbfb93d3d591e79bbe9e94c4b6304d825e71), [`fb5ccdf9`](https://github.com/xataio/client-ts/commit/fb5ccdf9fa95c37d54fbc5d9c0bb45872c831609), [`7da604d2`](https://github.com/xataio/client-ts/commit/7da604d27990e20ecadba6122434fca563e6a8c9), [`4ae00036`](https://github.com/xataio/client-ts/commit/4ae00036b53c6c89e02a1fcfdd992f1a3c22892c), [`bdae6668`](https://github.com/xataio/client-ts/commit/bdae6668fb571d29f1b1068a54f6866a80d9b174), [`9486bdcc`](https://github.com/xataio/client-ts/commit/9486bdccc0af567bc5f2e8f91592b0143c539c45), [`9486bdcc`](https://github.com/xataio/client-ts/commit/9486bdccc0af567bc5f2e8f91592b0143c539c45)]: - - @xata.io/client@0.21.0 - -## 0.0.3 - -### Patch Changes - -- Updated dependencies [[`6cbeaa0`](https://github.com/xataio/client-ts/commit/6cbeaa00050b5aa99ab7c98052a906487263e026), [`a5a9aa5`](https://github.com/xataio/client-ts/commit/a5a9aa59987faa1d3d701d7431b8a96031e01ac7), [`c64b2eb`](https://github.com/xataio/client-ts/commit/c64b2eb9add70e75d419d418ab9608caac0dbfa1), [`485b217`](https://github.com/xataio/client-ts/commit/485b217079c4b2091d697e68622c48eddd130ceb), [`4d7499c`](https://github.com/xataio/client-ts/commit/4d7499ccbb135691350334fd8022f7a5da41c5f2)]: - - @xata.io/client@0.20.0 - -## 0.0.2 - -### Patch Changes - -- Updated dependencies [[`f80f051`](https://github.com/xataio/client-ts/commit/f80f05118dd0588861b8229114a469f016ef77ac), [`c14f431`](https://github.com/xataio/client-ts/commit/c14f431db020036ab2b059bcc52a5d56b321c8e7), [`2e341e5`](https://github.com/xataio/client-ts/commit/2e341e5c6140f9c4ddd74e479049992c26c43ea2), [`c8def01`](https://github.com/xataio/client-ts/commit/c8def013e9e2d5b634cdb2850f757a0b3e9e0a6d), [`f2f749f`](https://github.com/xataio/client-ts/commit/f2f749f4c64246a303da8d4a617773fc55c1d021), [`f2f749f`](https://github.com/xataio/client-ts/commit/f2f749f4c64246a303da8d4a617773fc55c1d021)]: - - @xata.io/client@0.19.0 diff --git a/packages/plugin-client-cloudflare/package.json b/packages/plugin-client-cloudflare/package.json deleted file mode 100644 index 8e6a88e85..000000000 --- a/packages/plugin-client-cloudflare/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "@xata.io/plugin-client-cloudflare", - "version": "0.0.45", - "description": "", - "main": "./dist/index.cjs", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "import": "./dist/index.mjs", - "require": "./dist/index.cjs", - "types": "./dist/index.d.ts" - } - }, - "scripts": { - "build": "rimraf dist && rollup -c", - "tsc": "tsc --noEmit" - }, - "author": "", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/xataio/client-ts/issues" - }, - "dependencies": { - "@cloudflare/workers-types": "^4.20240405.0", - "@xata.io/client": "workspace:*" - } -} diff --git a/packages/plugin-client-cloudflare/rollup.config.mjs b/packages/plugin-client-cloudflare/rollup.config.mjs deleted file mode 100644 index 9c57e2aa4..000000000 --- a/packages/plugin-client-cloudflare/rollup.config.mjs +++ /dev/null @@ -1,29 +0,0 @@ -import dts from 'rollup-plugin-dts'; -import esbuild from 'rollup-plugin-esbuild'; - -export default [ - { - input: 'src/index.ts', - plugins: [esbuild()], - output: [ - { - file: `dist/index.cjs`, - format: 'cjs', - sourcemap: true - }, - { - file: `dist/index.mjs`, - format: 'es', - sourcemap: true - } - ] - }, - { - input: 'src/index.ts', - plugins: [dts()], - output: { - file: `dist/index.d.ts`, - format: 'es' - } - } -]; diff --git a/packages/plugin-client-cloudflare/src/cache.ts b/packages/plugin-client-cloudflare/src/cache.ts deleted file mode 100644 index 916313492..000000000 --- a/packages/plugin-client-cloudflare/src/cache.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { CacheImpl, serialize, deserialize } from '@xata.io/client'; - -export type CloudflareKVCacheOptions = { namespace: KVNamespace; ttl?: number }; - -export class CloudflareKVCache implements CacheImpl { - #kv: KVNamespace; - defaultQueryTTL: number; - - constructor(options: CloudflareKVCacheOptions) { - this.#kv = options.namespace; - this.defaultQueryTTL = options.ttl ?? 60 * 1000; - } - - // FIXME: Binding does not support bulk operations yet. - async getAll(): Promise> { - const keys = await this.#listAll(); - const values = await Promise.all(keys.map((key) => this.get(key))); - return keys.reduce((acc, key, index) => ({ ...acc, [key]: values[index] }), {}); - } - - async get(key: string): Promise { - try { - const value = await this.#kv.get(key); - if (value === null) { - return null; - } - - return deserialize(value) as T; - } catch (e) { - // Ignore, KV namespace limit reached - console.error('KV namespace error', e); - return null; - } - } - - async set(key: string, value: T): Promise { - try { - await this.#kv.put(key, serialize(value), { expirationTtl: this.defaultQueryTTL }); - } catch (e) { - // Ignore, KV namespace limit reached - console.error('KV namespace error', e); - } - } - - async delete(key: string): Promise { - try { - await this.#kv.delete(key); - } catch (e) { - // Ignore, KV namespace limit reached - console.error('KV namespace error', e); - } - } - - // FIXME: Binding does not support bulk operations yet. - async clear(): Promise { - const keys = await this.#listAll(); - for (const key in keys) { - await this.delete(key); - } - } - - async #listAll(): Promise { - const getKeys = async (cursor?: string): Promise<{ keys: string[]; cursor?: string }> => { - try { - const result = await this.#kv.list({ cursor }); - const keys = result.keys.map((key) => key.name); - const nextCursor = result.list_complete ? undefined : result.cursor; - - return { keys, cursor: nextCursor }; - } catch (e) { - // Ignore, KV namespace limit reached - console.error('KV namespace error', e); - return { keys: [] }; - } - }; - - const { keys, cursor } = await getKeys(); - - let currentCursor = cursor; - while (currentCursor) { - const { keys: nextKeys, cursor: nextCursor } = await getKeys(currentCursor); - keys.push(...nextKeys); - currentCursor = nextCursor; - } - - return keys; - } -} diff --git a/packages/plugin-client-cloudflare/src/index.ts b/packages/plugin-client-cloudflare/src/index.ts deleted file mode 100644 index 77e55d4ef..000000000 --- a/packages/plugin-client-cloudflare/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './cache'; diff --git a/packages/plugin-client-cloudflare/tsconfig.json b/packages/plugin-client-cloudflare/tsconfig.json deleted file mode 100644 index d223dc872..000000000 --- a/packages/plugin-client-cloudflare/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "target": "es2020", - "lib": ["esnext"], - "allowJs": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true, - "module": "es2020", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": false, - "outDir": "dist", - "declaration": true, - "types": ["@cloudflare/workers-types"] - }, - "include": ["src"], - "exclude": ["node_modules"] -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8fa13d805..6f701106a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -390,25 +390,6 @@ importers: specifier: ^4.7.2 version: 4.7.2 - packages/plugin-client-cache: - dependencies: - '@xata.io/client': - specifier: workspace:* - version: link:../client - devDependencies: - lru-cache: - specifier: ^10.2.0 - version: 10.2.0 - - packages/plugin-client-cloudflare: - dependencies: - '@cloudflare/workers-types': - specifier: ^4.20240405.0 - version: 4.20240405.0 - '@xata.io/client': - specifier: workspace:* - version: link:../client - packages/plugin-client-drizzle: dependencies: '@xata.io/client': @@ -3172,11 +3153,6 @@ packages: prettier: 2.8.8 dev: true - /@cloudflare/workers-types@4.20240405.0: - resolution: - { integrity: sha512-sEVOhyOgXUwfLkgHqbLZa/sfkSYrh7/zLmI6EZNibPaVPvAnAcItbNNl3SAlLyLKuwf8m4wAIAgu9meKWCvXjg== } - dev: false - /@cspotcode/source-map-support@0.8.1: resolution: { integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== } diff --git a/test/integration/cache.test.ts b/test/integration/cache.test.ts deleted file mode 100644 index 8ac6963aa..000000000 --- a/test/integration/cache.test.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test } from 'vitest'; -import { BaseClientOptions, SimpleCache } from '../../packages/client/src'; -import { XataClient } from '../../packages/codegen/example/xata'; -import { setUpTestEnvironment, TestEnvironmentResult } from '../utils/setup'; - -const cache = new SimpleCache(); - -let xata: XataClient; -let clientOptions: BaseClientOptions; -let hooks: TestEnvironmentResult['hooks']; - -beforeAll(async (ctx) => { - const result = await setUpTestEnvironment('cache', { cache }); - - xata = result.client; - clientOptions = result.clientOptions; - hooks = result.hooks; - - await hooks.beforeAll(ctx); -}); - -afterAll(async (ctx) => { - await hooks.afterAll(ctx); -}); - -beforeEach(async (ctx) => { - await hooks.beforeEach(ctx); -}); - -afterEach(async (ctx) => { - await cache.clear(); - await hooks.afterEach(ctx); -}); - -describe('cache', () => { - test('query with ttl', async () => { - const user = await xata.db.users.create({ full_name: 'John Doe' }); - - await cache.clear(); - - await xata.db.users.filter({ id: user.id }).getFirst(); - - const cacheItems = Object.entries(await cache.getAll()); - expect(Object.keys(cacheItems)).toHaveLength(1); - - const [cacheKey, value] = cacheItems[0] as any; - const cacheItem = await cache.get(cacheKey); - expect(cacheItem).not.toBeNull(); - expect(cacheItem?.records[0]?.full_name).toBe('John Doe'); - - await cache.set(cacheKey, { ...value, records: [{ ...user, full_name: 'Jane Doe' }] }); - - const query = await xata.db.users.filter({ id: user.id }).getFirst({ cache: 120000 }); - expect(query?.full_name).toBe('Jane Doe'); - }); - - test('query with expired ttl', async () => { - const user = await xata.db.users.create({ full_name: 'John Doe' }); - - await cache.clear(); - - await xata.db.users.filter({ id: user.id }).getFirst(); - - const cacheItems = Object.entries(await cache.getAll()); - expect(cacheItems).toHaveLength(1); - - const [key, value] = cacheItems[0] as any; - - await cache.set(key, { ...value, records: [{ ...user, full_name: 'Jane Doe' }] }); - - await new Promise((resolve) => setTimeout(resolve, 2000)); - - const query = await xata.db.users.filter({ id: user.id }).getFirst({ cache: 500 }); - expect(query?.full_name).toBe('John Doe'); - }); - - test("query with negative ttl doesn't cache", async () => { - const user = await xata.db.users.create({ full_name: 'John Doe' }); - - await cache.clear(); - - await xata.db.users.filter({ id: user.id }).getFirst(); - - const cacheItems = Object.entries(await cache.getAll()); - expect(cacheItems).toHaveLength(1); - - const [key, value] = cacheItems[0] as any; - - await cache.set(key, { ...value, records: [{ ...user, full_name: 'Jane Doe' }] }); - - const query = await xata.db.users.filter({ id: user.id }).getFirst({ cache: -1 }); - expect(query?.full_name).toBe('John Doe'); - }); - - test('no cache', async () => { - const client1 = new XataClient({ ...clientOptions, cache: undefined }); - const client2 = new XataClient({ ...clientOptions, cache: undefined }); - - const teamsA1 = await client1.db.teams.getAll(); - const teamsA2 = await client2.db.teams.getAll(); - - expect(teamsA1).toHaveLength(teamsA2.length); - - await client2.db.teams.create({}); - - const teamsB1 = await client1.db.teams.getAll(); - const teamsB2 = await client2.db.teams.getAll(); - - expect(teamsB1).toHaveLength(teamsB2.length); - expect(teamsB1).toHaveLength(teamsA1.length + 1); - expect(teamsB2).toHaveLength(teamsA2.length + 1); - }); -}); diff --git a/test/utils/setup.ts b/test/utils/setup.ts index f12fcb50f..063720b35 100644 --- a/test/utils/setup.ts +++ b/test/utils/setup.ts @@ -8,7 +8,7 @@ import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions' import dotenv from 'dotenv'; import { join } from 'path'; import { File, Mock, Suite, TestContext, vi } from 'vitest'; -import { BaseClient, CacheImpl, XataApiClient } from '../../packages/client/src'; +import { BaseClient, XataApiClient } from '../../packages/client/src'; import { getHostUrl, parseProviderString } from '../../packages/client/src/api/providers'; import { TraceAttributes } from '../../packages/client/src/schema/tracing'; import { XataClient } from '../../packages/codegen/example/xata'; @@ -29,7 +29,6 @@ const region = process.env.XATA_REGION || 'eu-west-1'; const host = parseProviderString(process.env.XATA_API_PROVIDER); export type EnvironmentOptions = { - cache?: CacheImpl; fetch?: any; }; @@ -45,7 +44,6 @@ export type TestEnvironmentResult = { fetch: Mock; apiKey: string; branch: string; - cache?: CacheImpl; }; hooks: { beforeAll: (ctx: Suite | File) => Promise; @@ -57,7 +55,7 @@ export type TestEnvironmentResult = { export async function setUpTestEnvironment( prefix: string, - { cache, fetch: envFetch }: EnvironmentOptions = {} + { fetch: envFetch }: EnvironmentOptions = {} ): Promise { if (host === null) { throw new Error( @@ -86,7 +84,6 @@ export async function setUpTestEnvironment( branch: 'main', apiKey, fetch, - cache, trace, clientName: 'sdk-tests' }; From 1779c52f5f7ff81f1a91939806aff83aabbb8922 Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Tue, 27 Feb 2024 08:22:48 +0100 Subject: [PATCH 05/22] Update pgroll spec Signed-off-by: Alexis Rico --- cli/src/commands/pull/index.ts | 2 +- cli/src/commands/push/index.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/src/commands/pull/index.ts b/cli/src/commands/pull/index.ts index 0f43064fe..aea162d63 100644 --- a/cli/src/commands/pull/index.ts +++ b/cli/src/commands/pull/index.ts @@ -53,7 +53,7 @@ export default class Pull extends BaseCommand { let logs: Schemas.MigrationHistoryItem[] | Schemas.Commit[] = []; if (isBranchPgRollEnabled(details)) { - const { migrations } = await xata.api.branch.pgRollMigrationHistory({ + const { migrations } = await xata.api.migrations.getMigrationHistory({ pathParams: { workspace, region, dbBranchName: `${database}:${branch}` } }); logs = migrations; diff --git a/cli/src/commands/push/index.ts b/cli/src/commands/push/index.ts index 70f016906..596b88655 100644 --- a/cli/src/commands/push/index.ts +++ b/cli/src/commands/push/index.ts @@ -49,7 +49,7 @@ export default class Push extends BaseCommand { let logs: Schemas.MigrationHistoryItem[] | Schemas.Commit[] = []; if (isBranchPgRollEnabled(details)) { - const { migrations } = await xata.api.branch.pgRollMigrationHistory({ + const { migrations } = await xata.api.migrations.getMigrationHistory({ pathParams: { workspace, region, dbBranchName: `${database}:${branch}` } }); logs = migrations; @@ -103,7 +103,7 @@ export default class Push extends BaseCommand { .flatMap((migration) => PgRollMigrationDefinition.parse(migration)); for (const migration of migrationsToPush) { try { - await xata.api.branch.applyMigration({ + await xata.api.migrations.applyMigration({ pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, body: migration }); From 9cc556cb816bb66a41fd894890861dac2844dc39 Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Tue, 27 Feb 2024 08:51:18 +0100 Subject: [PATCH 06/22] Fix release in next channel Signed-off-by: Alexis Rico --- .github/workflows/release.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 55331ed46..9c4f6aa52 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,8 +52,9 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} run: | - npx changeset version - npx changeset publish + npx changeset pre exit + npx changeset version --snapshot next + npx changeset publish --tag next --no-git-tag - name: Create Release Pull Request or Publish to npm uses: changesets/action@v1 From dfe23cae85d20872cb9922728b52d0bb33d0cbd3 Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Wed, 28 Feb 2024 16:54:14 +0100 Subject: [PATCH 07/22] Rename internal columns breaking change (#1370) Signed-off-by: Alexis Rico --- cli/src/commands/diff/index.ts | 65 --------- cli/src/utils/diff.ts | 26 ---- packages/client/src/api/fetcher.ts | 2 + packages/client/src/schema/filters.test.ts | 6 +- packages/client/src/schema/filters.ts | 3 +- packages/client/src/schema/index.test.ts | 22 +-- packages/client/src/schema/index.ts | 2 +- packages/client/src/schema/inference.spec.ts | 16 +-- packages/client/src/schema/query.ts | 4 +- packages/client/src/schema/record.ts | 70 +++------- packages/client/src/schema/repository.ts | 134 +++++++++---------- packages/client/src/schema/selection.spec.ts | 71 +++++----- packages/client/src/schema/selection.ts | 16 +-- packages/client/src/schema/sorting.spec.ts | 8 +- packages/client/src/schema/sorting.ts | 4 +- packages/client/src/search/boosters.spec.ts | 2 +- packages/client/src/search/index.ts | 18 ++- packages/codegen/example/schema.json | 60 +++++++++ packages/codegen/example/types.d.ts | 63 +++++++++ packages/codegen/example/xata.cjs | 100 ++++++++------ packages/codegen/example/xata.js | 16 ++- packages/codegen/example/xata.ts | 14 +- test/integration/create.test.ts | 116 +++++++--------- test/integration/createOrReplace.test.ts | 28 ++-- test/integration/createOrUpdate.test.ts | 38 +++--- test/integration/delete.test.ts | 34 ++--- test/integration/files.test.ts | 10 +- test/integration/json.test.ts | 24 ++-- test/integration/query.test.ts | 108 ++++++--------- test/integration/read.test.ts | 48 +++---- test/integration/revlinks.test.ts | 6 +- test/integration/search.test.ts | 76 +++++------ test/integration/smoke.test.ts | 9 +- test/integration/sql.test.ts | 117 ++++++++-------- test/integration/summarize.test.ts | 10 +- test/integration/transactions.test.ts | 32 ++--- test/integration/update.test.ts | 73 +++++----- test/mock_data.ts | 88 ++++++++++++ test/utils/setup.ts | 54 ++++++-- 39 files changed, 847 insertions(+), 746 deletions(-) delete mode 100644 cli/src/commands/diff/index.ts delete mode 100644 cli/src/utils/diff.ts diff --git a/cli/src/commands/diff/index.ts b/cli/src/commands/diff/index.ts deleted file mode 100644 index e3d6ca7d4..000000000 --- a/cli/src/commands/diff/index.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Args } from '@oclif/core'; -import { BaseCommand } from '../../base.js'; -import { getLocalMigrationFiles } from '../../migrations/files.js'; -import { buildMigrationDiff } from '../../utils/diff.js'; -import compact from 'lodash.compact'; - -export default class Diff extends BaseCommand { - static description = 'Compare two local or remote branches'; - - static examples = []; - - static flags = { - ...this.commonFlags, - ...this.databaseURLFlag - }; - - static args = { - branch: Args.string({ description: 'The branch to compare', required: false }), - base: Args.string({ description: 'The base branch to compare against', required: false }) - }; - - static hidden = true; - - static enableJsonFlag = true; - - async run() { - const { args, flags } = await this.parseCommand(); - - const xata = await this.getXataClient(); - const { workspace, region, database, branch } = await this.getParsedDatabaseURLWithBranch( - flags.db, - args.branch ?? 'main' - ); - - this.info(`Diff command is experimental, use with caution`); - - const localMigrationFiles = await getLocalMigrationFiles(); - const schemaOperations = compact(localMigrationFiles.flatMap((migrationFile) => migrationFile.operations)); - - const apiRequest = - args.branch && args.base - ? xata.api.migrations.compareBranchSchemas({ - pathParams: { workspace, region, dbBranchName: `${database}:${args.branch}`, branchName: args.base }, - body: {} - }) - : xata.api.migrations.compareBranchWithUserSchema({ - pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, - body: { schema: { tables: [] }, schemaOperations } - }); - - const { - edits: { operations } - } = await apiRequest; - - const diff = buildMigrationDiff(operations); - if (this.jsonEnabled()) return diff; - - if (operations.length === 0) { - this.log('No changes found'); - return; - } - - this.log(diff); - } -} diff --git a/cli/src/utils/diff.ts b/cli/src/utils/diff.ts deleted file mode 100644 index 118f35ded..000000000 --- a/cli/src/utils/diff.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Schemas } from '@xata.io/client'; -import chalk from 'chalk'; - -export function buildMigrationDiff(ops: Schemas.MigrationOp[]): string { - const lines = ops.map((op) => { - if ('addTable' in op) { - return `${chalk.green('+')} ${chalk.bold(op.addTable.table)}`; - } else if ('removeTable' in op) { - return `${chalk.red('-')} ${chalk.bold(op.removeTable.table)}`; - } else if ('renameTable' in op) { - return `${chalk.yellow('~')} ${chalk.bold(op.renameTable.oldName)} -> ${chalk.bold(op.renameTable.newName)}`; - } else if ('addColumn' in op) { - return `${chalk.green('+')} ${chalk.bold(op.addColumn.table)}.${chalk.bold(op.addColumn.column.name)}`; - } else if ('removeColumn' in op) { - return `${chalk.red('-')} ${chalk.bold(op.removeColumn.table)}.${chalk.bold(op.removeColumn.column)}`; - } else if ('renameColumn' in op) { - return `${chalk.yellow('~')} ${chalk.bold(op.renameColumn.table)}.${chalk.bold( - op.renameColumn.oldName - )} -> ${chalk.bold(op.renameColumn.newName)}`; - } else { - throw new Error(`Unknown migration op: ${JSON.stringify(op)}`); - } - }); - - return lines.join('\n'); -} diff --git a/packages/client/src/api/fetcher.ts b/packages/client/src/api/fetcher.ts index 6971e5c02..94ca7e7b6 100644 --- a/packages/client/src/api/fetcher.ts +++ b/packages/client/src/api/fetcher.ts @@ -203,6 +203,8 @@ export async function fetch< 'X-Xata-Client-ID': clientID ?? defaultClientID, 'X-Xata-Session-ID': sessionID ?? generateUUID(), 'X-Xata-Agent': xataAgent, + // Force field rename to xata_ internal properties + 'X-Features': compact(['feat-internal-field-rename-api=1', customHeaders?.['X-Features']]).join(' '), ...customHeaders, ...hostHeader(fullUrl), Authorization: `Bearer ${apiKey}` diff --git a/packages/client/src/schema/filters.test.ts b/packages/client/src/schema/filters.test.ts index 79725497c..c8273b372 100644 --- a/packages/client/src/schema/filters.test.ts +++ b/packages/client/src/schema/filters.test.ts @@ -5,6 +5,10 @@ import { XataRecord } from './record'; import { FilterExpression } from '../api/schemas'; type Record = XataRecord & { + xata_id: string; + xata_version: number; + xata_createdat: Date; + xata_updatedat: Date; name: string; string: string; number: number; @@ -230,7 +234,7 @@ const filterWithWildcardIsNotAllowed: Filter = { '*': { $is: 'foo' } }; const filterWithLinkWildcardIsNotAllowed: Filter = { 'owner.*': { $is: 'foo' } }; // Filter on internal column is allowed -const filterOnInternalColumnIsAllowed: Filter = { 'xata.version': { $is: 4 } }; +const filterOnInternalColumnIsAllowed: Filter = { xata_version: { $is: 4 } }; test('fake test', () => { // This is a fake test to make sure that the type definitions in this file are working diff --git a/packages/client/src/schema/filters.ts b/packages/client/src/schema/filters.ts index e5c65032a..e3272628b 100644 --- a/packages/client/src/schema/filters.ts +++ b/packages/client/src/schema/filters.ts @@ -2,7 +2,6 @@ import { FilterExpression, FilterPredicate } from '../api/schemas'; import { isDefined, isObject } from '../util/lang'; import { SingleOrArray, Values } from '../util/types'; import { JSONValue } from './json'; -import { XataRecordMetadata } from './record'; import { ColumnsByValue, ValueAtColumn } from './selection'; export type JSONFilterColumns = Values<{ @@ -13,7 +12,7 @@ export type JSONFilterColumns = Values<{ : never; }>; -export type FilterColumns = ColumnsByValue | `xata.${keyof XataRecordMetadata}`; +export type FilterColumns = ColumnsByValue; export type FilterValueAtColumn = NonNullable> extends JSONValue ? PropertyFilter diff --git a/packages/client/src/schema/index.test.ts b/packages/client/src/schema/index.test.ts index f62a8c123..4741adc7e 100644 --- a/packages/client/src/schema/index.test.ts +++ b/packages/client/src/schema/index.test.ts @@ -4,7 +4,7 @@ import { server } from '../../../../test/mock_server'; import { Response } from '../util/fetch'; interface User { - id: string; + xata_id: string; name: string; } @@ -322,14 +322,14 @@ describe('query', () => { test('returns a single object', async () => { const { fetch, users } = buildClient(); - const resultBody = { records: [{ id: '1234' }], meta: { page: { cursor: '', more: false } } }; + const resultBody = { records: [{ xata_id: '1234' }], meta: { page: { cursor: '', more: false } } }; const expected = { method: 'POST', path: '/tables/users/query', body: { page: { size: 1 } } }; const result = await expectRequest( fetch, expected, async () => { const first = await users.getFirst(); - expect(first?.id).toBe(resultBody.records[0].id); + expect(first?.xata_id).toBe(resultBody.records[0].xata_id); }, resultBody ); @@ -414,19 +414,19 @@ describe('Repository.update', () => { test('updates an object successfully', async () => { const { fetch, users } = buildClient(); - const object = { id: 'rec_1234', xata: { version: 1 }, name: 'Ada' }; + const object = { xata_id: 'rec_1234', xata_version: 1, name: 'Ada' }; const expected = [ - { method: 'PUT', path: `/tables/users/data/${object.id}`, body: object }, - { method: 'GET', path: `/tables/users/data/${object.id}` } + { method: 'PUT', path: `/tables/users/data/${object.xata_id}`, body: object }, + { method: 'GET', path: `/tables/users/data/${object.xata_id}` } ]; const result = await expectRequest( fetch, expected, async () => { - const result = await users.update(object.id, object); - expect(result?.id).toBe(object.id); + const result = await users.update(object.xata_id, object); + expect(result?.xata_id).toBe(object.xata_id); }, - { id: object.id } + { xata_id: object.xata_id } ); expect(result).toMatchInlineSnapshot(` @@ -467,7 +467,7 @@ describe('create', () => { test('successful', async () => { const { fetch, users } = buildClient(); - const created = { id: 'rec_1234', _version: 0 }; + const created = { xata_id: 'rec_1234', _version: 0 }; const object = { name: 'Ada' } as User; const expected = [ { method: 'POST', path: '/tables/users/data', body: object }, @@ -483,7 +483,7 @@ describe('create', () => { expected, async () => { const result = await users.create(object); - expect(result.id).toBe(created.id); + expect(result.xata_id).toBe(created.xata_id); }, created ); diff --git a/packages/client/src/schema/index.ts b/packages/client/src/schema/index.ts index 49a3ccdcf..b63fe4d5b 100644 --- a/packages/client/src/schema/index.ts +++ b/packages/client/src/schema/index.ts @@ -10,7 +10,7 @@ export * from './inference'; export * from './operators'; export * from './pagination'; export { Query } from './query'; -export { RecordColumnTypes, isIdentifiable, isXataRecord } from './record'; +export { RecordColumnTypes, isIdentifiable } from './record'; export type { BaseData, EditableData, Identifiable, JSONData, Link, XataRecord } from './record'; export { Repository, RestRepository } from './repository'; export * from './selection'; diff --git a/packages/client/src/schema/inference.spec.ts b/packages/client/src/schema/inference.spec.ts index 438c1752a..1aa717e2a 100644 --- a/packages/client/src/schema/inference.spec.ts +++ b/packages/client/src/schema/inference.spec.ts @@ -8,6 +8,10 @@ const tables = [ { name: 'teams', columns: [ + { name: 'xata_id', type: 'string' }, + { name: 'xata_version', type: 'int' }, + { name: 'xata_createdat', type: 'datetime' }, + { name: 'xata_updatedat', type: 'datetime' }, { name: 'name', type: 'string' }, { name: 'labels', type: 'multiple' }, { name: 'owner', type: 'link', link: { table: 'users' } } @@ -16,6 +20,10 @@ const tables = [ { name: 'users', columns: [ + { name: 'xata_id', type: 'string' }, + { name: 'xata_version', type: 'int' }, + { name: 'xata_createdat', type: 'datetime' }, + { name: 'xata_updatedat', type: 'datetime' }, { name: 'email', type: 'email' }, { name: 'full_name', type: 'string', notNull: true, defaultValue: 'John Doe' }, { name: 'team', type: 'link', link: { table: 'teams' } }, @@ -24,17 +32,9 @@ const tables = [ } ] as const; -function simpleTeam(team: SchemaInference['teams'] & XataRecord) { - team.getMetadata(); - team.owner?.getMetadata(); -} - function simpleUser(user: SchemaInference['users'] & XataRecord) { user.full_name.startsWith('a'); - user.getMetadata(); - user.team?.getMetadata(); - user.json?.foo; user.json?.[0]; } diff --git a/packages/client/src/schema/query.ts b/packages/client/src/schema/query.ts index deb416041..b29c8e9b7 100644 --- a/packages/client/src/schema/query.ts +++ b/packages/client/src/schema/query.ts @@ -201,8 +201,8 @@ export class Query = XataRecord> extends Identifiable { - /** - * Metadata of this record. - */ - xata: XataRecordMetadata; - - /** - * Get metadata of this record. - * @deprecated Use `xata` property instead. - */ - getMetadata(): XataRecordMetadata; - /** * Get an object representation of this record. */ @@ -142,30 +131,8 @@ export interface XataRecord = XataRecord< export type Link = XataRecord; -export type XataRecordMetadata = { - /** - * Number that is increased every time the record is updated. - */ - version: number; - /** - * Timestamp when the record was created. - */ - createdAt: Date; - /** - * Timestamp when the record was last updated. - */ - updatedAt: Date; -}; - export function isIdentifiable(x: any): x is Identifiable & Record { - return isObject(x) && isString((x as Partial)?.id); -} - -export function isXataRecord(x: any): x is XataRecord & Record { - const record = x as XataRecord & Record; - const metadata = record?.getMetadata(); - - return isIdentifiable(x) && isObject(metadata) && typeof metadata.version === 'number'; + return isObject(x) && isString(x?.xata_id); } type NumericOperator = ExclusiveOr< @@ -176,9 +143,9 @@ type NumericOperator = ExclusiveOr< export type InputXataFile = Partial | Promise>; type EditableDataFields = T extends XataRecord - ? { id: Identifier } | Identifier + ? { xata_id: Identifier } | Identifier : NonNullable extends XataRecord - ? { id: Identifier } | Identifier | null | undefined + ? { xata_id: Identifier } | Identifier | null | undefined : T extends Date ? string | Date : NonNullable extends Date @@ -205,7 +172,9 @@ type JSONDataFile = { [K in keyof XataFile]: XataFile[K] extends Function ? never : XataFile[K]; }; -type JSONDataFields = T extends XataFile +type JSONDataFields = T extends null | undefined | void + ? null | undefined + : T extends XataFile ? JSONDataFile : NonNullable extends XataFile ? JSONDataFile | null | undefined @@ -221,22 +190,17 @@ type JSONDataFields = T extends XataFile type JSONDataBase = Identifiable & { /** - * Metadata about the record. + * Timestamp when the record was created. + */ + xata_createdat: string; + /** + * Timestamp when the record was last updated. + */ + xata_updatedat: string; + /** + * Number that is increased every time the record is updated. */ - xata: { - /** - * Timestamp when the record was created. - */ - createdAt: string; - /** - * Timestamp when the record was last updated. - */ - updatedAt: string; - /** - * Number that is increased every time the record is updated. - */ - version: number; - }; + xata_version: number; }; export type JSONData = JSONDataBase & diff --git a/packages/client/src/schema/repository.ts b/packages/client/src/schema/repository.ts index fb3d6fe59..8fb96fc0a 100644 --- a/packages/client/src/schema/repository.ts +++ b/packages/client/src/schema/repository.ts @@ -22,7 +22,6 @@ import { FuzzinessExpression, HighlightExpression, PrefixExpression, - RecordsMetadata, SearchPageConfig, TransactionOperation } from '../api/schemas'; @@ -69,7 +68,7 @@ export abstract class Repository extends Query< * @returns The full persisted record. */ abstract create>( - object: Omit, 'id'> & Partial, + object: Omit, 'xata_id'> & Partial, columns: K[], options?: { ifVersion?: number } ): Promise>>; @@ -80,7 +79,7 @@ export abstract class Repository extends Query< * @returns The full persisted record. */ abstract create( - object: Omit, 'id'> & Partial, + object: Omit, 'xata_id'> & Partial, options?: { ifVersion?: number } ): Promise>>; @@ -93,7 +92,7 @@ export abstract class Repository extends Query< */ abstract create>( id: Identifier, - object: Omit, 'id'>, + object: Omit, 'xata_id'>, columns: K[], options?: { ifVersion?: number } ): Promise>>; @@ -106,7 +105,7 @@ export abstract class Repository extends Query< */ abstract create( id: Identifier, - object: Omit, 'id'>, + object: Omit, 'xata_id'>, options?: { ifVersion?: number } ): Promise>>; @@ -117,7 +116,7 @@ export abstract class Repository extends Query< * @returns Array of the persisted records in order. */ abstract create>( - objects: Array, 'id'> & Partial>, + objects: Array, 'xata_id'> & Partial>, columns: K[] ): Promise>[]>; @@ -127,7 +126,7 @@ export abstract class Repository extends Query< * @returns Array of the persisted records in order. */ abstract create( - objects: Array, 'id'> & Partial> + objects: Array, 'xata_id'> & Partial> ): Promise>[]>; /** @@ -432,7 +431,7 @@ export abstract class Repository extends Query< * @returns The full persisted record. */ abstract createOrUpdate>( - object: Omit, 'id'> & Partial, + object: Omit, 'xata_id'> & Partial, columns: K[], options?: { ifVersion?: number } ): Promise>>; @@ -444,7 +443,7 @@ export abstract class Repository extends Query< * @returns The full persisted record. */ abstract createOrUpdate( - object: Omit, 'id'> & Partial, + object: Omit, 'xata_id'> & Partial, options?: { ifVersion?: number } ): Promise>>; @@ -458,7 +457,7 @@ export abstract class Repository extends Query< */ abstract createOrUpdate>( id: Identifier | undefined, - object: Omit, 'id'>, + object: Omit, 'xata_id'>, columns: K[], options?: { ifVersion?: number } ): Promise>>; @@ -472,7 +471,7 @@ export abstract class Repository extends Query< */ abstract createOrUpdate( id: Identifier | undefined, - object: Omit, 'id'>, + object: Omit, 'xata_id'>, options?: { ifVersion?: number } ): Promise>>; @@ -484,7 +483,7 @@ export abstract class Repository extends Query< * @returns Array of the persisted records. */ abstract createOrUpdate>( - objects: Array, 'id'> & Partial>, + objects: Array, 'xata_id'> & Partial>, columns: K[] ): Promise>[]>; @@ -495,7 +494,7 @@ export abstract class Repository extends Query< * @returns Array of the persisted records. */ abstract createOrUpdate( - objects: Array, 'id'> & Partial> + objects: Array, 'xata_id'> & Partial> ): Promise>[]>; /** @@ -506,7 +505,7 @@ export abstract class Repository extends Query< * @returns The full persisted record. */ abstract createOrReplace>( - object: Omit, 'id'> & Partial, + object: Omit, 'xata_id'> & Partial, columns: K[], options?: { ifVersion?: number } ): Promise>>; @@ -518,7 +517,7 @@ export abstract class Repository extends Query< * @returns The full persisted record. */ abstract createOrReplace( - object: Omit, 'id'> & Partial, + object: Omit, 'xata_id'> & Partial, options?: { ifVersion?: number } ): Promise>>; @@ -532,7 +531,7 @@ export abstract class Repository extends Query< */ abstract createOrReplace>( id: Identifier | undefined, - object: Omit, 'id'>, + object: Omit, 'xata_id'>, columns: K[], options?: { ifVersion?: number } ): Promise>>; @@ -546,7 +545,7 @@ export abstract class Repository extends Query< */ abstract createOrReplace( id: Identifier | undefined, - object: Omit, 'id'>, + object: Omit, 'xata_id'>, options?: { ifVersion?: number } ): Promise>>; @@ -558,7 +557,7 @@ export abstract class Repository extends Query< * @returns Array of the persisted records. */ abstract createOrReplace>( - objects: Array, 'id'> & Partial>, + objects: Array, 'xata_id'> & Partial>, columns: K[] ): Promise>[]>; @@ -569,7 +568,7 @@ export abstract class Repository extends Query< * @returns Array of the persisted records. */ abstract createOrReplace( - objects: Array, 'id'> & Partial> + objects: Array, 'xata_id'> & Partial> ): Promise>[]>; /** @@ -915,11 +914,14 @@ export class RestRepository } // Create one record with id as property - if (isObject(a) && isString(a.id)) { - if (a.id === '') throw new Error("The id can't be empty"); + if (isObject(a) && isString(a.xata_id)) { + if (a.xata_id === '') throw new Error("The id can't be empty"); const columns = isValidSelectableColumns(b) ? b : undefined; - return await this.#insertRecordWithId(a.id, { ...a, id: undefined }, columns, { createOnly: true, ifVersion }); + return await this.#insertRecordWithId(a.xata_id, { ...a, xata_id: undefined }, columns, { + createOnly: true, + ifVersion + }); } // Create one record without id @@ -1053,11 +1055,11 @@ export class RestRepository const ids = a.map((item) => extractId(item)); - const finalObjects = await this.getAll({ filter: { id: { $any: compact(ids) } }, columns }); + const finalObjects = await this.getAll({ filter: { xata_id: { $any: compact(ids) } }, columns }); // Maintain order of objects const dictionary = finalObjects.reduce((acc, object) => { - acc[object.id] = object; + acc[object.xata_id] = object; return acc; }, {} as Dictionary); @@ -1206,7 +1208,7 @@ export class RestRepository if (a.length === 0) return []; // TODO: Transaction API fails fast if one of the records is not found - const existing = await this.read(a, ['id']); + const existing = await this.read(a, ['xata_id'] as SelectableColumn[]); const updates = a.filter((_item, index) => existing[index] !== null); await this.#updateRecords(updates as Array> & Identifiable>, { @@ -1229,9 +1231,9 @@ export class RestRepository } // Update one record with id as property - if (isObject(a) && isString(a.id)) { + if (isObject(a) && isString(a.xata_id)) { const columns = isValidSelectableColumns(b) ? b : undefined; - return await this.#updateRecordWithID(a.id, { ...a, id: undefined }, columns, { ifVersion }); + return await this.#updateRecordWithID(a.xata_id, { ...a, xata_id: undefined }, columns, { ifVersion }); } } catch (error: any) { if (error.status === 422) return null; @@ -1318,7 +1320,7 @@ export class RestRepository if (!recordId) return null; // Ensure id is not present in the update payload - const { id: _id, ...record } = await this.#transformObjectToApi(object); + const { xata_id: _id, ...record } = await this.#transformObjectToApi(object); try { const response = await updateRecordWithID({ @@ -1349,9 +1351,9 @@ export class RestRepository objects: Array> & Identifiable>, { ifVersion, upsert }: { ifVersion?: number; upsert: boolean } ) { - const operations = await promiseMap(objects, async ({ id, ...object }) => { + const operations = await promiseMap(objects, async ({ xata_id, ...object }) => { const fields = await this.#transformObjectToApi(object); - return { update: { table: this.#table, id, ifVersion, upsert, fields } }; + return { update: { table: this.#table, id: xata_id, ifVersion, upsert, fields } }; }); const chunkedOperations: TransactionOperation[][] = chunk(operations, BULK_OPERATION_MAX_SIZE); @@ -1392,13 +1394,13 @@ export class RestRepository ): Promise>>; async createOrUpdate>( id: Identifier, - object: Omit, 'id'>, + object: Omit, 'xata_id'>, columns: K[], options?: { ifVersion?: number } ): Promise>>; async createOrUpdate( id: Identifier, - object: Omit, 'id'>, + object: Omit, 'xata_id'>, options?: { ifVersion?: number } ): Promise>>; async createOrUpdate>( @@ -1410,7 +1412,7 @@ export class RestRepository ): Promise>[]>; async createOrUpdate>( a: Identifier | EditableData | EditableData[], - b?: EditableData | Omit, 'id'> | K[] | { ifVersion?: number }, + b?: EditableData | Omit, 'xata_id'> | K[] | { ifVersion?: number }, c?: K[] | { ifVersion?: number }, d?: { ifVersion?: number } ): Promise< @@ -1434,7 +1436,7 @@ export class RestRepository const columns = isValidSelectableColumns(b) ? b : (['*'] as K[]); // TODO: Transaction API does not support column projection - const result = await this.read(a, columns); + const result = await this.read(a as any[], columns); return result; } @@ -1447,11 +1449,11 @@ export class RestRepository } // Create or update one record with id as property - if (isObject(a) && isString(a.id)) { - if (a.id === '') throw new Error("The id can't be empty"); + if (isObject(a) && isString(a.xata_id)) { + if (a.xata_id === '') throw new Error("The id can't be empty"); const columns = isValidSelectableColumns(c) ? c : undefined; - return await this.#upsertRecordWithID(a.id, { ...a, id: undefined }, columns, { ifVersion }); + return await this.#upsertRecordWithID(a.xata_id, { ...a, xata_id: undefined }, columns, { ifVersion }); } // Create with undefined id as param @@ -1460,7 +1462,7 @@ export class RestRepository } // Create with undefined id as property - if (isObject(a) && !isDefined(a.id)) { + if (isObject(a) && !isDefined(a.xata_id)) { return await this.create(a as EditableData, b as K[]); } @@ -1470,7 +1472,7 @@ export class RestRepository async #upsertRecordWithID( recordId: Identifier, - object: Omit, 'id'>, + object: Omit, 'xata_id'>, columns: SelectableColumn[] = ['*'], { ifVersion }: { ifVersion?: number } ) { @@ -1504,13 +1506,13 @@ export class RestRepository ): Promise>>; async createOrReplace>( id: Identifier | undefined, - object: Omit, 'id'>, + object: Omit, 'xata_id'>, columns: K[], options?: { ifVersion?: number } ): Promise>>; async createOrReplace( id: Identifier | undefined, - object: Omit, 'id'>, + object: Omit, 'xata_id'>, options?: { ifVersion?: number } ): Promise>>; async createOrReplace>( @@ -1522,7 +1524,7 @@ export class RestRepository ): Promise>[]>; async createOrReplace>( a: Identifier | EditableData | EditableData[] | undefined, - b?: EditableData | Omit, 'id'> | K[] | { ifVersion?: number }, + b?: EditableData | Omit, 'xata_id'> | K[] | { ifVersion?: number }, c?: K[] | { ifVersion?: number }, d?: { ifVersion?: number } ): Promise< @@ -1556,11 +1558,14 @@ export class RestRepository } // Create or replace one record with id as property - if (isObject(a) && isString(a.id)) { - if (a.id === '') throw new Error("The id can't be empty"); + if (isObject(a) && isString(a.xata_id)) { + if (a.xata_id === '') throw new Error("The id can't be empty"); const columns = isValidSelectableColumns(c) ? c : undefined; - return await this.#insertRecordWithId(a.id, { ...a, id: undefined }, columns, { createOnly: false, ifVersion }); + return await this.#insertRecordWithId(a.xata_id, { ...a, xata_id: undefined }, columns, { + createOnly: false, + ifVersion + }); } // Create with undefined id as param @@ -1569,7 +1574,7 @@ export class RestRepository } // Create with undefined id as property - if (isObject(a) && !isDefined(a.id)) { + if (isObject(a) && !isDefined(a.xata_id)) { return await this.create(a as EditableData, b as K[]); } @@ -1616,7 +1621,7 @@ export class RestRepository const ids = a.map((o) => { if (isString(o)) return o; - if (isString(o.id)) return o.id; + if (isString(o.xata_id)) return o.xata_id; throw new Error('Invalid arguments for delete method'); }); @@ -1636,8 +1641,8 @@ export class RestRepository } // Delete one record with id as property - if (isObject(a) && isString(a.id)) { - return this.#deleteRecord(a.id, b); + if (isObject(a) && isString(a.xata_id)) { + return this.#deleteRecord(a.xata_id, b); } throw new Error('Invalid arguments for delete method'); @@ -1977,13 +1982,13 @@ export class RestRepository for (const [key, value] of Object.entries(object)) { // Ignore internal properties - if (key === 'xata') continue; + if (['xata_version', 'xata_createdat', 'xata_updatedat'].includes(key)) continue; const type = schema.columns.find((column) => column.name === key)?.type; switch (type) { case 'link': { - result[key] = isIdentifiable(value) ? value.id : value; + result[key] = isIdentifiable(value) ? value.xata_id : value; break; } case 'datetime': { @@ -2016,8 +2021,7 @@ export const initObject = ( selectedColumns: SelectableColumn[] | SelectableColumnWithObjectNotation[] ) => { const data: Dictionary = {}; - const { xata, ...rest } = object ?? {}; - Object.assign(data, rest); + Object.assign(data, { ...object }); const { columns } = schemaTables.find(({ name }) => name === table) ?? {}; if (!columns) console.error(`Table ${table} not found in schema`); @@ -2092,39 +2096,27 @@ export const initObject = ( } const record = { ...data }; - const metadata = - xata !== undefined - ? { ...xata, createdAt: new Date(xata.createdAt), updatedAt: new Date(xata.updatedAt) } - : undefined; record.read = function (columns?: any) { - return db[table].read(record['id'] as string, columns); + return db[table].read(record['xata_id'] as string, columns); }; record.update = function (data: any, b?: any, c?: any) { const columns = isValidSelectableColumns(b) ? b : ['*']; const ifVersion = parseIfVersion(b, c); - return db[table].update(record['id'] as string, data, columns, { ifVersion }); + return db[table].update(record['xata_id'] as string, data, columns, { ifVersion }); }; record.replace = function (data: any, b?: any, c?: any) { const columns = isValidSelectableColumns(b) ? b : ['*']; const ifVersion = parseIfVersion(b, c); - return db[table].createOrReplace(record['id'] as string, data, columns, { ifVersion }); + return db[table].createOrReplace(record['xata_id'] as string, data, columns, { ifVersion }); }; record.delete = function () { - return db[table].delete(record['id'] as string); - }; - - if (metadata !== undefined) { - record.xata = Object.freeze(metadata); - } - - record.getMetadata = function () { - return record.xata; + return db[table].delete(record['xata_id'] as string); }; record.toSerializable = function () { @@ -2135,7 +2127,7 @@ export const initObject = ( return JSON.stringify(record); }; - for (const prop of ['read', 'update', 'replace', 'delete', 'getMetadata', 'toSerializable', 'toString']) { + for (const prop of ['read', 'update', 'replace', 'delete', 'toSerializable', 'toString']) { Object.defineProperty(record, prop, { enumerable: false }); } @@ -2146,7 +2138,7 @@ export const initObject = ( function extractId(value: any): Identifier | undefined { if (isString(value)) return value; - if (isObject(value) && isString(value.id)) return value.id; + if (isObject(value) && isString(value.xata_id)) return value.xata_id; return undefined; } diff --git a/packages/client/src/schema/selection.spec.ts b/packages/client/src/schema/selection.spec.ts index f3db5b729..1124362c0 100644 --- a/packages/client/src/schema/selection.spec.ts +++ b/packages/client/src/schema/selection.spec.ts @@ -6,6 +6,10 @@ import { SelectableColumn, SelectedPick, ValueAtColumn } from './selection'; import { XataFile } from './files'; interface Team { + xata_id: string; + xata_version: number; + xata_createdat: Date; + xata_updatedat: Date; name: string; labels?: string[] | null; owner?: UserRecord | null; @@ -14,6 +18,10 @@ interface Team { type TeamRecord = Team & XataRecord; interface User { + xata_id: string; + xata_version: number; + xata_createdat: Date; + xata_updatedat: Date; email?: string | null; full_name: string; team?: TeamRecord | null; @@ -27,7 +35,7 @@ type UserRecord = User & XataRecord; // SelectableColumn // // --------------------------------------------------------------------------- // -const validTeamColumns: SelectableColumn[] = ['*', 'id', 'name', 'owner.*', 'owner.date']; +const validTeamColumns: SelectableColumn[] = ['*', 'xata_id', 'name', 'owner.*', 'owner.date']; // @ts-expect-error const invalidFullNameTeamColumn: SelectableColumn = 'full_name'; @@ -41,12 +49,12 @@ const invalidReadTeamColumn: SelectableColumn = 'owner.read.*'; const invalidInternalDateColumns: SelectableColumn = 'owner.date.getFullYear'; // Internal columns -const internalVersionColumns: SelectableColumn = 'xata.version'; -const internalCreatedAtColumns: SelectableColumn = 'xata.createdAt'; -const internalUpdatedAtColumns: SelectableColumn = 'xata.updatedAt'; -const linkVersionColumns: SelectableColumn = 'owner.xata.version'; -const linkCreatedAtColumns: SelectableColumn = 'owner.xata.createdAt'; -const linkUpdatedAtColumns: SelectableColumn = 'owner.xata.updatedAt'; +const internalVersionColumns: SelectableColumn = 'xata_version'; +const internalCreatedAtColumns: SelectableColumn = 'xata_createdat'; +const internalUpdatedAtColumns: SelectableColumn = 'xata_updatedat'; +const linkVersionColumns: SelectableColumn = 'owner.xata_version'; +const linkCreatedAtColumns: SelectableColumn = 'owner.xata_createdat'; +const linkUpdatedAtColumns: SelectableColumn = 'owner.xata_updatedat'; // ValueAtColumn // // --------------------------------------------------------------------------- // @@ -59,33 +67,22 @@ const invalidLabelsValue: ValueAtColumn = [1]; // ---------------------------------------------------------------------------- // function test1(user: SelectedPick) { - user.id; + user.xata_id; user.read(); user.full_name; - user.xata.version; - user.xata.createdAt; - user.xata.updatedAt; + user.xata_version; + user.xata_createdat; + user.xata_updatedat; // @ts-expect-error - user.team.id; - user.team?.id; + user.team.xata_id; + user.team?.xata_id; user.team?.read(); // @ts-expect-error user.team?.name; - // TODO(link.xata) @ts-expect-error - user.team?.xata.version; - // TODO(link.xata) @ts-expect-error - user.team?.xata.createdAt; - // TODO(link.xata) @ts-expect-error - user.team?.xata.updatedAt; - - user.team?.xata?.version; - user.team?.xata?.createdAt; - user.team?.xata?.updatedAt; - - user.partner.id; + user.partner.xata_id; user.partner.read(); // @ts-expect-error user.partner.full_name; @@ -96,14 +93,14 @@ function test1(user: SelectedPick) { } function test2(user: SelectedPick) { - user.id; + user.xata_id; user.read(); user.full_name; - user.team?.id; + user.team?.xata_id; user.team?.read(); user.team?.name; user.team?.owner; - user.team?.owner?.id; + user.team?.owner?.xata_id; user.team?.owner?.read(); // @ts-expect-error user.team?.owner?.full_name; @@ -125,29 +122,29 @@ function test2(user: SelectedPick) { } function test3(user: SelectedPick) { - user.id; + user.xata_id; user.read(); // @ts-expect-error user.full_name; - user.team?.id; + user.team?.xata_id; user.team?.read(); // @ts-expect-error user.team?.name; - user.team?.owner?.id; + user.team?.owner?.xata_id; user.team?.owner?.read(); user.team?.owner?.full_name; } function test4(user: SelectedPick) { user.partner; - user.partner.id; + user.partner.xata_id; user.partner.read(); user.partner.full_name; // @ts-expect-error user.partner.full_name = null; // @ts-expect-error - user.team.id; - user.team?.id; + user.team.xata_id; + user.team?.xata_id; // @ts-expect-error user.team.read(); user.team?.read(); @@ -159,14 +156,14 @@ function test4(user: SelectedPick) { function test5(user: SelectedPick) { user.partner; - user.partner.id; + user.partner.xata_id; user.partner.read(); user.partner.full_name; // @ts-expect-error user.partner.full_name = null; // @ts-expect-error - user.team.id; - user.team?.id; + user.team.xata_id; + user.team?.xata_id; // @ts-expect-error user.team.read(); user.team?.read(); diff --git a/packages/client/src/schema/selection.ts b/packages/client/src/schema/selection.ts index f0d0afc6d..7e3026cbd 100644 --- a/packages/client/src/schema/selection.ts +++ b/packages/client/src/schema/selection.ts @@ -7,10 +7,6 @@ import { Link, XataRecord } from './record'; export type SelectableColumn = // Alias for any property | '*' - // Alias for id (not in schema) - | 'id' - // Internal properties - | `xata.${'version' | 'createdAt' | 'updatedAt'}` // Properties of the current level | DataProps // Nested properties of the lower levels @@ -99,14 +95,6 @@ export type ValueAtColumn = Recur ? never : Key extends '*' ? Values // Alias for any property - : Key extends 'id' - ? string // Alias for id (not in schema) - : Key extends 'xata.version' - ? number - : Key extends 'xata.createdAt' - ? Date - : Key extends 'xata.updatedAt' - ? Date : Key extends keyof Object ? Object[Key] // Properties of the current level : Key extends `${infer K}.${infer V}` @@ -163,7 +151,7 @@ type NestedColumns = RecursivePath['length'] ext >; // Private: Utility type to get object properties without XataRecord ones -type DataProps = Exclude, StringKeys>; +type DataProps = Exclude, StringKeys>>; // Private: Utility type to get the value of a column at a given path (nested object value) // For "foo.bar.baz" we return { foo: { bar: { baz: type } } } @@ -193,7 +181,7 @@ type NestedValueAtColumn> = ? // If the property is a link, we forward the type of the internal XataRecord // Since it can be nullable, we use ForwardNullable to avoid loosing the internal type // Links that are not expanded ["link"] instead of ["link.*"] don't have the xata property - ForwardNullable, ['*']>, 'xata' | 'getMetadata'>> + ForwardNullable, ['*']>> : O[K]; } : Key extends '*' diff --git a/packages/client/src/schema/sorting.spec.ts b/packages/client/src/schema/sorting.spec.ts index 14db7fbab..2363c43b0 100644 --- a/packages/client/src/schema/sorting.spec.ts +++ b/packages/client/src/schema/sorting.spec.ts @@ -4,6 +4,10 @@ import { XataRecord } from './record'; import { ApiSortFilter } from './sorting'; type Record = XataRecord & { + xata_id: string; + xata_version: number; + xata_createdat: Date; + xata_updatedat: Date; name: string; string: string; number: number; @@ -31,10 +35,10 @@ const sortWithRandomWildcard: ApiSortFilter = { '*': 'random' }; const sortWithRandomWildcardOnColumn: ApiSortFilter = { name: 'random' }; // Sort by updatedAt is allowed -const sortWithUpdatedAt: ApiSortFilter = { 'xata.updatedAt': 'asc' }; +const sortWithUpdatedAt: ApiSortFilter = { xata_updatedat: 'asc' }; // Sort by createdAt is allowed -const sortWithCreatedAt: ApiSortFilter = { 'xata.createdAt': 'asc' }; +const sortWithCreatedAt: ApiSortFilter = { xata_createdat: 'asc' }; // Sort by unknown metadata is not allowed //@ts-expect-error diff --git a/packages/client/src/schema/sorting.ts b/packages/client/src/schema/sorting.ts index e53f8579a..6064f032a 100644 --- a/packages/client/src/schema/sorting.ts +++ b/packages/client/src/schema/sorting.ts @@ -1,6 +1,6 @@ import { isObject, isString } from '../util/lang'; import { SingleOrArray, Values } from '../util/types'; -import { XataRecord, XataRecordMetadata } from './record'; +import { XataRecord } from './record'; import { ColumnsByValue } from './selection'; export type SortDirection = 'asc' | 'desc'; @@ -8,7 +8,7 @@ export type SortDirection = 'asc' | 'desc'; type RandomFilter = { '*': 'random' }; type RandomFilterExtended = { column: '*'; direction: 'random' }; -export type SortColumns = ColumnsByValue | `xata.${keyof XataRecordMetadata}`; +export type SortColumns = ColumnsByValue; export type SortFilterExtended> = | RandomFilterExtended diff --git a/packages/client/src/search/boosters.spec.ts b/packages/client/src/search/boosters.spec.ts index ab7299ee0..f02b53018 100644 --- a/packages/client/src/search/boosters.spec.ts +++ b/packages/client/src/search/boosters.spec.ts @@ -55,7 +55,7 @@ const invalidBoosters1: Boosters[] = [ { numericBooster: { column: 'name', factor: 50, modifier: 'invalid' } }, { // @ts-expect-error - dateBooster: { column: 'createdAt', origin: '2020-01-21T00:00:00Z', scale: '1d', decay: 0.2 }, + dateBooster: { column: 'invalid', origin: '2020-01-21T00:00:00Z', scale: '1d', decay: 0.2 }, ifMatchesFilter: { noSuchColumn: 'test' } } ]; diff --git a/packages/client/src/search/index.ts b/packages/client/src/search/index.ts index 82371e1ce..2345fe993 100644 --- a/packages/client/src/search/index.ts +++ b/packages/client/src/search/index.ts @@ -3,7 +3,7 @@ import { FuzzinessExpression, HighlightExpression, PrefixExpression, SearchPageC import { XataPlugin, XataPluginOptions } from '../plugins'; import { SchemaPluginResult } from '../schema'; import { Filter } from '../schema/filters'; -import { BaseData, XataRecord, XataRecordMetadata } from '../schema/record'; +import { BaseData, XataRecord } from '../schema/record'; import { initObject } from '../schema/repository'; import { SelectedPick } from '../schema/selection'; import { GetArrayInnerType, StringKeys, Values } from '../util/types'; @@ -77,7 +77,8 @@ export class SearchPlugin> extends Xa return { totalCount, records: records.map((record) => { - const { table = 'orphan' } = record.xata; + const table = record.xata_table; + // TODO: Search endpoint doesn't support column selection return { table, record: initObject(this.db, pluginOptions.tables, table, record, ['*']) } as any; }) @@ -90,7 +91,7 @@ export class SearchPlugin> extends Xa const { records: rawRecords, totalCount } = await this.#search(query, options, pluginOptions); const records = rawRecords.reduce((acc, record) => { - const { table = 'orphan' } = record.xata; + const table = record.xata_table; const items = acc[table] ?? []; // TODO: Search endpoint doesn't support column selection @@ -121,20 +122,17 @@ export class SearchPlugin> extends Xa } } -export type SearchXataRecord = Omit & { - xata: XataRecordMetadata & SearchExtraProperties; - getMetadata: () => XataRecordMetadata & SearchExtraProperties; -}; +export type SearchXataRecord = Record & SearchExtraProperties; type SearchExtraProperties = { /* * The record's table name. APIs that return records from multiple tables will set this field accordingly. */ - table: string; + xata_table: string; /* * Highlights of the record. This is used by the search APIs to indicate which fields and parts of the fields have matched the search. */ - highlight?: { + xata_highlight?: { [key: string]: | string[] | { @@ -144,7 +142,7 @@ type SearchExtraProperties = { /* * The record's relevancy score. This is returned by the search APIs. */ - score?: number; + xata_score?: number; }; type ReturnTable = Table extends Tables ? Table : never; diff --git a/packages/codegen/example/schema.json b/packages/codegen/example/schema.json index 47e78643b..f09b9b235 100644 --- a/packages/codegen/example/schema.json +++ b/packages/codegen/example/schema.json @@ -3,6 +3,26 @@ { "name": "teams", "columns": [ + { + "name": "xata_id", + "type": "string", + "notNull": true + }, + { + "name": "xata_version", + "type": "int", + "notNull": true + }, + { + "name": "xata_createdat", + "type": "datetime", + "notNull": true + }, + { + "name": "xata_updatedat", + "type": "datetime", + "notNull": true + }, { "name": "name", "type": "string" @@ -61,6 +81,26 @@ { "name": "users", "columns": [ + { + "name": "xata_id", + "type": "string", + "notNull": true + }, + { + "name": "xata_version", + "type": "int", + "notNull": true + }, + { + "name": "xata_createdat", + "type": "datetime", + "notNull": true + }, + { + "name": "xata_updatedat", + "type": "datetime", + "notNull": true + }, { "name": "email", "type": "email", @@ -151,6 +191,26 @@ { "name": "pets", "columns": [ + { + "name": "xata_id", + "type": "string", + "notNull": true + }, + { + "name": "xata_version", + "type": "int", + "notNull": true + }, + { + "name": "xata_createdat", + "type": "datetime", + "notNull": true + }, + { + "name": "xata_updatedat", + "type": "datetime", + "notNull": true + }, { "name": "name", "type": "string" diff --git a/packages/codegen/example/types.d.ts b/packages/codegen/example/types.d.ts index e994082df..600b19945 100644 --- a/packages/codegen/example/types.d.ts +++ b/packages/codegen/example/types.d.ts @@ -3,6 +3,26 @@ declare const tables: readonly [ { readonly name: 'teams'; readonly columns: readonly [ + { + readonly name: 'xata_id'; + readonly type: 'string'; + readonly notNull: true; + }, + { + readonly name: 'xata_version'; + readonly type: 'int'; + readonly notNull: true; + }, + { + readonly name: 'xata_createdat'; + readonly type: 'datetime'; + readonly notNull: true; + }, + { + readonly name: 'xata_updatedat'; + readonly type: 'datetime'; + readonly notNull: true; + }, { readonly name: 'name'; readonly type: 'string'; @@ -61,6 +81,26 @@ declare const tables: readonly [ { readonly name: 'users'; readonly columns: readonly [ + { + readonly name: 'xata_id'; + readonly type: 'string'; + readonly notNull: true; + }, + { + readonly name: 'xata_version'; + readonly type: 'int'; + readonly notNull: true; + }, + { + readonly name: 'xata_createdat'; + readonly type: 'datetime'; + readonly notNull: true; + }, + { + readonly name: 'xata_updatedat'; + readonly type: 'datetime'; + readonly notNull: true; + }, { readonly name: 'email'; readonly type: 'email'; @@ -73,6 +113,9 @@ declare const tables: readonly [ { readonly name: 'photo'; readonly type: 'file'; + readonly file: { + readonly defaultPublicAccess: true; + }; }, { readonly name: 'attachments'; @@ -148,6 +191,26 @@ declare const tables: readonly [ { readonly name: 'pets'; readonly columns: readonly [ + { + readonly name: 'xata_id'; + readonly type: 'string'; + readonly notNull: true; + }, + { + readonly name: 'xata_version'; + readonly type: 'int'; + readonly notNull: true; + }, + { + readonly name: 'xata_createdat'; + readonly type: 'datetime'; + readonly notNull: true; + }, + { + readonly name: 'xata_updatedat'; + readonly type: 'datetime'; + readonly notNull: true; + }, { readonly name: 'name'; readonly type: 'string'; diff --git a/packages/codegen/example/xata.cjs b/packages/codegen/example/xata.cjs index fe8c8c9da..e4556d88d 100644 --- a/packages/codegen/example/xata.cjs +++ b/packages/codegen/example/xata.cjs @@ -1,69 +1,81 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); exports.getXataClient = exports.XataClient = void 0; -// Generated by Xata Codegen 0.27.0. Please do not edit. -const client_1 = require('../../client/src'); +// Generated by Xata Codegen 0.29.1. Please do not edit. +const client_1 = require("../../client/src"); /** @typedef { import('./types').SchemaTables } SchemaTables */ /** @type { SchemaTables } */ const tables = [ { - name: 'teams', + name: "teams", columns: [ - { name: 'name', type: 'string' }, - { name: 'description', type: 'text' }, - { name: 'labels', type: 'multiple' }, - { name: 'index', type: 'int' }, - { name: 'rating', type: 'float' }, - { name: 'founded_date', type: 'datetime' }, - { name: 'email', type: 'email' }, - { name: 'plan', type: 'string' }, - { name: 'dark', type: 'bool' }, - { name: 'config', type: 'json' }, - { name: 'owner', type: 'link', link: { table: 'users' } } + { name: "xata_id", type: "string", notNull: true }, + { name: "xata_version", type: "int", notNull: true }, + { name: "xata_createdat", type: "datetime", notNull: true }, + { name: "xata_updatedat", type: "datetime", notNull: true }, + { name: "name", type: "string" }, + { name: "description", type: "text" }, + { name: "labels", type: "multiple" }, + { name: "index", type: "int" }, + { name: "rating", type: "float" }, + { name: "founded_date", type: "datetime" }, + { name: "email", type: "email" }, + { name: "plan", type: "string" }, + { name: "dark", type: "bool" }, + { name: "config", type: "json" }, + { name: "owner", type: "link", link: { table: "users" } }, ], - revLinks: [{ table: 'users', column: 'team' }] + revLinks: [{ table: "users", column: "team" }], }, { - name: 'users', + name: "users", columns: [ - { name: 'email', type: 'email', unique: true }, - { name: 'name', type: 'string' }, - { name: 'photo', type: 'file' }, - { name: 'attachments', type: 'file[]' }, - { name: 'plan', type: 'string' }, - { name: 'dark', type: 'bool' }, + { name: "xata_id", type: "string", notNull: true }, + { name: "xata_version", type: "int", notNull: true }, + { name: "xata_createdat", type: "datetime", notNull: true }, + { name: "xata_updatedat", type: "datetime", notNull: true }, + { name: "email", type: "email", unique: true }, + { name: "name", type: "string" }, + { name: "photo", type: "file", file: { defaultPublicAccess: true } }, + { name: "attachments", type: "file[]" }, + { name: "plan", type: "string" }, + { name: "dark", type: "bool" }, { - name: 'full_name', - type: 'string', + name: "full_name", + type: "string", notNull: true, - defaultValue: 'John Doe' + defaultValue: "John Doe", }, - { name: 'index', type: 'int' }, - { name: 'rating', type: 'float' }, - { name: 'birthDate', type: 'datetime' }, - { name: 'street', type: 'string' }, - { name: 'zipcode', type: 'int' }, - { name: 'team', type: 'link', link: { table: 'teams' } }, - { name: 'pet', type: 'link', link: { table: 'pets' } }, - { name: 'account_value', type: 'int' }, - { name: 'vector', type: 'vector', vector: { dimension: 4 } } + { name: "index", type: "int" }, + { name: "rating", type: "float" }, + { name: "birthDate", type: "datetime" }, + { name: "street", type: "string" }, + { name: "zipcode", type: "int" }, + { name: "team", type: "link", link: { table: "teams" } }, + { name: "pet", type: "link", link: { table: "pets" } }, + { name: "account_value", type: "int" }, + { name: "vector", type: "vector", vector: { dimension: 4 } }, ], - revLinks: [{ table: 'teams', column: 'owner' }] + revLinks: [{ table: "teams", column: "owner" }], }, { - name: 'pets', + name: "pets", columns: [ - { name: 'name', type: 'string' }, - { name: 'type', type: 'string' }, - { name: 'num_legs', type: 'int' } + { name: "xata_id", type: "string", notNull: true }, + { name: "xata_version", type: "int", notNull: true }, + { name: "xata_createdat", type: "datetime", notNull: true }, + { name: "xata_updatedat", type: "datetime", notNull: true }, + { name: "name", type: "string" }, + { name: "type", type: "string" }, + { name: "num_legs", type: "int" }, ], - revLinks: [{ table: 'users', column: 'pet' }] - } + revLinks: [{ table: "users", column: "pet" }], + }, ]; /** @type { import('../../client/src').ClientConstructor<{}> } */ const DatabaseClient = (0, client_1.buildClient)(); const defaultOptions = { - databaseURL: 'https://test-r5vcv5.eu-west-1.xata.sh/db/test' + databaseURL: "https://test-r5vcv5.eu-west-1.xata.sh/db/test", }; /** @typedef { import('./types').DatabaseSchema } DatabaseSchema */ /** @extends DatabaseClient */ diff --git a/packages/codegen/example/xata.js b/packages/codegen/example/xata.js index c305d4780..df321e500 100644 --- a/packages/codegen/example/xata.js +++ b/packages/codegen/example/xata.js @@ -1,4 +1,4 @@ -// Generated by Xata Codegen 0.27.0. Please do not edit. +// Generated by Xata Codegen 0.29.1. Please do not edit. import { buildClient } from '../../client/src'; /** @typedef { import('./types').SchemaTables } SchemaTables */ /** @type { SchemaTables } */ @@ -6,6 +6,10 @@ const tables = [ { name: 'teams', columns: [ + { name: 'xata_id', type: 'string', notNull: true }, + { name: 'xata_version', type: 'int', notNull: true }, + { name: 'xata_createdat', type: 'datetime', notNull: true }, + { name: 'xata_updatedat', type: 'datetime', notNull: true }, { name: 'name', type: 'string' }, { name: 'description', type: 'text' }, { name: 'labels', type: 'multiple' }, @@ -23,9 +27,13 @@ const tables = [ { name: 'users', columns: [ + { name: 'xata_id', type: 'string', notNull: true }, + { name: 'xata_version', type: 'int', notNull: true }, + { name: 'xata_createdat', type: 'datetime', notNull: true }, + { name: 'xata_updatedat', type: 'datetime', notNull: true }, { name: 'email', type: 'email', unique: true }, { name: 'name', type: 'string' }, - { name: 'photo', type: 'file' }, + { name: 'photo', type: 'file', file: { defaultPublicAccess: true } }, { name: 'attachments', type: 'file[]' }, { name: 'plan', type: 'string' }, { name: 'dark', type: 'bool' }, @@ -50,6 +58,10 @@ const tables = [ { name: 'pets', columns: [ + { name: 'xata_id', type: 'string', notNull: true }, + { name: 'xata_version', type: 'int', notNull: true }, + { name: 'xata_createdat', type: 'datetime', notNull: true }, + { name: 'xata_updatedat', type: 'datetime', notNull: true }, { name: 'name', type: 'string' }, { name: 'type', type: 'string' }, { name: 'num_legs', type: 'int' } diff --git a/packages/codegen/example/xata.ts b/packages/codegen/example/xata.ts index 963d89588..68e6af4e0 100644 --- a/packages/codegen/example/xata.ts +++ b/packages/codegen/example/xata.ts @@ -6,6 +6,10 @@ const tables = [ { name: 'teams', columns: [ + { name: 'xata_id', type: 'string', notNull: true }, + { name: 'xata_version', type: 'int', notNull: true }, + { name: 'xata_createdat', type: 'datetime', notNull: true }, + { name: 'xata_updatedat', type: 'datetime', notNull: true }, { name: 'name', type: 'string' }, { name: 'description', type: 'text' }, { name: 'labels', type: 'multiple' }, @@ -23,9 +27,13 @@ const tables = [ { name: 'users', columns: [ + { name: 'xata_id', type: 'string', notNull: true }, + { name: 'xata_version', type: 'int', notNull: true }, + { name: 'xata_createdat', type: 'datetime', notNull: true }, + { name: 'xata_updatedat', type: 'datetime', notNull: true }, { name: 'email', type: 'email', unique: true }, { name: 'name', type: 'string' }, - { name: 'photo', type: 'file' }, + { name: 'photo', type: 'file', file: { defaultPublicAccess: true } }, { name: 'attachments', type: 'file[]' }, { name: 'plan', type: 'string' }, { name: 'dark', type: 'bool' }, @@ -50,6 +58,10 @@ const tables = [ { name: 'pets', columns: [ + { name: 'xata_id', type: 'string', notNull: true }, + { name: 'xata_version', type: 'int', notNull: true }, + { name: 'xata_createdat', type: 'datetime', notNull: true }, + { name: 'xata_updatedat', type: 'datetime', notNull: true }, { name: 'name', type: 'string' }, { name: 'type', type: 'string' }, { name: 'num_legs', type: 'int' } diff --git a/test/integration/create.test.ts b/test/integration/create.test.ts index 5296cfd62..db9c75fd8 100644 --- a/test/integration/create.test.ts +++ b/test/integration/create.test.ts @@ -30,33 +30,25 @@ describe('record creation', () => { test('create single user without id', async () => { const user = await xata.db.users.create({ name: 'User ships', birthDate: new Date() }); - expect(user.id).toBeDefined(); + expect(user.xata_id).toBeDefined(); expect(user.name).toBe('User ships'); expect(user.read).toBeDefined(); - expect(user.getMetadata).toBeDefined(); expect(user.birthDate).toBeInstanceOf(Date); - const metadata = user.getMetadata(); - expect(metadata.createdAt).toBeInstanceOf(Date); - expect(metadata.updatedAt).toBeInstanceOf(Date); - expect(metadata.version).toBe(0); - - expect(user.xata.createdAt).toBeInstanceOf(Date); - expect(user.xata.updatedAt).toBeInstanceOf(Date); - expect(user.xata.version).toBe(0); + expect(user.xata_createdat).toBeInstanceOf(Date); + expect(user.xata_updatedat).toBeInstanceOf(Date); + expect(user.xata_version).toBe(0); const json = user.toSerializable(); - expect(json.xata.createdAt).toBeDefined(); - expect(json.xata.updatedAt).toBeDefined(); - expect(json.xata.version).toBe(0); + expect(json.xata_createdat).toBeDefined(); + expect(json.xata_updatedat).toBeDefined(); + expect(json.xata_version).toBe(0); - expect(json.id).toBeDefined(); + expect(json.xata_id).toBeDefined(); expect(json.name).toBe('User ships'); // @ts-expect-error expect(json.read).not.toBeDefined(); - // @ts-expect-error - expect(json.getMetadata).not.toBeDefined(); expect(typeof json.birthDate).toBe('string'); }); @@ -64,53 +56,42 @@ describe('record creation', () => { const team = await xata.db.teams.create({ name: 'Team ships' }); const user = await xata.db.users.create({ name: 'User ships', team }, ['*', 'team.*']); - expect(user.id).toBeDefined(); + expect(user.xata_id).toBeDefined(); expect(user.name).toBe('User ships'); expect(user.read).toBeDefined(); - expect(user.getMetadata).toBeDefined(); expect(user.team).toBeDefined(); - expect(user.team?.id).toBe(team.id); + expect(user.team?.xata_id).toBe(team.xata_id); expect(user.team?.name).toBe('Team ships'); expect(user.team?.read).toBeDefined(); - expect(user.team?.getMetadata).toBeDefined(); - - const userMetadata = user.getMetadata(); - expect(userMetadata.createdAt).toBeInstanceOf(Date); - expect(userMetadata.updatedAt).toBeInstanceOf(Date); - expect(userMetadata.version).toBe(0); - expect(user.xata.createdAt).toBeInstanceOf(Date); - expect(user.xata.updatedAt).toBeInstanceOf(Date); - expect(user.xata.version).toBe(0); + expect(user.xata_createdat).toBeInstanceOf(Date); + expect(user.xata_updatedat).toBeInstanceOf(Date); + expect(user.xata_version).toBe(0); const json = user.toSerializable(); - expect(json.id).toBeDefined(); + expect(json.xata_id).toBeDefined(); expect(json.name).toBe('User ships'); // @ts-expect-error expect(json.read).not.toBeDefined(); - // @ts-expect-error - expect(json.getMetadata).not.toBeDefined(); expect(json.team).toBeDefined(); - expect(json.team?.id).toBe(team.id); + expect(json.team?.xata_id).toBe(team.xata_id); expect(json.team?.name).toBe('Team ships'); // @ts-expect-error expect(json.team.read).not.toBeDefined(); - // @ts-expect-error - expect(json.team.getMetadata).not.toBeDefined(); }); test('create multiple teams without ids', async () => { const teams = await xata.db.teams.create([{ name: 'Team cars' }, { name: 'Team planes' }], ['*', 'owner.*']); expect(teams).toHaveLength(2); - expect(teams[0].id).toBeDefined(); + expect(teams[0].xata_id).toBeDefined(); expect(teams[0].name).toBe('Team cars'); expect(teams[0].read).toBeDefined(); - expect(teams[1].id).toBeDefined(); + expect(teams[1].xata_id).toBeDefined(); expect(teams[1].name).toBe('Team planes'); expect(teams[1].read).toBeDefined(); - expect(teams[0].id).not.toBe(teams[1].id); + expect(teams[0].xata_id).not.toBe(teams[1].xata_id); expect(teams[0].labels).toBeNull(); expect(teams[1].labels).toBeNull(); @@ -126,21 +107,21 @@ describe('record creation', () => { email: 'john4@doe.com' }); - const apiUser = await xata.db.users.filter({ id: user.id }).getFirst(); + const apiUser = await xata.db.users.filter({ xata_id: user.xata_id }).getFirst(); if (!apiUser) throw new Error('No user found'); - expect(user.id).toBe('a-unique-record-john-4'); + expect(user.xata_id).toBe('a-unique-record-john-4'); expect(user.read).toBeDefined(); expect(user.full_name).toBe('John Doe 4'); expect(user.full_name.startsWith('John')).toBe(true); - expect(user.id).toBe(apiUser.id); + expect(user.xata_id).toBe(apiUser.xata_id); expect(user.full_name).toBe(apiUser.full_name); expect(user.email).toBe(apiUser.email); - expect(user.xata.createdAt).toBeInstanceOf(Date); - expect(apiUser.xata.createdAt).toBeInstanceOf(Date); - expect(user.xata.createdAt.getTime()).toBe(apiUser.xata.createdAt.getTime()); + expect(user.xata_createdat).toBeInstanceOf(Date); + expect(apiUser.xata_createdat).toBeInstanceOf(Date); + expect(user.xata_createdat.getTime()).toBe(apiUser.xata_createdat.getTime()); expect( xata.db.users.create('a-unique-record-john-4', { @@ -152,19 +133,19 @@ describe('record creation', () => { test('create user with inlined id', async () => { const user = await xata.db.users.create({ - id: 'a-unique-record-john-5', + xata_id: 'a-unique-record-john-5', full_name: 'John Doe 5', email: 'john5@doe.com' }); - const apiUser = await xata.db.users.filter({ id: user.id }).getFirst(); + const apiUser = await xata.db.users.filter({ xata_id: user.xata_id }).getFirst(); if (!apiUser) throw new Error('No user found'); - expect(user.id).toBe('a-unique-record-john-5'); + expect(user.xata_id).toBe('a-unique-record-john-5'); expect(user.read).toBeDefined(); expect(user.full_name).toBe('John Doe 5'); - expect(user.id).toBe(apiUser.id); + expect(user.xata_id).toBe(apiUser.xata_id); expect(user.full_name).toBe(apiUser.full_name); expect(user.email).toBe(apiUser.email); }); @@ -181,7 +162,7 @@ describe('record creation', () => { test('create user with empty inline id is not allowed', async () => { expect( xata.db.users.create({ - id: '', + xata_id: '', full_name: 'John Doe 3', email: 'john3@doe.com' }) @@ -204,53 +185,56 @@ describe('record creation', () => { }); test('create multiple some with id and others without id', async () => { - const teams = await xata.db.teams.create([{ id: 'team_cars', name: 'Team cars' }, { name: 'Team planes' }]); + const teams = await xata.db.teams.create([{ xata_id: 'team_cars', name: 'Team cars' }, { name: 'Team planes' }]); expect(teams).toHaveLength(2); - expect(teams[0].id).toBe('team_cars'); + expect(teams[0].xata_id).toBe('team_cars'); expect(teams[0].name).toBe('Team cars'); expect(teams[0].read).toBeDefined(); - expect(teams[1].id).toBeDefined(); + expect(teams[1].xata_id).toBeDefined(); expect(teams[1].name).toBe('Team planes'); expect(teams[1].read).toBeDefined(); }); test('create multiple with returning columns', async () => { - const teams = await xata.db.teams.create([{ name: 'Team cars' }, { name: 'Team planes', labels: ['foo'] }], ['id']); + const teams = await xata.db.teams.create( + [{ name: 'Team cars' }, { name: 'Team planes', labels: ['foo'] }], + ['xata_id'] + ); expect(teams).toHaveLength(2); - expect(teams[0].id).toBeDefined(); + expect(teams[0].xata_id).toBeDefined(); // @ts-expect-error expect(teams[0].name).not.toBeDefined(); expect(teams[0].read).toBeDefined(); - expect(teams[1].id).toBeDefined(); + expect(teams[1].xata_id).toBeDefined(); // @ts-expect-error expect(teams[1].name).not.toBeDefined(); expect(teams[1].read).toBeDefined(); const team1 = await teams[0].read(); - expect(team1?.id).toBe(teams[0].id); + expect(team1?.xata_id).toBe(teams[0].xata_id); expect(team1?.name).toBe('Team cars'); const team2 = await teams[1].read(['labels']); - expect(team2?.id).toBe(teams[1].id); + expect(team2?.xata_id).toBe(teams[1].xata_id); // @ts-expect-error expect(team2?.name).not.toBeDefined(); expect(team2?.labels).toEqual(['foo']); }); test('create single with returning columns', async () => { - const team = await xata.db.teams.create({ name: 'Team cars' }, ['id', 'owner']); + const team = await xata.db.teams.create({ name: 'Team cars' }, ['xata_id', 'owner']); expect(team).toBeDefined(); - expect(team.id).toBeDefined(); + expect(team.xata_id).toBeDefined(); // @ts-expect-error expect(team.name).not.toBeDefined(); expect(team.owner).toBeNull(); expect(team.read).toBeDefined(); const team1 = await team.read(); - expect(team1?.id).toBe(team.id); + expect(team1?.xata_id).toBe(team.xata_id); expect(team1?.name).toBe('Team cars'); }); @@ -258,7 +242,7 @@ describe('record creation', () => { const data = { full_name: 'John Doe 3', email: 'unique@example.com' }; const user = await xata.db.users.create(data); - expect(user.id).toBeDefined(); + expect(user.xata_id).toBeDefined(); expect(user.read).toBeDefined(); expect(user.full_name).toBe(data.full_name); expect(user.email).toBe(data.email); @@ -275,7 +259,7 @@ describe('record creation', () => { test('create and fail if already exists', async () => { const user1 = await xata.db.users.create({ full_name: 'John Doe 3', email: 'doe3@john.net' }); - expect(user1.id).toBeDefined(); + expect(user1.xata_id).toBeDefined(); expect(user1.read).toBeDefined(); expect(user1.full_name).toBe('John Doe 3'); @@ -285,7 +269,7 @@ describe('record creation', () => { test('create multiple fails if one of them already exists', async () => { const user1 = await xata.db.users.create({ full_name: 'John Doe 4', email: 'doe4@john.net' }); - expect(user1.id).toBeDefined(); + expect(user1.xata_id).toBeDefined(); expect(user1.read).toBeDefined(); expect(user1.full_name).toBe('John Doe 4'); @@ -318,7 +302,7 @@ describe('record creation', () => { ]); expect(teams).toHaveLength(2); - expect(teams[0].id).toBeDefined(); + expect(teams[0].xata_id).toBeDefined(); expect(teams[0].name).toMatchInlineSnapshot(` "Team 🚗" @@ -338,7 +322,7 @@ describe('record creation', () => { 🚕" `); - expect(teams[1].id).toBeDefined(); + expect(teams[1].xata_id).toBeDefined(); expect(teams[1].name).toMatchInlineSnapshot('"Team 🚀"'); expect(teams[1].labels).toMatchInlineSnapshot(` [ @@ -373,11 +357,11 @@ describe('record creation', () => { const team = await xata.db.teams.create({ name: 'Team cars', owner: user }, ['owner.name']); expect(team).toBeDefined(); - expect(team.id).toBeDefined(); + expect(team.xata_id).toBeDefined(); // @ts-expect-error expect(team.name).toBeUndefined(); expect(team.owner).toBeDefined(); - expect(team.owner?.id).toBe(user.id); + expect(team.owner?.xata_id).toBe(user.xata_id); expect(team.owner?.name).toBe('John Doe 3'); }); }); diff --git a/test/integration/createOrReplace.test.ts b/test/integration/createOrReplace.test.ts index 8d320ce15..541bc37ed 100644 --- a/test/integration/createOrReplace.test.ts +++ b/test/integration/createOrReplace.test.ts @@ -34,13 +34,13 @@ describe('record create or replace', () => { expect(team.email).toBe('ships@ilovethem.com'); expect(team.name).toBe('Team ships'); - const replacedTeam = await xata.db.teams.createOrReplace(team.id, { name: 'Team boats' }); + const replacedTeam = await xata.db.teams.createOrReplace(team.xata_id, { name: 'Team boats' }); - expect(replacedTeam.id).toBe(team.id); + expect(replacedTeam.xata_id).toBe(team.xata_id); expect(replacedTeam.read).toBeDefined(); expect(replacedTeam.email).toBeNull(); - const apiTeam = await xata.db.teams.filter({ id: team.id }).getFirst(); + const apiTeam = await xata.db.teams.filter({ xata_id: team.xata_id }).getFirst(); expect(replacedTeam.name).toBe('Team boats'); expect(apiTeam?.name).toBe('Team boats'); @@ -48,14 +48,14 @@ describe('record create or replace', () => { }); test('create or replace with optional id', async () => { - const id: string | undefined = undefined; + const xata_id: string | undefined = undefined; - const team = await xata.db.teams.createOrReplace({ id, name: 'Team ships' }); - expect(team.id).toBeDefined(); + const team = await xata.db.teams.createOrReplace({ xata_id, name: 'Team ships' }); + expect(team.xata_id).toBeDefined(); }); test('create or replace fails with empty id', async () => { - await expect(xata.db.teams.createOrReplace({ id: '', name: 'Team ships' })).rejects.toThrowError(); + await expect(xata.db.teams.createOrReplace({ xata_id: '', name: 'Team ships' })).rejects.toThrowError(); }); test('create or replace team with inline id', async () => { @@ -64,13 +64,13 @@ describe('record create or replace', () => { expect(team.read).toBeDefined(); expect(team.email).toBe('ships2@example.com'); - const replacedTeam = await xata.db.teams.createOrReplace({ id: team.id, name: 'Team boats' }); + const replacedTeam = await xata.db.teams.createOrReplace({ xata_id: team.xata_id, name: 'Team boats' }); - expect(replacedTeam.id).toBe(team.id); + expect(replacedTeam.xata_id).toBe(team.xata_id); expect(replacedTeam.read).toBeDefined(); expect(replacedTeam.email).toBeNull(); - const apiTeam = await xata.db.teams.filter({ id: team.id }).getFirst(); + const apiTeam = await xata.db.teams.filter({ xata_id: team.xata_id }).getFirst(); expect(replacedTeam.name).toBe('Team boats'); expect(apiTeam?.name).toBe('Team boats'); @@ -84,14 +84,14 @@ describe('record create or replace', () => { expect(team.email).toBe('ships3@example.com'); const replacedTeam = await xata.db.teams.createOrReplace([ - { id: team.id, name: 'Team boats' }, - { ...team, id: 'planes' } + { xata_id: team.xata_id, name: 'Team boats' }, + { ...team, xata_id: 'planes' } ]); - expect(replacedTeam[0].id).toBe(team.id); + expect(replacedTeam[0].xata_id).toBe(team.xata_id); expect(replacedTeam[0].read).toBeDefined(); expect(replacedTeam[0].email).toBeNull(); - expect(replacedTeam[1].id).toBe('planes'); + expect(replacedTeam[1].xata_id).toBe('planes'); expect(replacedTeam[1].read).toBeDefined(); expect(replacedTeam[1].email).toBe(team.email); }); diff --git a/test/integration/createOrUpdate.test.ts b/test/integration/createOrUpdate.test.ts index dc82eba7f..74718d3c6 100644 --- a/test/integration/createOrUpdate.test.ts +++ b/test/integration/createOrUpdate.test.ts @@ -30,39 +30,39 @@ describe('record create or update', () => { test('create or update single team with id', async () => { const team = await xata.db.teams.create({ name: 'Team ships' }); - const updatedTeam = await xata.db.teams.createOrUpdate(team.id, { name: 'Team boats' }); + const updatedTeam = await xata.db.teams.createOrUpdate(team.xata_id, { name: 'Team boats' }); - expect(updatedTeam.id).toBe(team.id); + expect(updatedTeam.xata_id).toBe(team.xata_id); expect(updatedTeam.read).toBeDefined(); - const apiTeam = await xata.db.teams.filter({ id: team.id }).getFirst(); + const apiTeam = await xata.db.teams.filter({ xata_id: team.xata_id }).getFirst(); expect(updatedTeam.name).toBe('Team boats'); expect(apiTeam?.name).toBe('Team boats'); }); test('create or update with optional id', async () => { - const id: string | undefined = undefined; + const xata_id: string | undefined = undefined; - const team = await xata.db.teams.createOrUpdate(id, { name: 'Team ships' }); - expect(team.id).toBeDefined(); + const team = await xata.db.teams.createOrUpdate(xata_id, { name: 'Team ships' }); + expect(team.xata_id).toBeDefined(); }); test('create or update fails with empty id', async () => { - const id: string | undefined = ''; + const xata_id: string | undefined = ''; - await expect(xata.db.teams.createOrUpdate(id, { name: 'Team ships' })).rejects.toThrowError(); + await expect(xata.db.teams.createOrUpdate(xata_id, { name: 'Team ships' })).rejects.toThrowError(); }); test('create or update team with inline id', async () => { const team = await xata.db.teams.create({ name: 'Team ships' }); - const updatedTeam = await xata.db.teams.createOrUpdate({ id: team.id, name: 'Team boats' }); + const updatedTeam = await xata.db.teams.createOrUpdate({ xata_id: team.xata_id, name: 'Team boats' }); - expect(updatedTeam.id).toBe(team.id); + expect(updatedTeam.xata_id).toBe(team.xata_id); expect(updatedTeam.read).toBeDefined(); - const apiTeam = await xata.db.teams.filter({ id: team.id }).getFirst(); + const apiTeam = await xata.db.teams.filter({ xata_id: team.xata_id }).getFirst(); expect(updatedTeam.name).toBe('Team boats'); expect(apiTeam?.name).toBe('Team boats'); @@ -71,17 +71,19 @@ describe('record create or update', () => { test('create or update multiple teams', async () => { const teams = await xata.db.teams.create([{ name: 'Team cars' }, { name: 'Team planes' }]); - const updatedTeams = await xata.db.teams.createOrUpdate(teams.map((team) => ({ id: team.id, name: 'Team boats' }))); + const updatedTeams = await xata.db.teams.createOrUpdate( + teams.map((team) => ({ xata_id: team.xata_id, name: 'Team boats' })) + ); expect(updatedTeams).toHaveLength(2); expect(updatedTeams[0].read).toBeDefined(); expect(updatedTeams[1].read).toBeDefined(); - expect(updatedTeams[0].id).toBe(teams[0].id); - expect(updatedTeams[1].id).toBe(teams[1].id); + expect(updatedTeams[0].xata_id).toBe(teams[0].xata_id); + expect(updatedTeams[1].xata_id).toBe(teams[1].xata_id); expect(updatedTeams[0].name).toBe('Team boats'); expect(updatedTeams[1].name).toBe('Team boats'); - const apiTeams = await xata.db.teams.filter({ $any: teams.map((t) => ({ id: t.id })) }).getAll(); + const apiTeams = await xata.db.teams.filter({ $any: teams.map((t) => ({ xata_id: t.xata_id })) }).getAll(); expect(apiTeams).toHaveLength(2); @@ -95,10 +97,10 @@ describe('record create or update', () => { }); test('create or update many without getting rate limited', async () => { - const newUsers = Array.from({ length: 250 }).map((_, i) => ({ id: `user-${i}`, full_name: `user-${i}` })); - const result = await Promise.all(newUsers.map((user) => xata.db.users.createOrUpdate(user, ['id']))); + const newUsers = Array.from({ length: 250 }).map((_, i) => ({ xata_id: `user-${i}`, full_name: `user-${i}` })); + const result = await Promise.all(newUsers.map((user) => xata.db.users.createOrUpdate(user, ['xata_id']))); expect(result).toHaveLength(250); - expect(result.every((item) => item.id)).toBeTruthy(); + expect(result.every((item) => item.xata_id)).toBeTruthy(); }, 100000); }); diff --git a/test/integration/delete.test.ts b/test/integration/delete.test.ts index 0c6918e43..174c14852 100644 --- a/test/integration/delete.test.ts +++ b/test/integration/delete.test.ts @@ -30,13 +30,13 @@ describe('record deletion', () => { test('delete single team with id', async () => { const team = await xata.db.teams.create({ name: 'Team ships' }); - await xata.db.teams.delete(team.id); + await xata.db.teams.delete(team.xata_id); const copy = await team.read(); expect(copy).toBeNull(); - const apiTeam = await xata.db.teams.filter({ id: team.id }).getFirst(); + const apiTeam = await xata.db.teams.filter({ xata_id: team.xata_id }).getFirst(); expect(apiTeam).toBeNull(); }); @@ -44,17 +44,17 @@ describe('record deletion', () => { test('delete multiple teams with id list', async () => { const teams = await xata.db.teams.create([{ name: 'Team cars' }, { name: 'Team planes' }]); - const result = await xata.db.teams.delete(teams.map((team) => team.id)); + const result = await xata.db.teams.delete(teams.map((team) => team.xata_id)); expect(result.length).toBe(2); - expect(result[0]?.id).toBe(teams[0].id); - expect(result[1]?.id).toBe(teams[1].id); + expect(result[0]?.xata_id).toBe(teams[0].xata_id); + expect(result[1]?.xata_id).toBe(teams[1].xata_id); expect(result[0]?.read).toBeDefined(); expect(result[1]?.read).toBeDefined(); expect(result[0]?.name).toBe('Team cars'); expect(result[1]?.name).toBe('Team planes'); - const apiTeams = await xata.db.teams.filter({ $any: teams.map((t) => ({ id: t.id })) }).getAll(); + const apiTeams = await xata.db.teams.filter({ $any: teams.map((t) => ({ xata_id: t.xata_id })) }).getAll(); expect(apiTeams).toHaveLength(0); }); @@ -68,7 +68,7 @@ describe('record deletion', () => { expect(copy).toBeNull(); - const apiTeam = await xata.db.teams.filter({ id: team.id }).getFirst(); + const apiTeam = await xata.db.teams.filter({ xata_id: team.xata_id }).getFirst(); expect(apiTeam).toBeNull(); }); @@ -78,7 +78,7 @@ describe('record deletion', () => { await xata.db.teams.delete(teams); - const apiTeams = await xata.db.teams.filter({ $any: teams.map((t) => ({ id: t.id })) }).getAll(); + const apiTeams = await xata.db.teams.filter({ $any: teams.map((t) => ({ xata_id: t.xata_id })) }).getAll(); expect(apiTeams).toHaveLength(0); }); @@ -86,18 +86,18 @@ describe('record deletion', () => { test('delete multiple teams with invalid', async () => { const teams = await xata.db.teams.create([{ name: 'Team cars' }, { name: 'Team planes' }]); - const result = await xata.db.teams.delete([...teams, { id: 'invalid' }]); + const result = await xata.db.teams.delete([...teams, { xata_id: 'invalid' }]); expect(result.length).toBe(3); - expect(result[0]?.id).toBe(teams[0].id); - expect(result[1]?.id).toBe(teams[1].id); + expect(result[0]?.xata_id).toBe(teams[0].xata_id); + expect(result[1]?.xata_id).toBe(teams[1].xata_id); expect(result[0]?.read).toBeDefined(); expect(result[1]?.read).toBeDefined(); expect(result[0]?.name).toBe('Team cars'); expect(result[1]?.name).toBe('Team planes'); expect(result[2]).toBeNull(); - const apiTeams = await xata.db.teams.filter({ $any: teams.map((t) => ({ id: t.id })) }).getAll(); + const apiTeams = await xata.db.teams.filter({ $any: teams.map((t) => ({ xata_id: t.xata_id })) }).getAll(); expect(apiTeams).toHaveLength(0); }); @@ -110,7 +110,7 @@ describe('record deletion', () => { expect(copy).toBeNull(); - const apiTeam = await xata.db.teams.filter({ id: team.id }).getFirst(); + const apiTeam = await xata.db.teams.filter({ xata_id: team.xata_id }).getFirst(); expect(apiTeam).toBeNull(); }); @@ -119,14 +119,14 @@ describe('record deletion', () => { const valid = await xata.db.teams.create({ name: 'Team ships' }); const team1 = await xata.db.teams.delete('invalid'); - const team2 = await xata.db.teams.delete({ id: 'invalid', name: 'Team boats' }); - const team3 = await xata.db.teams.delete([{ id: 'invalid', name: 'Team boats' }, valid]); + const team2 = await xata.db.teams.delete({ xata_id: 'invalid', name: 'Team boats' }); + const team3 = await xata.db.teams.delete([{ xata_id: 'invalid', name: 'Team boats' }, valid]); expect(team1).toBeNull(); expect(team2).toBeNull(); expect(team3[0]).toBeNull(); expect(team3[1]).toBeDefined(); - expect(team3[1]?.id).toBe(valid.id); + expect(team3[1]?.xata_id).toBe(valid.xata_id); expect(team3[1]?.name).toBe('Team ships'); }); @@ -134,7 +134,7 @@ describe('record deletion', () => { const team = await xata.db.teams.create({ name: 'Team ships' }); const result = await xata.db.teams.delete(team); - expect(result?.id).toBe(team.id); + expect(result?.xata_id).toBe(team.xata_id); const result2 = await xata.db.teams.delete(team); expect(result2).toBeNull(); diff --git a/test/integration/files.test.ts b/test/integration/files.test.ts index 90504835f..aecde9c22 100644 --- a/test/integration/files.test.ts +++ b/test/integration/files.test.ts @@ -68,7 +68,7 @@ describe('file support', () => { test('create file with binary endpoint JSON and mediaType override', async () => { const record = await xata.db.users.create({ name: 'another' }); - const file = await xata.files.upload({ table: 'users', column: 'attachments', record: record.id }, json, { + const file = await xata.files.upload({ table: 'users', column: 'attachments', record: record.xata_id }, json, { mediaType: 'text/plain' }); @@ -89,7 +89,7 @@ describe('file support', () => { test('create file with binary endpoint JSON', async () => { const record = await xata.db.users.create({ name: 'another' }); - const file = await xata.files.upload({ table: 'users', column: 'attachments', record: record.id }, json); + const file = await xata.files.upload({ table: 'users', column: 'attachments', record: record.xata_id }, json); expect(file.id).toBeDefined(); expect(file.mediaType).toBe('application/json'); @@ -108,7 +108,7 @@ describe('file support', () => { test('create file with binary endpoint CSV', async () => { const record = await xata.db.users.create({ name: 'another' }); - const file = await xata.files.upload({ table: 'users', column: 'attachments', record: record.id }, csv); + const file = await xata.files.upload({ table: 'users', column: 'attachments', record: record.xata_id }, csv); expect(file.id).toBeDefined(); expect(file.mediaType).toBe('text/csv'); @@ -128,7 +128,7 @@ describe('file support', () => { test('create XataFile on binary endpoint', async () => { const record = await xata.db.users.create({ name: 'another' }); const file = await xata.files.upload( - { table: 'users', column: 'attachments', record: record.id }, + { table: 'users', column: 'attachments', record: record.xata_id }, XataFile.fromBlob(csv) ); @@ -166,7 +166,7 @@ describe('file support', () => { expect(upload1.status).toBe(201); expect(upload2.status).toBe(201); - const user = await xata.db.users.read(result.id, [ + const user = await xata.db.users.read(result.xata_id, [ '*', 'photo.*', 'photo.base64Content', diff --git a/test/integration/json.test.ts b/test/integration/json.test.ts index 6f76e3da0..9bef22a5a 100644 --- a/test/integration/json.test.ts +++ b/test/integration/json.test.ts @@ -29,7 +29,7 @@ afterEach(async (ctx) => { describe('JSON support', () => { test('read returns json', async () => { const record = await xata.db.teams.create({ name: 'test', config: { hello: 'world' } }); - const read = await xata.db.teams.read(record.id, ['config']); + const read = await xata.db.teams.read(record.xata_id, ['config']); expect(read?.config.hello).toBe('world'); }); @@ -47,7 +47,7 @@ describe('JSON support', () => { expect(record.config.hello).toBe('world'); - await xata.db.teams.delete(record.id); + await xata.db.teams.delete(record.xata_id); }); test('create file with JSON as string', async () => { @@ -55,7 +55,7 @@ describe('JSON support', () => { expect(record.config.hello).toBe('world'); - await xata.db.teams.delete(record.id); + await xata.db.teams.delete(record.xata_id); }); test('create file with JSON array as object', async () => { @@ -63,7 +63,7 @@ describe('JSON support', () => { expect(record.config[0].hello[0]).toBe('world'); - await xata.db.teams.delete(record.id); + await xata.db.teams.delete(record.xata_id); }); test('create file with JSON array as string', async () => { @@ -71,7 +71,7 @@ describe('JSON support', () => { expect(record.config[0].hello[0]).toBe('world'); - await xata.db.teams.delete(record.id); + await xata.db.teams.delete(record.xata_id); }); test('filters work with JSON fields', async () => { @@ -118,22 +118,22 @@ describe('JSON support', () => { .getAll(); expect(filterEquals.length).toBe(1); - expect(filterEquals[0].id).toBe(r2.id); + expect(filterEquals[0].xata_id).toBe(r2.xata_id); const filterNodeEqualsString = await xata.db.teams.filter('config->bg->path', 'a/b/c').getAll(); expect(filterNodeEqualsString.length).toBe(2); const filterNodeEqualsNumber = await xata.db.teams.filter('config->bg->alpha', 0.8).getAll(); expect(filterNodeEqualsNumber.length).toBe(1); - expect(filterNodeEqualsNumber[0].id).toBe(r1.id); + expect(filterNodeEqualsNumber[0].xata_id).toBe(r1.xata_id); const filterNodeGreaterThan = await xata.db.teams.filter('config->bg->alpha', { $gt: 0.5 }).getAll(); expect(filterNodeGreaterThan.length).toBe(1); - expect(filterNodeGreaterThan[0].id).toBe(r1.id); + expect(filterNodeGreaterThan[0].xata_id).toBe(r1.xata_id); const filterNodeLessThan = await xata.db.teams.filter('config->bg->alpha', { $lt: 0.5 }).getAll(); expect(filterNodeLessThan.length).toBe(1); - expect(filterNodeLessThan[0].id).toBe(r2.id); + expect(filterNodeLessThan[0].xata_id).toBe(r2.xata_id); const filterNodeEqualsNumberNotFound = await xata.db.teams.filter('config->bg->alpha', 1).getAll(); expect(filterNodeEqualsNumberNotFound.length).toBe(0); @@ -212,15 +212,15 @@ describe('JSON support', () => { const recordsBySizeM = await xata.db.teams.filter({ 'config->size': 'M' }).getMany(); expect(recordsBySizeM.length).toBe(1); - expect(recordsBySizeM[0].id).toBe(record1.id); + expect(recordsBySizeM[0].xata_id).toBe(record1.xata_id); const recordsLengthGreater = await xata.db.teams.filter({ 'config->length': { $gt: 50 } }).getMany(); expect(recordsLengthGreater.length).toBe(1); - expect(recordsLengthGreater[0].id).toBe(record3.id); + expect(recordsLengthGreater[0].xata_id).toBe(record3.xata_id); const recordsBySubstring = await xata.db.teams.filter({ 'config->isbn': { $contains: '0140449334' } }).getMany(); expect(recordsBySubstring.length).toBe(1); - expect(recordsBySubstring[0].id).toBe(record2.id); + expect(recordsBySubstring[0].xata_id).toBe(record2.xata_id); const recordsWithNegationOperator = await xata.db.teams.filter({ 'config->color': { $isNot: 'yellow' } }).getMany(); expect(recordsWithNegationOperator.length).toBe(2); diff --git a/test/integration/query.test.ts b/test/integration/query.test.ts index a1bb91d08..233cf3514 100644 --- a/test/integration/query.test.ts +++ b/test/integration/query.test.ts @@ -5,7 +5,6 @@ import { iContains, includesAll, includesNone, - isXataRecord, lt, Repository, XataApiClient, @@ -42,8 +41,8 @@ beforeAll(async (ctx) => { await hooks.beforeAll(ctx); - const { id: ownerAnimalsId } = await xata.db.users.create(ownerAnimals); - const { id: ownerFruitsId } = await xata.db.users.create(ownerFruits); + const { xata_id: ownerAnimalsId } = await xata.db.users.create(ownerAnimals); + const { xata_id: ownerFruitsId } = await xata.db.users.create(ownerFruits); const fruitsTeam = await xata.db.teams.create({ name: 'Team fruits', @@ -249,9 +248,9 @@ describe('integration tests', () => { if (!ownerAnimals) throw new Error('Could not find owner of team animals'); // Regression test on filtering on nullable property - const team = await xata.db.teams.filter('owner.id', ownerAnimals.id).getFirst(); + const team = await xata.db.teams.filter('owner.xata_id', ownerAnimals.xata_id).getFirst(); - expect(team?.owner?.id).toEqual(ownerAnimals.id); + expect(team?.owner?.xata_id).toEqual(ownerAnimals.xata_id); }); test('filter on object', async () => { @@ -431,7 +430,7 @@ describe('integration tests', () => { test('get all users', async () => { const users = await xata.db.users.getAll(); expect(users).toHaveLength(mockUsers.length); - expect(users[0].id).toBeDefined(); + expect(users[0].xata_id).toBeDefined(); }); test('get first', async () => { @@ -440,11 +439,11 @@ describe('integration tests', () => { expect(user).toBeDefined(); expect(definedUser).toBeDefined(); - expect(user?.id).toBe(definedUser.id); + expect(user?.xata_id).toBe(definedUser.xata_id); }); test('get first not found', async () => { - const query = xata.db.users.filter('id', 'not-found'); + const query = xata.db.users.filter('xata_id', 'not-found'); const user = await query.getFirst(); @@ -479,7 +478,7 @@ describe('integration tests', () => { const user = await xata.db.users.select(['full_name']).getFirst(); expect(user).toBeDefined(); - expect(user?.id).toBeDefined(); + expect(user?.xata_id).toBeDefined(); expect(user?.full_name).toBeDefined(); //@ts-expect-error expect(user?.email).not.toBeDefined(); @@ -491,7 +490,7 @@ describe('integration tests', () => { }); expect(user).toBeDefined(); - expect(user?.id).toBeDefined(); + expect(user?.xata_id).toBeDefined(); expect(user?.full_name).toBeDefined(); expect(user?.email).toBeDefined(); }); @@ -503,10 +502,10 @@ describe('integration tests', () => { street: '123 Main St' }); - const records = await xata.db.users.filter('id', user.id).select(['*', 'team.*']).getAll(); + const records = await xata.db.users.filter('xata_id', user.xata_id).select(['*', 'team.*']).getAll(); expect(records).toHaveLength(1); - expect(records[0].id).toBe(user.id); + expect(records[0].xata_id).toBe(user.xata_id); expect(records[0].full_name).toBe('John Doe'); expect(records[0].street).toBe('123 Main St'); expect(records[0].team).toBeNull(); @@ -521,14 +520,14 @@ describe('integration tests', () => { street: '123 Main St' }); - const updatedUserResponse = await xata.db.users.update(user.id, { street: 'New street', zipcode: 11 }); + const updatedUserResponse = await xata.db.users.update(user.xata_id, { street: 'New street', zipcode: 11 }); - const updatedUser = await xata.db.users.filter({ id: user.id }).getFirst(); + const updatedUser = await xata.db.users.filter({ xata_id: user.xata_id }).getFirst(); if (!updatedUser) throw new Error('No user found'); await user.delete(); - expect(user.id).toBe(updatedUser.id); + expect(user.xata_id).toBe(updatedUser.xata_id); expect(user.street).toBe('123 Main St'); expect(user.zipcode).toBeNull(); @@ -550,7 +549,7 @@ describe('integration tests', () => { const updatedUserResponse = await user.update({ street: 'New street 2', zipcode: 22 }); - const updatedUser = await xata.db.users.filter({ id: user.id }).getFirst(); + const updatedUser = await xata.db.users.filter({ xata_id: user.xata_id }).getFirst(); if (!updatedUser) throw new Error('No user found'); await user.delete(); @@ -572,15 +571,15 @@ describe('integration tests', () => { email: 'john6@doe.com' }); - const apiUser = await xata.db.users.filter({ id: user.id }).getFirst(); + const apiUser = await xata.db.users.filter({ xata_id: user.xata_id }).getFirst(); if (!apiUser) throw new Error('No user found'); await user.delete(); - expect(user.id).toBe('my-good-old-john-6'); + expect(user.xata_id).toBe('my-good-old-john-6'); expect(user.full_name).toBe('John Doe 6'); - expect(user.id).toBe(apiUser.id); + expect(user.xata_id).toBe(apiUser.xata_id); expect(user.full_name).toBe(apiUser.full_name); expect(user.email).toBe(apiUser.email); }); @@ -610,18 +609,10 @@ describe('integration tests', () => { }); test('Pagination default value', async () => { - await api.table.createTable({ - pathParams: { workspace, region, dbBranchName: `${database}:main`, tableName: 'planes' } - }); - await api.table.setTableSchema({ - pathParams: { workspace, region, dbBranchName: `${database}:main`, tableName: 'planes' }, - body: { columns: [{ name: 'name', type: 'string' }] } - }); - const planes = Array.from({ length: PAGINATION_DEFAULT_SIZE + 50 }, (_, index) => ({ name: `Plane ${index}` })); - const createdPlanes = await baseClient.db.planes.create(planes); - const queriedPlanes = await baseClient.db.planes.getPaginated(); + const createdPlanes = await xata.db.users.create(planes); + const queriedPlanes = await xata.db.users.filter({ name: { $startsWith: 'Plane' } }).getPaginated(); expect(createdPlanes).toHaveLength(PAGINATION_DEFAULT_SIZE + 50); expect(queriedPlanes.records).toHaveLength(PAGINATION_DEFAULT_SIZE); @@ -646,38 +637,26 @@ describe('integration tests', () => { await user.update({ team }); const updatedUser = await user.read(); - expect(updatedUser?.team?.id).toEqual(team.id); + expect(updatedUser?.team?.xata_id).toEqual(team.xata_id); - // TODO(link.xata) @ts-expect-error - expect(updatedUser?.team?.xata?.version).not.toBeDefined(); - // TODO(link.xata) @ts-expect-error - expect(updatedUser?.team?.xata?.createdAt).not.toBeDefined(); - // TODO(link.xata) @ts-expect-error - expect(updatedUser?.team?.xata?.updatedAt).not.toBeDefined(); - - const response = await xata.db.teams.getFirst({ filter: { id: team.id }, columns: ['*', 'owner.*'] }); + const response = await xata.db.teams.getFirst({ filter: { xata_id: team.xata_id }, columns: ['*', 'owner.*'] }); const owner = await response?.owner?.read(); - expect(response?.owner?.id).toBeDefined(); + expect(response?.owner?.xata_id).toBeDefined(); expect(response?.owner?.full_name).toBeDefined(); - expect(owner?.id).toBeDefined(); + expect(owner?.xata_id).toBeDefined(); expect(owner?.full_name).toBeDefined(); - expect(response?.owner?.id).toBe(owner?.id); + expect(response?.owner?.xata_id).toBe(owner?.xata_id); expect(response?.owner?.full_name).toBe(owner?.full_name); - const teamMetadata = response?.owner?.getMetadata(); - expect(teamMetadata?.createdAt).toBeInstanceOf(Date); - expect(teamMetadata?.updatedAt).toBeInstanceOf(Date); - expect(teamMetadata?.version).toBe(1); - - expect(response?.owner?.xata?.createdAt).toBeInstanceOf(Date); - expect(response?.owner?.xata?.updatedAt).toBeInstanceOf(Date); - expect(response?.owner?.xata?.version).toBe(1); + expect(response?.owner?.xata_createdat).toBeInstanceOf(Date); + expect(response?.owner?.xata_updatedat).toBeInstanceOf(Date); + expect(response?.owner?.xata_version).toBe(1); const nestedObject = await xata.db.teams.getFirst({ - filter: { id: team.id }, + filter: { xata_id: team.xata_id }, columns: ['owner.team', 'owner.full_name'] }); @@ -686,14 +665,13 @@ describe('integration tests', () => { expect(nestedName).toEqual(user.full_name); - expect(isXataRecord(nestedProperty)).toBe(true); expect(nestedProperty?.name).toEqual(team.name); // @ts-expect-error expect(nestedProperty?.owner?.full_name).not.toBeDefined(); const nestedRead = await nestedProperty?.owner?.read(); - expect(nestedRead?.id).toBeDefined(); + expect(nestedRead?.xata_id).toBeDefined(); expect(nestedRead?.full_name).toEqual(user.full_name); }); @@ -704,51 +682,51 @@ describe('integration tests', () => { const team = await xata.db.teams.create({ name: 'Example Team', owner }); const updated = await team.update({ owner: owner2 }); - expect(team.owner?.id).toEqual(owner.id); - expect(updated?.owner?.id).toEqual(owner2.id); + expect(team.owner?.xata_id).toEqual(owner.xata_id); + expect(updated?.owner?.xata_id).toEqual(owner2.xata_id); }); test('Update link with linked object (string)', async () => { const owner = await xata.db.users.create({ full_name: 'Example User' }); const owner2 = await xata.db.users.create({ full_name: 'Example User 2' }); - const team = await xata.db.teams.create({ name: 'Example Team', owner: owner.id }); - const updated = await team.update({ owner: owner2.id }); + const team = await xata.db.teams.create({ name: 'Example Team', owner: owner.xata_id }); + const updated = await team.update({ owner: owner2.xata_id }); - expect(team.owner?.id).toEqual(owner.id); - expect(updated?.owner?.id).toEqual(owner2.id); + expect(team.owner?.xata_id).toEqual(owner.xata_id); + expect(updated?.owner?.xata_id).toEqual(owner2.xata_id); }); test('Filter with null value', async () => { const newOwner = await xata.db.users.create({ full_name: 'Example User' }); const newTeam = await xata.db.teams.create({ name: 'Example Team', owner: newOwner }); - const owner = await xata.db.users.filter({ id: newOwner.id }).getFirst(); + const owner = await xata.db.users.filter({ xata_id: newOwner.xata_id }).getFirst(); if (!owner) throw new Error('No user found'); - const team = await xata.db.teams.filter({ owner }).getFirst(); - expect(team?.id).toEqual(newTeam.id); + const team = await xata.db.teams.filter({ owner: owner.xata_id }).getFirst(); + expect(team?.xata_id).toEqual(newTeam.xata_id); }); test('Filter with multiple column', async () => { const newTeam = await xata.db.teams.create({ name: 'Example Team', labels: ['a', 'b'] }); const team = await xata.db.teams.filter({ labels: newTeam.labels }).getFirst(); - expect(team?.id).toEqual(newTeam.id); + expect(team?.xata_id).toEqual(newTeam.xata_id); }); test('Partial filters should work', async () => { const newTeam = await xata.db.teams.create({ name: 'A random real team', labels: ['a', 'b'] }); const maybeId = undefined; - const records = await xata.db.teams.filter({ id: maybeId, name: newTeam.name }).getMany(); + const records = await xata.db.teams.filter({ xata_id: maybeId, name: newTeam.name }).getMany(); expect(records).toHaveLength(1); - expect(records[0].id).toEqual(newTeam.id); + expect(records[0].xata_id).toEqual(newTeam.xata_id); const serialized = records.toSerializable(); expect(serialized).toHaveLength(1); - expect(serialized[0].id).toEqual(newTeam.id); + expect(serialized[0].xata_id).toEqual(newTeam.xata_id); const string = records.toString(); expect(string).toContain('A random real team'); diff --git a/test/integration/read.test.ts b/test/integration/read.test.ts index f3ce676b9..f7a63c3fd 100644 --- a/test/integration/read.test.ts +++ b/test/integration/read.test.ts @@ -30,16 +30,16 @@ describe('record read', () => { test('read single team with id', async () => { const team = await xata.db.teams.create({ name: 'Team ships' }); - const copy = await xata.db.teams.read(team.id); - const definedCopy = await xata.db.teams.readOrThrow(team.id); + const copy = await xata.db.teams.read(team.xata_id); + const definedCopy = await xata.db.teams.readOrThrow(team.xata_id); expect(copy).toBeDefined(); - expect(copy?.id).toBe(team.id); - expect(copy?.xata.createdAt).toBeInstanceOf(Date); + expect(copy?.xata_id).toBe(team.xata_id); + expect(copy?.xata_createdat).toBeInstanceOf(Date); expect(definedCopy).toBeDefined(); - expect(definedCopy.id).toBe(team.id); - expect(definedCopy.xata.createdAt).toBeInstanceOf(Date); + expect(definedCopy.xata_id).toBe(team.xata_id); + expect(definedCopy.xata_createdat).toBeInstanceOf(Date); }); test('read multiple teams ', async () => { @@ -49,27 +49,27 @@ describe('record read', () => { const definedCopies = await xata.db.teams.readOrThrow(teams); expect(copies).toHaveLength(2); - expect(copies[0]?.id).toBe(teams[0].id); - expect(copies[1]?.id).toBe(teams[1].id); + expect(copies[0]?.xata_id).toBe(teams[0].xata_id); + expect(copies[1]?.xata_id).toBe(teams[1].xata_id); expect(definedCopies).toHaveLength(2); - expect(definedCopies[0].id).toBe(teams[0].id); - expect(definedCopies[1].id).toBe(teams[1].id); + expect(definedCopies[0].xata_id).toBe(teams[0].xata_id); + expect(definedCopies[1].xata_id).toBe(teams[1].xata_id); }); test('read multiple teams with id list', async () => { const teams = await xata.db.teams.create([{ name: 'Team cars' }, { name: 'Team planes' }]); - const copies = await xata.db.teams.read(teams.map((team) => team.id)); - const definedCopies = await xata.db.teams.readOrThrow(teams.map((team) => team.id)); + const copies = await xata.db.teams.read(teams.map((team) => team.xata_id)); + const definedCopies = await xata.db.teams.readOrThrow(teams.map((team) => team.xata_id)); expect(copies).toHaveLength(2); - expect(copies[0]?.id).toBe(teams[0].id); - expect(copies[1]?.id).toBe(teams[1].id); + expect(copies[0]?.xata_id).toBe(teams[0].xata_id); + expect(copies[1]?.xata_id).toBe(teams[1].xata_id); expect(definedCopies).toHaveLength(2); - expect(definedCopies[0].id).toBe(teams[0].id); - expect(definedCopies[1].id).toBe(teams[1].id); + expect(definedCopies[0].xata_id).toBe(teams[0].xata_id); + expect(definedCopies[1].xata_id).toBe(teams[1].xata_id); }); test("read single and return null if team doesn't exist", async () => { @@ -84,17 +84,17 @@ describe('record read', () => { test("read multiple teams with id list and ignores a team if doesn't exist", async () => { const teams = await xata.db.teams.create([{ name: 'Team cars' }, { name: 'Team planes' }]); - const copies = await xata.db.teams.read(teams.map((team) => team.id).concat(['does-not-exist'])); + const copies = await xata.db.teams.read(teams.map((team) => team.xata_id).concat(['does-not-exist'])); expect(copies).toHaveLength(3); - expect(copies[0]?.id).toBe(teams[0].id); - expect(copies[1]?.id).toBe(teams[1].id); + expect(copies[0]?.xata_id).toBe(teams[0].xata_id); + expect(copies[1]?.xata_id).toBe(teams[1].xata_id); expect(copies[2]).toBeNull(); }); test("read multiple teams with id list and throws if a team doesn't exist", async () => { const teams = await xata.db.teams.create([{ name: 'Team cars' }, { name: 'Team planes' }]); - expect(xata.db.teams.readOrThrow(teams.map((team) => team.id).concat(['does-not-exist']))).rejects.toThrow(); + expect(xata.db.teams.readOrThrow(teams.map((team) => team.xata_id).concat(['does-not-exist']))).rejects.toThrow(); }); test('read multiple with empty array', async () => { @@ -138,15 +138,15 @@ describe('record read', () => { const owner = await xata.db.users.create({ full_name: 'John', street: 'Newark' }); const team = await xata.db.teams.create({ name: 'Team ships', labels: ['foo', 'bar'], owner }); - const copy = await xata.db.teams.read(team.id, ['id', 'name', 'owner.street']); + const copy = await xata.db.teams.read(team.xata_id, ['xata_id', 'name', 'owner.street']); expect(copy).toBeDefined(); - expect(copy?.id).toBe(team.id); + expect(copy?.xata_id).toBe(team.xata_id); expect(copy?.name).toBe(team.name); // @ts-expect-error expect(copy?.labels).not.toBeDefined(); expect(copy?.owner).toBeDefined(); - expect(copy?.owner?.id).toBe(owner.id); + expect(copy?.owner?.xata_id).toBe(owner.xata_id); expect(copy?.owner?.street).toBe(owner.street); // @ts-expect-error expect(copy?.owner?.city).not.toBeDefined(); @@ -162,7 +162,7 @@ describe('record read', () => { const replacedTeam = await team.replace({ name: 'Team boats' }); - expect(replacedTeam?.id).toBe(team.id); + expect(replacedTeam?.xata_id).toBe(team.xata_id); expect(replacedTeam?.read).toBeDefined(); expect(replacedTeam?.email).toBeNull(); }); diff --git a/test/integration/revlinks.test.ts b/test/integration/revlinks.test.ts index dd29a3f31..b72065686 100644 --- a/test/integration/revlinks.test.ts +++ b/test/integration/revlinks.test.ts @@ -31,7 +31,7 @@ describe('Revlinks', () => { const user = await xata.db.users.create({ name: 'test' }); const team = await xata.db.teams.create({ name: 'test', owner: user }); - expect(team.owner?.id).toBe(user.id); + expect(team.owner?.xata_id).toBe(user.xata_id); const records = await xata.db.users .select([ @@ -50,7 +50,7 @@ describe('Revlinks', () => { expect(records[0]?.ownerTeams?.records).toHaveLength(1); expect(records[0]?.ownerTeams?.records[0]?.name).toBe(team.name); - await xata.db.users.delete(user.id); - await xata.db.teams.delete(team.id); + await xata.db.teams.delete(team.xata_id); + await xata.db.users.delete(user.xata_id); }); }); diff --git a/test/integration/search.test.ts b/test/integration/search.test.ts index a22677bdb..ef51b8f3b 100644 --- a/test/integration/search.test.ts +++ b/test/integration/search.test.ts @@ -28,12 +28,12 @@ beforeAll(async (ctx) => { { name: 'Team fruits', labels: ['apple', 'banana', 'orange'], - owner: ownerFruits + owner: ownerFruits as any }, { name: 'Team animals', labels: ['monkey', 'lion', 'eagle', 'dolphin'], - owner: ownerAnimals + owner: ownerAnimals as any }, { name: 'Mixed team fruits & animals', @@ -67,11 +67,11 @@ describe( expect(records.length).toBeGreaterThan(0); expect(records.length).toBe(2); - expect(records[0].id).toBeDefined(); + expect(records[0].xata_id).toBeDefined(); expect(records[0].full_name?.includes('Owner')).toBeTruthy(); expect(records[0].read).toBeDefined(); - expect(records[0].getMetadata().score).toBeDefined(); - expect(records[0].getMetadata().table).toBe('users'); + expect(records[0].xata_score).toBeDefined(); + expect(records[0].xata_table).toBe('users'); }); test('search in table with filtering', async () => { @@ -81,10 +81,10 @@ describe( expect(totalCount).toBe(1); expect(records.length).toBe(1); - expect(records[0].id).toBeDefined(); + expect(records[0].xata_id).toBeDefined(); expect(records[0].full_name?.includes('Owner of team animals')).toBeTruthy(); expect(records[0].read).toBeDefined(); - expect(records[0].getMetadata().score).toBeDefined(); + expect(records[0].xata_score).toBeDefined(); }); test('search by tables with multiple tables', async () => { @@ -97,15 +97,15 @@ describe( expect(users.length).toBeGreaterThan(0); expect(teams.length).toBeGreaterThan(0); - expect(users[0].id).toBeDefined(); + expect(users[0].xata_id).toBeDefined(); expect(users[0].read).toBeDefined(); expect(users[0].full_name?.includes('fruits')).toBeTruthy(); - expect(users[0].getMetadata().score).toBeDefined(); + expect(users[0].xata_score).toBeDefined(); - expect(teams[0].id).toBeDefined(); + expect(teams[0].xata_id).toBeDefined(); expect(teams[0].read).toBeDefined(); expect(teams[0].name?.includes('fruits')).toBeTruthy(); - expect(users[0].getMetadata().score).toBeDefined(); + expect(users[0].xata_score).toBeDefined(); }); test('search by table with all tables', async () => { @@ -118,15 +118,15 @@ describe( expect(users.length).toBeGreaterThan(0); expect(teams.length).toBeGreaterThan(0); - expect(users[0].id).toBeDefined(); + expect(users[0].xata_id).toBeDefined(); expect(users[0].read).toBeDefined(); expect(users[0].full_name?.includes('fruits')).toBeTruthy(); - expect(users[0].getMetadata().score).toBeDefined(); + expect(users[0].xata_score).toBeDefined(); - expect(teams[0].id).toBeDefined(); + expect(teams[0].xata_id).toBeDefined(); expect(teams[0].read).toBeDefined(); expect(teams[0].name?.includes('fruits')).toBeTruthy(); - expect(teams[0].getMetadata().score).toBeDefined(); + expect(teams[0].xata_score).toBeDefined(); }); test('search all with multiple tables', async () => { @@ -136,17 +136,17 @@ describe( expect(totalCount).toBeGreaterThan(0); for (const result of records) { if (result.table === 'teams') { - expect(result.record.id).toBeDefined(); + expect(result.record.xata_id).toBeDefined(); expect(result.record.read).toBeDefined(); expect(result.record.name?.includes('fruits')).toBeTruthy(); - expect(result.record.getMetadata().score).toBeDefined(); - expect(result.record.getMetadata().table).toBe('teams'); + expect(result.record.xata_score).toBeDefined(); + expect(result.record.xata_table).toBe('teams'); } else { - expect(result.record.id).toBeDefined(); + expect(result.record.xata_id).toBeDefined(); expect(result.record.read).toBeDefined(); expect(result.record.full_name?.includes('fruits')).toBeTruthy(); - expect(result.record.getMetadata().table).toBe('users'); - expect(result.record.getMetadata().score).toBeDefined(); + expect(result.record.xata_table).toBe('users'); + expect(result.record.xata_score).toBeDefined(); } } }); @@ -157,10 +157,10 @@ describe( expect(totalCount).toBeGreaterThan(0); for (const result of records) { - expect(result.record.id).toBeDefined(); + expect(result.record.xata_id).toBeDefined(); expect(result.record.read).toBeDefined(); expect(result.record.name?.includes('fruits')).toBeTruthy(); - expect(result.record.getMetadata().score).toBeDefined(); + expect(result.record.xata_score).toBeDefined(); //@ts-expect-error result.table === 'users'; @@ -174,20 +174,20 @@ describe( expect(totalCount).toBeGreaterThan(0); for (const result of records) { if (result.table === 'teams') { - expect(result.record.id).toBeDefined(); + expect(result.record.xata_id).toBeDefined(); expect(result.record.read).toBeDefined(); expect(result.record.name?.includes('fruits')).toBeTruthy(); - expect(result.record.getMetadata().score).toBeDefined(); + expect(result.record.xata_score).toBeDefined(); } else if (result.table === 'users') { - expect(result.record.id).toBeDefined(); + expect(result.record.xata_id).toBeDefined(); expect(result.record.read).toBeDefined(); expect(result.record.full_name?.includes('fruits')).toBeTruthy(); - expect(result.record.getMetadata().score).toBeDefined(); + expect(result.record.xata_score).toBeDefined(); } else if (result.table === 'pets') { - expect(result.record.id).toBeDefined(); + expect(result.record.xata_id).toBeDefined(); expect(result.record.read).toBeDefined(); expect(result.record.name?.includes('fruits')).toBeTruthy(); - expect(result.record.getMetadata().score).toBeDefined(); + expect(result.record.xata_score).toBeDefined(); } } }); @@ -203,11 +203,11 @@ describe( expect(records[0].table).toBe('teams'); if (records[0].table === 'teams') { - expect(records[0].record.id).toBeDefined(); + expect(records[0].record.xata_id).toBeDefined(); expect(records[0].record.read).toBeDefined(); expect(records[0].record.name?.includes('fruits')).toBeTruthy(); - expect(records[0].record.getMetadata().score).toBeDefined(); - expect(records[0].record.xata.highlight).toBeDefined(); + expect(records[0].record.xata_score).toBeDefined(); + expect(records[0].record.xata_highlight).toBeDefined(); } }); @@ -224,10 +224,10 @@ describe( expect(page1.length).toBe(1); expect(page2.length).toBe(1); - expect(page1[0].id).not.toBe(page2[0].id); + expect(page1[0].xata_id).not.toBe(page2[0].xata_id); - expect(page1[0].id).toBe(owners[0].id); - expect(page2[0].id).toBe(owners[1].id); + expect(page1[0].xata_id).toBe(owners[0].xata_id); + expect(page2[0].xata_id).toBe(owners[1].xata_id); }); test('global search with page and offset', async () => { @@ -252,10 +252,10 @@ describe( expect(page1.length).toBe(1); expect(page2.length).toBe(1); - expect(page1[0].id).not.toBe(page2[0].id); + expect(page1[0].xata_id).not.toBe(page2[0].xata_id); - expect(page1[0].id).toBe(owners[0].id); - expect(page2[0].id).toBe(owners[1].id); + expect(page1[0].xata_id).toBe(owners[0].xata_id); + expect(page2[0].xata_id).toBe(owners[1].xata_id); }); }, { retry: 5 } diff --git a/test/integration/smoke.test.ts b/test/integration/smoke.test.ts index f7f2d59c6..c4bd0ecee 100644 --- a/test/integration/smoke.test.ts +++ b/test/integration/smoke.test.ts @@ -73,18 +73,21 @@ describe('API Client Integration Tests', () => { console.log('Created branch, table and schema'); - const { id } = await newApi.records.insertRecord({ + const response = await newApi.records.insertRecord({ pathParams: { workspace, region, dbBranchName: `${database}:branch`, tableName: 'table' }, body: { email: 'example@foo.bar' } }); + // @ts-expect-error Remove this once pgroll is normalized + const id = response.xata_id; + console.log('Created record', id); const record = await newApi.records.getRecord({ pathParams: { workspace, region, dbBranchName: `${database}:branch`, tableName: 'table', recordId: id } }); - expect(record.id).toBeDefined(); + expect(record.xata_id).toBeDefined(); expect(record.email).toEqual('example@foo.bar'); await waitForSearchIndexing(newApi, workspace, database); @@ -95,7 +98,7 @@ describe('API Client Integration Tests', () => { }); expect(search.totalCount).toEqual(1); - expect(search.records[0].id).toEqual(id); + expect(search.records[0].xata_id).toEqual(id); const failedSearch = await newApi.searchAndFilter.searchTable({ pathParams: { workspace, region, dbBranchName: `${database}:branch`, tableName: 'table' }, diff --git a/test/integration/sql.test.ts b/test/integration/sql.test.ts index 0bed97768..60f6deb07 100644 --- a/test/integration/sql.test.ts +++ b/test/integration/sql.test.ts @@ -30,29 +30,14 @@ describe('SQL proxy', () => { test.skip('read single team with id', async () => { const team = await xata.db.teams.create({ name: 'Team ships' }); - const { records, warning, columns } = await xata.sql`SELECT * FROM teams WHERE id = ${team.id}`; + const { records, warning, columns } = + await xata.sql`SELECT * FROM teams WHERE xata_id = ${team.xata_id}`; expect(warning).toBeUndefined(); expect(records).toHaveLength(1); expect(columns).toMatchInlineSnapshot(` [ - { - "name": "id", - "type": "text", - }, - { - "name": "xata.version", - "type": "int4", - }, - { - "name": "xata.createdAt", - "type": "timestamptz", - }, - { - "name": "xata.updatedAt", - "type": "timestamptz", - }, { "name": "name", "type": "text", @@ -67,7 +52,7 @@ describe('SQL proxy', () => { }, { "name": "index", - "type": "int8", + "type": "int4", }, { "name": "rating", @@ -93,6 +78,22 @@ describe('SQL proxy', () => { "name": "config", "type": "jsonb", }, + { + "name": "xata_id", + "type": "text", + }, + { + "name": "xata_version", + "type": "int4", + }, + { + "name": "xata_createdat", + "type": "timestamptz", + }, + { + "name": "xata_updatedat", + "type": "timestamptz", + }, { "name": "owner", "type": "text", @@ -100,7 +101,7 @@ describe('SQL proxy', () => { ] `); - expect(records[0].id).toBe(team.id); + expect(records[0].xata_id).toBe(team.xata_id); expect(records[0].name).toBe('Team ships'); }); @@ -114,22 +115,6 @@ describe('SQL proxy', () => { expect(columns).toMatchInlineSnapshot(` [ - { - "name": "id", - "type": "text", - }, - { - "name": "xata.version", - "type": "int4", - }, - { - "name": "xata.createdAt", - "type": "timestamptz", - }, - { - "name": "xata.updatedAt", - "type": "timestamptz", - }, { "name": "name", "type": "text", @@ -144,7 +129,7 @@ describe('SQL proxy', () => { }, { "name": "index", - "type": "int8", + "type": "int4", }, { "name": "rating", @@ -170,6 +155,22 @@ describe('SQL proxy', () => { "name": "config", "type": "jsonb", }, + { + "name": "xata_id", + "type": "text", + }, + { + "name": "xata_version", + "type": "int4", + }, + { + "name": "xata_createdat", + "type": "timestamptz", + }, + { + "name": "xata_updatedat", + "type": "timestamptz", + }, { "name": "owner", "type": "text", @@ -177,8 +178,8 @@ describe('SQL proxy', () => { ] `); - const record1 = records.find((record) => record.id === teams[0].id); - const record2 = records.find((record) => record.id === teams[1].id); + const record1 = records.find((record) => record.xata_id === teams[0].xata_id); + const record2 = records.find((record) => record.xata_id === teams[1].xata_id); expect(record1).toBeDefined(); expect(record1?.name).toBe('[A] Cars'); @@ -188,28 +189,12 @@ describe('SQL proxy', () => { test.skip('create team', async () => { const { records, warning, columns } = await xata.sql({ - statement: `INSERT INTO teams (name) VALUES ($1) RETURNING *`, - params: ['Team ships 2'] + statement: `INSERT INTO teams (xata_id, name) VALUES ($1, $2) RETURNING *`, + params: ['my-id', 'Team ships 2'] }); expect(columns).toMatchInlineSnapshot(` [ - { - "name": "id", - "type": "text", - }, - { - "name": "xata.version", - "type": "int4", - }, - { - "name": "xata.createdAt", - "type": "timestamptz", - }, - { - "name": "xata.updatedAt", - "type": "timestamptz", - }, { "name": "name", "type": "text", @@ -224,7 +209,7 @@ describe('SQL proxy', () => { }, { "name": "index", - "type": "int8", + "type": "int4", }, { "name": "rating", @@ -250,6 +235,22 @@ describe('SQL proxy', () => { "name": "config", "type": "jsonb", }, + { + "name": "xata_id", + "type": "text", + }, + { + "name": "xata_version", + "type": "int4", + }, + { + "name": "xata_createdat", + "type": "timestamptz", + }, + { + "name": "xata_updatedat", + "type": "timestamptz", + }, { "name": "owner", "type": "text", @@ -261,7 +262,7 @@ describe('SQL proxy', () => { expect(records).toHaveLength(1); expect(records[0].name).toBe('Team ships 2'); - const team = await xata.db.teams.read(records[0].id); + const team = await xata.db.teams.read(records[0].xata_id); expect(team).toBeDefined(); expect(team?.name).toBe('Team ships 2'); }); diff --git a/test/integration/summarize.test.ts b/test/integration/summarize.test.ts index cc999ee37..0538d05f7 100644 --- a/test/integration/summarize.test.ts +++ b/test/integration/summarize.test.ts @@ -27,11 +27,11 @@ beforeAll(async (ctx) => { rating: 10.5, plan: 'paid', dark: true, - pet: pet1.id, + pet: pet1.xata_id, account_value: 5 }, - { full_name: 'B', name: 'B', index: 10, rating: 10.5, plan: 'free', pet: pet2.id, account_value: 3 }, - { full_name: 'C', name: 'C', index: 30, rating: 40.0, plan: 'paid', pet: pet3.id } + { full_name: 'B', name: 'B', index: 10, rating: 10.5, plan: 'free', pet: pet2.xata_id, account_value: 3 }, + { full_name: 'C', name: 'C', index: 30, rating: 40.0, plan: 'paid', pet: pet3.xata_id } ]); }); @@ -426,7 +426,7 @@ describe('summarize', () => { const result = await xata.db.users.summarize({ columns: ['name'], summaries: { total: { count: '*' } }, - filter: { id: 'nomatches' } + filter: { xata_id: 'nomatches' } }); expect(result.summaries).toMatchInlineSnapshot('[]'); @@ -440,7 +440,7 @@ describe('summarize', () => { const result = await xata.db.users.summarize({ columns: ['name'], summaries: { total: { count: '*' } }, - filter: { id: user1?.id ?? '' } + filter: { xata_id: user1?.xata_id ?? '' } }); expect(result.summaries).toMatchInlineSnapshot(` diff --git a/test/integration/transactions.test.ts b/test/integration/transactions.test.ts index 71cf03456..d7e670590 100644 --- a/test/integration/transactions.test.ts +++ b/test/integration/transactions.test.ts @@ -38,7 +38,7 @@ describe('insert transactions', () => { expect(response.results).toEqual([{ operation: 'insert', id: expect.any(String), rows: 1 }]); - await xata.db.teams.delete({ id: response.results[0]?.id }); + await xata.db.teams.delete({ xata_id: response.results[0]?.id }); }); test('insert by ID', async () => { @@ -46,7 +46,7 @@ describe('insert transactions', () => { expect(response.results).toEqual([{ operation: 'insert', id: 'i0', rows: 1, columns: {} }]); - await xata.db.teams.delete({ id: 'i0' }); + await xata.db.teams.delete({ xata_id: 'i0' }); }); test('insert with createOnly and explicit ID', async () => { @@ -56,7 +56,7 @@ describe('insert transactions', () => { expect(response.results).toEqual([{ operation: 'insert', id: 'i0', rows: 1 }]); - await xata.db.teams.delete({ id: 'i0' }); + await xata.db.teams.delete({ xata_id: 'i0' }); }); test('replace existing record if createOnly is unset', async () => { @@ -67,7 +67,7 @@ describe('insert transactions', () => { expect(response.results).toEqual([{ operation: 'insert', id: 'i0', rows: 1, columns: {} }]); - await xata.db.teams.delete({ id: 'i0' }); + await xata.db.teams.delete({ xata_id: 'i0' }); }); test('replace existing record if createOnly is false', async () => { @@ -78,7 +78,7 @@ describe('insert transactions', () => { expect(response.results).toEqual([{ operation: 'insert', id: 'i0', rows: 1, columns: {} }]); - await xata.db.teams.delete({ id: 'i0' }); + await xata.db.teams.delete({ xata_id: 'i0' }); }); test('replace when ifVersion set', async () => { @@ -90,7 +90,7 @@ describe('insert transactions', () => { expect(response.results).toEqual([{ operation: 'insert', id: 'i0', rows: 1, columns: {} }]); - await xata.db.teams.delete({ id: 'i0' }); + await xata.db.teams.delete({ xata_id: 'i0' }); }); test('mix of operations', async () => { @@ -110,10 +110,10 @@ describe('insert transactions', () => { { operation: 'insert', id: 'j0', rows: 1, columns: {} } ]); - await xata.db.teams.delete({ id: response.results[0]?.id }); - await xata.db.teams.delete({ id: 'i1' }); - await xata.db.users.delete({ id: 'j1' }); - await xata.db.users.delete({ id: 'j0' }); + await xata.db.teams.delete({ xata_id: response.results[0]?.id }); + await xata.db.teams.delete({ xata_id: 'i1' }); + await xata.db.users.delete({ xata_id: 'j1' }); + await xata.db.users.delete({ xata_id: 'j0' }); }); }); @@ -317,9 +317,9 @@ describe('combined transactions', () => { { update: { table: 'teams', id: 'i2', fields: { name: 'c1' } } }, { update: { table: 'teams', id: 'i2', fields: { name: 'c1.1' } } }, { delete: { table: 'teams', id: 'i3' } }, - { get: { table: 'teams', id: 'i0', columns: ['id', 'index', 'name'] } }, - { get: { table: 'teams', id: 'i1', columns: ['id', 'index', 'name'] } }, - { get: { table: 'teams', id: 'i2', columns: ['id', 'index', 'name'] } } + { get: { table: 'teams', id: 'i0', columns: ['xata_id', 'index', 'name'] } }, + { get: { table: 'teams', id: 'i1', columns: ['xata_id', 'index', 'name'] } }, + { get: { table: 'teams', id: 'i2', columns: ['xata_id', 'index', 'name'] } } ]); expect(response.results).toEqual([ @@ -329,9 +329,9 @@ describe('combined transactions', () => { { operation: 'update', id: 'i2', rows: 1, columns: {} }, { operation: 'update', id: 'i2', rows: 1, columns: {} }, { operation: 'delete', rows: 1 }, - { operation: 'get', columns: { id: 'i0', name: 'a1', index: 0 } }, - { operation: 'get', columns: { id: 'i1', name: 'b1', index: 1 } }, - { operation: 'get', columns: { id: 'i2', name: 'c1.1', index: 2 } } + { operation: 'get', columns: { xata_id: 'i0', name: 'a1', index: 0 } }, + { operation: 'get', columns: { xata_id: 'i1', name: 'b1', index: 1 } }, + { operation: 'get', columns: { xata_id: 'i2', name: 'c1.1', index: 2 } } ]); const records = await xata.db.teams.read(['i0', 'i1', 'i2']); diff --git a/test/integration/update.test.ts b/test/integration/update.test.ts index 80747e46f..398a6694d 100644 --- a/test/integration/update.test.ts +++ b/test/integration/update.test.ts @@ -30,11 +30,11 @@ describe('record update', () => { test('update single team', async () => { const team = await xata.db.teams.create({ name: 'Team ships' }); - const updatedTeam = await xata.db.teams.update(team.id, { name: 'Team boats' }); + const updatedTeam = await xata.db.teams.update(team.xata_id, { name: 'Team boats' }); - expect(updatedTeam?.id).toBe(team.id); + expect(updatedTeam?.xata_id).toBe(team.xata_id); - const apiTeam = await xata.db.teams.filter({ id: team.id }).getFirst(); + const apiTeam = await xata.db.teams.filter({ xata_id: team.xata_id }).getFirst(); if (!apiTeam) throw new Error('No team found'); expect(updatedTeam?.name).toBe('Team boats'); @@ -48,7 +48,7 @@ describe('record update', () => { expect(updatedTeams).toHaveLength(2); - const apiTeams = await xata.db.teams.filter({ $any: teams.map((t) => ({ id: t.id })) }).getAll(); + const apiTeams = await xata.db.teams.filter({ $any: teams.map((t) => ({ xata_id: t.xata_id })) }).getAll(); expect(apiTeams).toHaveLength(2); expect(apiTeams[0].name).toBe('Team boats'); @@ -58,11 +58,11 @@ describe('record update', () => { test('update team with inline id', async () => { const team = await xata.db.teams.create({ name: 'Team ships' }); - const updatedTeam = await xata.db.teams.update({ id: team.id, name: 'Team boats' }); + const updatedTeam = await xata.db.teams.update({ xata_id: team.xata_id, name: 'Team boats' }); - expect(updatedTeam?.id).toBe(team.id); + expect(updatedTeam?.xata_id).toBe(team.xata_id); - const apiTeam = await xata.db.teams.filter({ id: team.id }).getFirst(); + const apiTeam = await xata.db.teams.filter({ xata_id: team.xata_id }).getFirst(); expect(updatedTeam?.name).toBe('Team boats'); expect(apiTeam?.name).toBe('Team boats'); @@ -77,92 +77,91 @@ describe('record update', () => { const valid = await xata.db.teams.create({ name: 'Team ships' }); const team1 = await xata.db.teams.update('invalid', { name: 'Team boats' }); - const team2 = await xata.db.teams.update({ id: 'invalid', name: 'Team boats' }); + const team2 = await xata.db.teams.update({ xata_id: 'invalid', name: 'Team boats' }); const team3 = await xata.db.teams.update([ - { id: 'invalid', name: 'Team boats' }, - { id: valid.id, name: 'Team boats 2' } + { xata_id: 'invalid', name: 'Team boats' }, + { xata_id: valid.xata_id, name: 'Team boats 2' } ]); expect(team1).toBeNull(); expect(team2).toBeNull(); expect(team3[0]).toBeNull(); expect(team3[1]).toBeDefined(); - expect(team3[1]?.id).toBe(valid.id); + expect(team3[1]?.xata_id).toBe(valid.xata_id); expect(team3[1]?.name).toBe('Team boats 2'); }); test('update item with if version', async () => { const team = await xata.db.teams.create({ name: 'Team ships' }); - const { version: versionA } = team.getMetadata(); + const baseVersion = team.xata_version; - const updatedTeam = await xata.db.teams.update(team.id, { name: 'Team boats' }, { ifVersion: versionA }); - const { version: versionB } = updatedTeam?.getMetadata() || {}; + const updatedTeam = await xata.db.teams.update(team.xata_id, { name: 'Team boats' }, { ifVersion: baseVersion }); - expect(updatedTeam?.id).toBe(team.id); - expect(versionB).toBe(versionA + 1); + expect(updatedTeam?.xata_id).toBe(team.xata_id); + expect(updatedTeam?.xata_version).toBe(baseVersion + 1); - const updatedTeam2 = await xata.db.teams.update(team.id, { name: 'Team planes' }, { ifVersion: versionA }); - const { version: versionC } = updatedTeam2?.getMetadata() || {}; + const updatedTeam2 = await xata.db.teams.update(team.xata_id, { name: 'Team planes' }, { ifVersion: baseVersion }); expect(updatedTeam2).toBeNull(); - expect(versionC).toBe(undefined); + expect(updatedTeam2?.xata_version).toBe(undefined); - const updatedTeam3 = await team.update({ name: 'Team cars' }, { ifVersion: versionA }); - const { version: versionD } = updatedTeam3?.getMetadata() || {}; + const updatedTeam3 = await team.update({ name: 'Team cars' }, { ifVersion: baseVersion }); expect(updatedTeam3).toBeNull(); - expect(versionD).toBe(undefined); + expect(updatedTeam3?.xata_version).toBe(undefined); - expect(xata.db.teams.updateOrThrow(team.id, { name: 'Team cars' }, { ifVersion: versionA })).rejects.toThrow(); + expect( + xata.db.teams.updateOrThrow(team.xata_id, { name: 'Team cars' }, { ifVersion: baseVersion }) + ).rejects.toThrow(); }); test('update item with id column', async () => { const team = await xata.db.teams.create({ name: 'Team ships' }); - const update1 = await xata.db.teams.update(team.id, { name: 'Team boats' }); + const update1 = await xata.db.teams.update(team.xata_id, { name: 'Team boats' }); - expect(update1?.id).toBe(team.id); + expect(update1?.xata_id).toBe(team.xata_id); expect(update1?.name).toBe('Team boats'); - const update2 = await xata.db.teams.update({ id: team.id, name: 'Team planes' }); + const update2 = await xata.db.teams.update({ xata_id: team.xata_id, name: 'Team planes' }); - expect(update2?.id).toBe(team.id); + expect(update2?.xata_id).toBe(team.xata_id); expect(update2?.name).toBe('Team planes'); - const update3 = await xata.db.teams.update([{ id: team.id, name: 'Team cars' }]); + const update3 = await xata.db.teams.update([{ xata_id: team.xata_id, name: 'Team cars' }]); - expect(update3[0]?.id).toBe(team.id); + expect(update3[0]?.xata_id).toBe(team.xata_id); expect(update3[0]?.name).toBe('Team cars'); const update4 = await update1?.update({ name: 'Team trains' }); - expect(update4?.id).toBe(team.id); + expect(update4?.xata_id).toBe(team.xata_id); expect(update4?.name).toBe('Team trains'); - const update5 = await update1?.update({ id: update1?.id, name: 'Team boats' }); + const update5 = await update1?.update({ xata_id: update1?.xata_id, name: 'Team boats' }); - expect(update5?.id).toBe(team.id); + expect(update5?.xata_id).toBe(team.xata_id); expect(update5?.name).toBe('Team boats'); const copy = await update2?.read(); - expect(copy?.id).toBe(team.id); + expect(copy?.xata_id).toBe(team.xata_id); expect(copy?.name).toBe('Team boats'); }); test('update with numeric operations', async () => { const pet = await xata.db.pets.create({ name: 'Pet', num_legs: 1 }); - const update1 = await xata.db.pets.update(pet.id, { num_legs: { $increment: 3 } }); + const update1 = await xata.db.pets.update(pet.xata_id, { num_legs: { $increment: 3 } }); expect(update1?.num_legs).toBe(4); - const update2 = await xata.db.pets.update({ id: pet.id, num_legs: { $divide: 2 } }); + const update2 = await xata.db.pets.update({ xata_id: pet.xata_id, num_legs: { $divide: 2 } }); expect(update2?.num_legs).toBe(2); - const update3 = await xata.db.pets.update([{ id: pet.id, num_legs: { $multiply: 2 } }]); + const update3 = await xata.db.pets.update([{ xata_id: pet.xata_id, num_legs: { $multiply: 2 } }]); expect(update3[0]?.num_legs).toBe(4); - const update4 = await xata.db.pets.update(pet.id, { num_legs: { $decrement: 4 } }); + const update4 = await xata.db.pets.update(pet.xata_id, { num_legs: { $decrement: 4 } }); expect(update4?.num_legs).toBe(0); }); }); diff --git a/test/mock_data.ts b/test/mock_data.ts index 079136936..a09dbf2fd 100644 --- a/test/mock_data.ts +++ b/test/mock_data.ts @@ -1,5 +1,6 @@ import { Schema } from '../packages/client/src/api/schemas'; import schemaJson from '../packages/codegen/example/schema.json'; +import { PgRollOperation } from '../packages/pgroll'; const animals = [ 'Ape', @@ -67,3 +68,90 @@ export const fruitUsers = fruits.map((fruit) => ({ export const mockUsers = [ownerFruits, ownerAnimals, ...animalUsers, ...fruitUsers]; export const schema = schemaJson as Schema; + +export const pgRollMigrations: PgRollOperation[] = [ + { + create_table: { + name: 'users', + columns: [ + { name: 'email', type: 'text', unique: true, nullable: true }, + { name: 'name', type: 'text', nullable: true }, + { name: 'photo', type: 'xata.xata_file', nullable: true, comment: `{ "xata.file.dpa": true }` }, + { name: 'attachments', type: 'xata.xata_file_array', nullable: true }, + { name: 'plan', type: 'text', nullable: true }, + { name: 'dark', type: 'boolean', nullable: true }, + { name: 'full_name', type: 'text', nullable: false, default: "'John Doe'" }, + { name: 'index', type: 'int8', nullable: true }, + { name: 'rating', type: 'float', nullable: true }, + { name: 'birthDate', type: 'timestamptz', nullable: true }, + { name: 'street', type: 'text', nullable: true }, + { name: 'zipcode', type: 'int', nullable: true }, + { name: 'account_value', type: 'int', nullable: true }, + { name: 'vector', type: 'real[]', nullable: true, comment: `{ "xata.search.dimension": 4 }` } + ] + } + }, + { + create_table: { + name: 'teams', + columns: [ + { name: 'name', type: 'text', nullable: true }, + { name: 'description', type: 'text', nullable: true }, + { name: 'labels', type: 'text[]', nullable: true }, + { name: 'index', type: 'int', nullable: true }, + { name: 'rating', type: 'float', nullable: true }, + { name: 'founded_date', type: 'timestamptz', nullable: true }, + { name: 'email', type: 'text', nullable: true }, + { name: 'plan', type: 'text', nullable: true }, + { name: 'dark', type: 'boolean', nullable: true }, + { name: 'config', type: 'jsonb', nullable: true } + ] + } + }, + { + create_table: { + name: 'pets', + columns: [ + { name: 'name', type: 'text', nullable: true }, + { name: 'type', type: 'text', nullable: true }, + { name: 'num_legs', type: 'int', nullable: true } + ] + } + }, + { + add_column: { + table: 'users', + column: { + name: 'team', + type: 'text', + nullable: true, + comment: `{ "xata.link": "teams" }`, + references: { name: 'fk_team_id', table: 'teams', column: 'xata_id' } + } + } + }, + { + add_column: { + table: 'users', + column: { + name: 'pet', + type: 'text', + nullable: true, + comment: `{ "xata.link": "pets" }`, + references: { name: 'fk_pet_id', table: 'pets', column: 'xata_id' } + } + } + }, + { + add_column: { + table: 'teams', + column: { + name: 'owner', + type: 'text', + nullable: true, + comment: `{ "xata.link": "users" }`, + references: { name: 'fk_owner_id', table: 'users', column: 'xata_id' } + } + } + } +]; diff --git a/test/utils/setup.ts b/test/utils/setup.ts index 063720b35..faaad81fa 100644 --- a/test/utils/setup.ts +++ b/test/utils/setup.ts @@ -13,7 +13,7 @@ import { getHostUrl, parseProviderString } from '../../packages/client/src/api/p import { TraceAttributes } from '../../packages/client/src/schema/tracing'; import { XataClient } from '../../packages/codegen/example/xata'; import { buildTraceFunction } from '../../packages/plugin-client-opentelemetry'; -import { schema } from '../mock_data'; +import { pgRollMigrations } from '../mock_data'; // Get environment variables before reading them dotenv.config({ path: join(process.cwd(), '.env') }); @@ -24,10 +24,10 @@ if (apiKey === '') throw new Error('XATA_API_KEY environment variable is not set const workspace = process.env.XATA_WORKSPACE ?? ''; if (workspace === '') throw new Error('XATA_WORKSPACE environment variable is not set'); -const region = process.env.XATA_REGION || 'eu-west-1'; - const host = parseProviderString(process.env.XATA_API_PROVIDER); +const region = process.env.XATA_REGION || 'us-east-1'; + export type EnvironmentOptions = { fetch?: any; }; @@ -74,7 +74,7 @@ export async function setUpTestEnvironment( const { databaseName: database } = await api.databases.createDatabase({ pathParams: { workspaceId: workspace, dbName: `sdk-integration-test-${prefix}-${id}` }, body: { region }, - headers: { 'X-Xata-Files': 'true' } + headers: { 'X-Features': 'feat-pgroll-migrations=1' } }); const workspaceUrl = getHostUrl(host, 'workspaces').replace('{workspaceId}', workspace).replace('{region}', region); @@ -88,15 +88,22 @@ export async function setUpTestEnvironment( clientName: 'sdk-tests' }; - const { edits } = await api.migrations.compareBranchWithUserSchema({ - pathParams: { workspace, region, dbBranchName: `${database}:main` }, - body: { schema } - }); + for (const operation of pgRollMigrations) { + const { jobID } = await api.migrations.applyMigration({ + pathParams: { workspace, region, dbBranchName: `${database}:main` }, + body: { operations: [operation] } + }); - await api.migrations.applyBranchSchemaEdit({ - pathParams: { workspace, region, dbBranchName: `${database}:main` }, - body: { edits } - }); + await waitForMigrationToFinish(api, workspace, region, database, 'main', jobID); + + if ('create_table' in operation) { + const { jobID } = await api.migrations.adaptTable({ + pathParams: { workspace, region, dbBranchName: `${database}:main`, tableName: operation.create_table.name } + }); + + await waitForMigrationToFinish(api, workspace, region, database, 'main', jobID); + } + } let span: Span | undefined; @@ -155,3 +162,26 @@ declare module 'vitest' { span?: Span; } } + +async function waitForMigrationToFinish( + api: XataApiClient, + workspace: string, + region: string, + database: string, + branch: string, + jobId: string +) { + const { status, error } = await api.migrations.getMigrationJobStatus({ + pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, jobId } + }); + if (status === 'failed') { + throw new Error(`Migration failed, ${error}`); + } + + if (status === 'completed') { + return; + } + + await new Promise((resolve) => setTimeout(resolve, 1000)); + return await waitForMigrationToFinish(api, workspace, region, database, branch, jobId); +} From 31e5f84fb15d22344a55dad49b03cd50aeec47ac Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Wed, 6 Mar 2024 09:20:47 +0100 Subject: [PATCH 08/22] Update test to allow postgres (#1396) --- test/utils/setup.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/utils/setup.ts b/test/utils/setup.ts index faaad81fa..db51d1016 100644 --- a/test/utils/setup.ts +++ b/test/utils/setup.ts @@ -71,6 +71,12 @@ export async function setUpTestEnvironment( const id = Date.now().toString(36); const api = new XataApiClient({ apiKey, fetch, host, clientName: 'sdk-tests' }); + + await api.workspaces.updateWorkspaceSettings({ + pathParams: { workspaceId: workspace }, + body: { postgresEnabled: true } + }); + const { databaseName: database } = await api.databases.createDatabase({ pathParams: { workspaceId: workspace, dbName: `sdk-integration-test-${prefix}-${id}` }, body: { region }, From 850edd56b2cc9aa65077aa72572db520f7675e90 Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Thu, 21 Mar 2024 15:36:32 +0100 Subject: [PATCH 09/22] Fix drizzle tests in `next` (#1417) Signed-off-by: Alexis Rico --- .../plugin-client-drizzle/test/drizzle.test.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/plugin-client-drizzle/test/drizzle.test.ts b/packages/plugin-client-drizzle/test/drizzle.test.ts index 4f4fd077a..213e68dbc 100644 --- a/packages/plugin-client-drizzle/test/drizzle.test.ts +++ b/packages/plugin-client-drizzle/test/drizzle.test.ts @@ -78,10 +78,9 @@ function getDrizzleClient(type: string, branch: string) { describe.concurrent.each([{ type: 'pg' }, { type: 'http' }])('Drizzle $type', ({ type }) => { beforeAll(async () => { - await api.database.createDatabase({ - workspace, - database, - data: { region, branchName: 'main' }, + await api.databases.createDatabase({ + pathParams: { workspaceId: workspace, dbName: database }, + body: { region, branchName: 'main' }, headers: { 'X-Features': 'feat-pgroll-migrations=1' } }); @@ -155,12 +154,15 @@ describe.concurrent.each([{ type: 'pg' }, { type: 'http' }])('Drizzle $type', ({ }); afterAll(async () => { - await api.database.deleteDatabase({ workspace, database }); + await api.databases.deleteDatabase({ pathParams: { workspaceId: workspace, dbName: database } }); }); beforeEach(async (ctx) => { ctx.branch = `test-${Math.random().toString(36).substring(7)}`; - await api.branches.createBranch({ workspace, database, region, branch: ctx.branch, from: 'main' }); + await api.branch.createBranch({ + pathParams: { workspace, region, dbBranchName: `${database}:${ctx.branch}` }, + body: { from: 'main' } + }); const { db, client } = getDrizzleClient(type, ctx.branch); await client?.connect(); @@ -171,7 +173,7 @@ describe.concurrent.each([{ type: 'pg' }, { type: 'http' }])('Drizzle $type', ({ afterEach(async (ctx) => { await ctx.client?.end(); - await api.branches.deleteBranch({ workspace, database, region, branch: ctx.branch }); + await api.branch.deleteBranch({ pathParams: { workspace, region, dbBranchName: `${database}:${ctx.branch}` } }); }); /* @@ -6285,7 +6287,7 @@ describe.concurrent.each([{ type: 'pg' }, { type: 'http' }])('Drizzle $type', ({ async function waitForReplication(): Promise { try { await new Promise((resolve) => setTimeout(resolve, 2000)); - await api.branches.getBranchList({ workspace, database, region }); + await api.branch.getBranchList({ pathParams: { workspace, dbName: database, region } }); } catch (error) { console.log(`Replication not ready yet, retrying...`); return await waitForReplication(); From d1afb7cdf8b482038b47950e8dcd892cb9a8682a Mon Sep 17 00:00:00 2001 From: Emily Morgan Date: Fri, 22 Mar 2024 09:41:21 +0100 Subject: [PATCH 10/22] fix: generate data native types (#1412) Signed-off-by: Alexis Rico Co-authored-by: Alexis Rico --- packages/importer/src/random-data.ts | 85 +++++++++++++++------------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/packages/importer/src/random-data.ts b/packages/importer/src/random-data.ts index 26cc39581..7f81a763f 100644 --- a/packages/importer/src/random-data.ts +++ b/packages/importer/src/random-data.ts @@ -1,5 +1,12 @@ import { fakerEN as faker } from '@faker-js/faker'; import { Schemas } from '@xata.io/client'; +import { z } from 'zod'; + +// TODO: Remove this once we migrate pgroll branches +type PgRollColumn = Schemas.Column & { + comment?: string; + pgType?: string; +}; export function generateRandomData(table: Schemas.Table, size: number) { const records: Record[] = []; @@ -11,7 +18,7 @@ export function generateRandomData(table: Schemas.Table, size: number) { return records; } -function randomRecord(columns: Schemas.Column[]) { +function randomRecord(columns: PgRollColumn[]) { const record: Record = {}; for (const column of columns) { record[column.name] = randomData(column); @@ -19,53 +26,53 @@ function randomRecord(columns: Schemas.Column[]) { return record; } -function randomData(column: Schemas.Column) { - switch (column.type) { - case 'text': - return faker.lorem.paragraphs(rand(2, 3)); - case 'email': - return faker.internet.email({ provider: 'acme.pets' }); +function randomData(column: PgRollColumn) { + const columnCommentType = narrowStringType(column.comment); + // Note that this is a best effort and seeding may fail for invalid Xata columns + // that are foreign keys, or have constraints such as length attached to them. + switch (column.pgType) { + case 'boolean': + return rand(0, 1) === 1; + case 'bigint': + case 'int8': + case 'integer': case 'int': + case 'int4': + case 'smallint': return rand(1, 100); - case 'float': + case 'double precision': + case 'float8': + case 'real': return rand(1, 10000) / rand(1, 100); - case 'bool': - return rand(0, 1) === 1; - case 'multiple': - return faker.word.words(rand(1, 3)).split(' '); - case 'string': - return randomString(column.name); - case 'datetime': + case 'text': + case 'varchar': + case 'character varying': + if (columnCommentType === 'email') return faker.internet.email({ provider: 'acme.pets' }); + return faker.word.words(3); + case 'timestamptz': return faker.date.recent({ days: rand(1, 10) }); - default: - return undefined; + case 'text[]': + return faker.word.words(rand(1, 3)).split(' '); } + + if (column.pgType?.startsWith('character(') || column.pgType?.startsWith('varchar(')) return faker.word.words(3); + if (column.pgType?.startsWith('numeric(')) return rand(1, 10000) / rand(1, 100); + + return undefined; } function rand(min: number, max: number) { return Math.floor(Math.random() * (max - min) + min); } -const generators: Record string> = { - city: () => faker.location.city(), - country: () => faker.location.country(), - county: () => faker.location.county(), - state: () => faker.location.state(), - street: () => faker.location.street(), - timezone: () => faker.location.timeZone(), - tz: () => faker.location.timeZone(), - zipcode: () => faker.location.zipCode(), - zip: () => faker.location.zipCode(), - department: () => faker.commerce.department(), - product: () => faker.commerce.product(), - company: () => faker.company.name(), - firstName: () => faker.person.firstName(), - lastName: () => faker.person.lastName(), - phone: () => faker.phone.number('501-###-###') -}; +export const xataStringColumns = ['email', 'text', 'string'] as const; -function randomString(columnName: string) { - const gen = generators[columnName.toLowerCase()]; - if (gen) return gen(); - return faker.word.words(2); -} +const XataStringColumn = z.object({ + ['xata.type']: z.enum(xataStringColumns) +}); + +const narrowStringType = (comment?: string): Schemas.Column['type'] => { + if (!comment) return 'text'; + const result = XataStringColumn.safeParse(JSON.parse(comment)); + return result.success ? result.data['xata.type'] : 'text'; +}; From 6c6f3e997e189d06c76a84446f25edcd856f01b8 Mon Sep 17 00:00:00 2001 From: Andrew Farries Date: Tue, 9 Apr 2024 14:54:28 +0100 Subject: [PATCH 11/22] Wait for completion on `pgroll` migration push (#1434) --- .changeset/light-cycles-repair.md | 2 +- cli/src/commands/push/index.ts | 9 ++++++--- cli/src/commands/push/push.test.ts | 8 ++++++++ cli/src/migrations/pgroll.ts | 31 ++++++++++++++++++++++++++---- test/integration/sql.test.ts | 2 +- 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/.changeset/light-cycles-repair.md b/.changeset/light-cycles-repair.md index 61c123457..8ed66fc50 100644 --- a/.changeset/light-cycles-repair.md +++ b/.changeset/light-cycles-repair.md @@ -1,5 +1,5 @@ --- -"@xata.io/client": major +'@xata.io/client': major --- Make XataApiClient to use ES Proxies diff --git a/cli/src/commands/push/index.ts b/cli/src/commands/push/index.ts index 596b88655..247c48458 100644 --- a/cli/src/commands/push/index.ts +++ b/cli/src/commands/push/index.ts @@ -1,5 +1,6 @@ import { Args, Flags } from '@oclif/core'; import { Schemas } from '@xata.io/client'; +import { PgRollMigrationDefinition } from '@xata.io/pgroll'; import { BaseCommand } from '../../base.js'; import { LocalMigrationFile, @@ -11,10 +12,10 @@ import { allMigrationsPgRollFormat, getBranchDetailsWithPgRoll, isBranchPgRollEnabled, - isMigrationPgRollFormat + isMigrationPgRollFormat, + waitForMigrationToFinish } from '../../migrations/pgroll.js'; import { MigrationFilePgroll } from '../../migrations/schema.js'; -import { PgRollMigrationDefinition } from '@xata.io/pgroll'; export default class Push extends BaseCommand { static description = 'Push local changes to a remote Xata branch'; @@ -103,10 +104,12 @@ export default class Push extends BaseCommand { .flatMap((migration) => PgRollMigrationDefinition.parse(migration)); for (const migration of migrationsToPush) { try { - await xata.api.migrations.applyMigration({ + const { jobID } = await xata.api.migrations.applyMigration({ pathParams: { workspace, region, dbBranchName: `${database}:${branch}` }, body: migration }); + + await waitForMigrationToFinish(xata.api, workspace, region, database, branch, jobID); } catch (e) { this.log(`Failed to push ${migration} with ${e}. Stopping.`); this.exit(1); diff --git a/cli/src/commands/push/push.test.ts b/cli/src/commands/push/push.test.ts index 94fa78b23..0cfca5376 100644 --- a/cli/src/commands/push/push.test.ts +++ b/cli/src/commands/push/push.test.ts @@ -188,6 +188,14 @@ const baseFetch = (url: string, request: any) => { } }) }; + } else if ( + url === `https://test-1234.us-east-1.xata.sh/db/db1:main/migrations/jobs/1234` && + request.method === 'GET' + ) { + return { + ok: true, + json: async () => ({ status: 'completed' }) + }; } throw new Error(`Unexpected fetch request: ${url} ${request.method}`); diff --git a/cli/src/migrations/pgroll.ts b/cli/src/migrations/pgroll.ts index 4028d220c..37ea8130a 100644 --- a/cli/src/migrations/pgroll.ts +++ b/cli/src/migrations/pgroll.ts @@ -1,9 +1,9 @@ -import { Schemas } from '@xata.io/client'; -import { migrationsDir, readMigrationsDir } from './files.js'; +import { Schemas, XataApiClient } from '@xata.io/client'; import path from 'path'; -import { safeJSONParse, safeReadFile } from '../utils/files.js'; -import { migrationFilePgroll, MigrationFilePgroll } from './schema.js'; import { XataClient } from '../base.js'; +import { safeJSONParse, safeReadFile } from '../utils/files.js'; +import { migrationsDir, readMigrationsDir } from './files.js'; +import { MigrationFilePgroll, migrationFilePgroll } from './schema.js'; export const isBranchPgRollEnabled = (details: Schemas.DBBranch) => { // @ts-expect-error TODO: Fix this when api is finalized @@ -121,3 +121,26 @@ export async function getBranchDetailsWithPgRoll( return details; } + +export async function waitForMigrationToFinish( + api: XataApiClient, + workspace: string, + region: string, + database: string, + branch: string, + jobId: string +) { + const { status, error } = await api.migrations.getMigrationJobStatus({ + pathParams: { workspace, region, dbBranchName: `${database}:${branch}`, jobId } + }); + if (status === 'failed') { + throw new Error(`Migration failed, ${error}`); + } + + if (status === 'completed') { + return; + } + + await new Promise((resolve) => setTimeout(resolve, 1000)); + return await waitForMigrationToFinish(api, workspace, region, database, branch, jobId); +} diff --git a/test/integration/sql.test.ts b/test/integration/sql.test.ts index 60f6deb07..e01782e82 100644 --- a/test/integration/sql.test.ts +++ b/test/integration/sql.test.ts @@ -373,7 +373,7 @@ describe('SQL proxy', () => { expect(record2).toBeDefined(); expect(record2?.[4]).toBe('[C] Planes'); }); - + test('xata.sql has a connection string', async () => { expect(xata.sql.connectionString).toBeDefined(); expect(xata.sql.connectionString).toMatch( From a1ee09bf6e8eda178a45f87b7779c8c0b15f1628 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 23 Apr 2024 11:33:14 +0200 Subject: [PATCH 12/22] test release assets --- .github/workflows/release.yml | 45 +- package.json | 6 + .../plugin-client-drizzle/src/pg/session.ts | 4 +- pnpm-lock.yaml | 395 ++++++++++++++---- 4 files changed, 340 insertions(+), 110 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9c4f6aa52..93b5d27f7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,10 +1,12 @@ name: Release on: + pull_request: push: branches: - - main - - next + # - main + # - next + - release-assets concurrency: ${{ github.workflow }}-${{ github.ref }} @@ -47,22 +49,25 @@ jobs: - name: Build run: pnpm build - - name: Update next channel - if: github.ref_name == 'next' - env: - GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} - run: | - npx changeset pre exit - npx changeset version --snapshot next - npx changeset publish --tag next --no-git-tag + # - name: Update next channel + # if: github.ref_name == 'next' + # env: + # GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} + # run: | + # npx changeset pre exit + # npx changeset version --snapshot next + # npx changeset publish --tag next --no-git-tag - - name: Create Release Pull Request or Publish to npm - uses: changesets/action@v1 - if: github.ref_name == 'main' - with: - title: Release tracking - publish: npx changeset publish - version: node ./scripts/changeset-version.mjs - env: - GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + # - name: Create Release Pull Request or Publish to npm + # uses: changesets/action@v1 + # if: github.ref_name == 'main' + # with: + # title: Release tracking + # publish: npx changeset publish + # version: node ./scripts/changeset-version.mjs + # env: + # GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} + # NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Release CLI + run: pnpm run release:cli diff --git a/package.json b/package.json index b4ab062d0..6beabb32f 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "test": "vitest", "test:canary": "tsx ./scripts/test-canary.ts", + "release:cli": "tsx ./scripts/release-cli.ts", "lint": "eslint .", "lint:fix": "eslint . --fix", "prepare": "husky install", @@ -107,5 +108,10 @@ "engines": { "node": "18.x", "pnpm": "8.x" + }, + "dependencies": { + "@pnpm/exportable-manifest": "^6.0.0", + "@pnpm/read-project-manifest": "^6.0.0", + "@pnpm/write-project-manifest": "^6.0.0" } } diff --git a/packages/plugin-client-drizzle/src/pg/session.ts b/packages/plugin-client-drizzle/src/pg/session.ts index bf44df5ec..842b7d151 100644 --- a/packages/plugin-client-drizzle/src/pg/session.ts +++ b/packages/plugin-client-drizzle/src/pg/session.ts @@ -158,7 +158,7 @@ export class XataSession< // @ts-expect-error getTransactionConfigSQL is internal await tx.execute(sql`begin ${tx.getTransactionConfigSQL(config)}`); try { - const result = await transaction(tx); + const result = await transaction(tx as any); await tx.execute(sql`commit`); return result; } catch (error) { @@ -184,7 +184,7 @@ export class XataTransaction< const tx = new XataTransaction(this.dialect, this.session, this.schema, this.nestedIndex + 1); await tx.execute(sql.raw(`savepoint ${savepointName}`)); try { - const result = await transaction(tx); + const result = await transaction(tx as any); await tx.execute(sql.raw(`release savepoint ${savepointName}`)); return result; } catch (e) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6f701106a..13f572dbe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,16 @@ settings: importers: .: + dependencies: + '@pnpm/exportable-manifest': + specifier: ^6.0.0 + version: 6.0.0 + '@pnpm/read-project-manifest': + specifier: ^6.0.0 + version: 6.0.0 + '@pnpm/write-project-manifest': + specifier: ^6.0.0 + version: 6.0.0 devDependencies: '@babel/core': specifier: ^7.24.4 @@ -157,6 +167,9 @@ importers: '@oclif/plugin-plugins': specifier: ^5.0.9 version: 5.0.9 + '@oclif/plugin-update': + specifier: ^4.2.7 + version: 4.2.7 '@types/ini': specifier: ^4.1.0 version: 4.1.0 @@ -167,16 +180,16 @@ importers: specifier: ^7.5.8 version: 7.5.8 '@xata.io/client': - specifier: workspace:* + specifier: next version: link:../packages/client '@xata.io/codegen': - specifier: workspace:* + specifier: next version: link:../packages/codegen '@xata.io/importer': - specifier: workspace:* + specifier: latest version: link:../packages/importer '@xata.io/pgroll': - specifier: workspace:* + specifier: latest version: link:../packages/pgroll ansi-regex: specifier: ^6.0.1 @@ -285,8 +298,8 @@ importers: specifier: ^3.1.4 version: 3.1.4(eslint@9.0.0)(typescript@5.4.5) oclif: - specifier: ^4.8.5 - version: 4.8.5 + specifier: ^4.8.8 + version: 4.8.8 shx: specifier: ^0.3.4 version: 0.3.4 @@ -614,8 +627,8 @@ packages: '@smithy/util-base64': 2.3.0 '@smithy/util-body-length-browser': 2.2.0 '@smithy/util-body-length-node': 2.3.0 - '@smithy/util-defaults-mode-browser': 2.2.0 - '@smithy/util-defaults-mode-node': 2.3.0 + '@smithy/util-defaults-mode-browser': 2.2.1 + '@smithy/util-defaults-mode-node': 2.3.1 '@smithy/util-endpoints': 1.2.0 '@smithy/util-middleware': 2.2.0 '@smithy/util-retry': 2.2.0 @@ -733,8 +746,8 @@ packages: '@smithy/util-base64': 2.3.0 '@smithy/util-body-length-browser': 2.2.0 '@smithy/util-body-length-node': 2.3.0 - '@smithy/util-defaults-mode-browser': 2.2.0 - '@smithy/util-defaults-mode-node': 2.3.0 + '@smithy/util-defaults-mode-browser': 2.2.1 + '@smithy/util-defaults-mode-node': 2.3.1 '@smithy/util-endpoints': 1.2.0 '@smithy/util-middleware': 2.2.0 '@smithy/util-retry': 2.2.0 @@ -831,8 +844,8 @@ packages: '@smithy/util-base64': 2.3.0 '@smithy/util-body-length-browser': 2.2.0 '@smithy/util-body-length-node': 2.3.0 - '@smithy/util-defaults-mode-browser': 2.2.0 - '@smithy/util-defaults-mode-node': 2.3.0 + '@smithy/util-defaults-mode-browser': 2.2.1 + '@smithy/util-defaults-mode-node': 2.3.1 '@smithy/util-endpoints': 1.2.0 '@smithy/util-middleware': 2.2.0 '@smithy/util-retry': 2.2.0 @@ -928,8 +941,8 @@ packages: '@smithy/util-base64': 2.3.0 '@smithy/util-body-length-browser': 2.2.0 '@smithy/util-body-length-node': 2.3.0 - '@smithy/util-defaults-mode-browser': 2.2.0 - '@smithy/util-defaults-mode-node': 2.3.0 + '@smithy/util-defaults-mode-browser': 2.2.1 + '@smithy/util-defaults-mode-node': 2.3.1 '@smithy/util-endpoints': 1.2.0 '@smithy/util-middleware': 2.2.0 '@smithy/util-retry': 2.2.0 @@ -996,7 +1009,7 @@ packages: dependencies: '@smithy/core': 1.4.2 '@smithy/protocol-http': 3.3.0 - '@smithy/signature-v4': 2.2.0 + '@smithy/signature-v4': 2.3.0 '@smithy/smithy-client': 2.5.1 '@smithy/types': 2.12.0 fast-xml-parser: 4.2.5 @@ -3961,6 +3974,12 @@ packages: protobufjs: 7.2.5 yargs: 17.7.2 + /@gwhitney/detect-indent@7.0.1: + resolution: + { integrity: sha512-7bQW+gkKa2kKZPeJf6+c6gFK9ARxQfn+FKy9ScTBppyKRWH2KzsmweXUoklqeEiHiNVWaeP5csIdsNq6w7QhzA== } + engines: { node: '>=12.20' } + dev: false + /@honeycombio/opentelemetry-node@0.4.0(supports-color@9.4.0): resolution: { integrity: sha512-6PFX8FGW7uA7vQ3mxNIoN36rH9Zx5kXh4kKP9zu28nynyWyy9JE3l8PNJYd9FS2L/d88ZUpQAiQ1pROaANd5MA== } @@ -4033,6 +4052,15 @@ packages: '@inquirer/core': 8.0.0 '@inquirer/type': 1.3.0 + /@inquirer/confirm@3.1.5: + resolution: + { integrity: sha512-6+dwZrpko5vr5EFEQmUbfBVhtu6IsnB8lQNsLHgO9S9fbfS5J6MuUj+NY0h98pPpYZXEazLR7qzypEDqVzf6aQ== } + engines: { node: '>=18' } + dependencies: + '@inquirer/core': 8.0.1 + '@inquirer/type': 1.3.0 + dev: true + /@inquirer/core@7.1.0: resolution: { integrity: sha512-FRCiDiU54XHt5B/D8hX4twwZuzSP244ANHbu3R7CAsJfiv1dUOz24ePBgCZjygEjDUi6BWIJuk4eWLKJ7LATUw== } @@ -4059,7 +4087,7 @@ packages: { integrity: sha512-ne5VhDqruYYzx8mmjDZ9F58ymrLJGxmSHJUcJGiW3tifzvl3goAm6gNX11w6+zUnGE54vgQ6ALDXL3IOSezMRw== } engines: { node: '>=18' } dependencies: - '@inquirer/type': 1.2.1 + '@inquirer/type': 1.3.0 '@types/mute-stream': 0.0.4 '@types/node': 20.12.7 '@types/wrap-ansi': 3.0.0 @@ -4093,31 +4121,54 @@ packages: strip-ansi: 6.0.1 wrap-ansi: 6.2.0 + /@inquirer/core@8.0.1: + resolution: + { integrity: sha512-qJRk1y51Os2ARc11Bg2N6uIwiQ9qBSrmZeuMonaQ/ntFpb4+VlcQ8Gl1TFH67mJLz3HA2nvuave0nbv6Lu8pbg== } + engines: { node: '>=18' } + dependencies: + '@inquirer/figures': 1.0.1 + '@inquirer/type': 1.3.0 + '@types/mute-stream': 0.0.4 + '@types/node': 20.12.7 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-spinners: 2.9.2 + cli-width: 4.1.0 + mute-stream: 1.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + /@inquirer/figures@1.0.0: resolution: { integrity: sha512-3fw+7+77/duTnMJTeSS44wneszghI4tkr0m0xdIJabbYRe36ElzmsqyboMZ1nFRon6sT+ckVvYDVjwapKv+2sw== } engines: { node: '>=18' } + /@inquirer/figures@1.0.1: + resolution: + { integrity: sha512-mtup3wVKia3ZwULPHcbs4Mor8Voi+iIXEWD7wCNbIO6lYR62oPCTQyrddi5OMYVXHzeCSoneZwJuS8sBvlEwDw== } + engines: { node: '>=18' } + /@inquirer/input@2.1.1: resolution: { integrity: sha512-Ag5PDh3/V3B68WGD/5LKXDqbdWKlF7zyfPAlstzu0NoZcZGBbZFjfgXlZIcb6Gs+AfdSi7wNf7soVAaMGH7moQ== } engines: { node: '>=18' } dependencies: '@inquirer/core': 7.1.2 - '@inquirer/type': 1.2.1 + '@inquirer/type': 1.3.0 dev: true - /@inquirer/select@2.2.1: + /@inquirer/select@2.3.1: resolution: - { integrity: sha512-JR4FeHvuxPSPWQy8DzkIvoIsJ4SWtSFb4xVLvLto84dL+jkv12lm8ILtuax4bMHvg5MBj3wYUF6Tk9izJ07gdw== } + { integrity: sha512-UagbSdmSjeoukHLXqkDQi2ewiGEogUyxaOeKeH34Ngmc/2z+S8u4JsJWToMJNKIHjEtoTFdlYpFrxCxapp06nQ== } engines: { node: '>=18' } dependencies: - '@inquirer/core': 7.1.2 - '@inquirer/type': 1.2.1 + '@inquirer/core': 8.0.1 + '@inquirer/figures': 1.0.1 + '@inquirer/type': 1.3.0 ansi-escapes: 4.3.2 chalk: 4.1.2 - figures: 3.2.0 - dev: true /@inquirer/type@1.2.1: resolution: @@ -4857,6 +4908,40 @@ packages: wordwrap: 1.0.0 wrap-ansi: 7.0.0 + /@oclif/core@3.26.4: + resolution: + { integrity: sha512-ntfo2ut7enNtAn/jB/dryMUPBM2Fh8Fydmi3k/Ybo6lCGU/hmsPFkBRjCEJAQMyNkK2yVZARaWogdOrcVgFz+w== } + engines: { node: '>=18.0.0' } + dependencies: + '@types/cli-progress': 3.11.5 + ansi-escapes: 4.3.2 + ansi-styles: 4.3.0 + cardinal: 2.1.1 + chalk: 4.1.2 + clean-stack: 3.0.1 + cli-progress: 3.12.0 + color: 4.2.3 + debug: 4.3.4(supports-color@8.1.1) + ejs: 3.1.10 + get-package-type: 0.1.0 + globby: 11.1.0 + hyperlinker: 1.0.0 + indent-string: 4.0.0 + is-wsl: 2.2.0 + js-yaml: 3.14.1 + minimatch: 9.0.4 + natural-orderby: 2.0.3 + object-treeify: 1.1.33 + password-prompt: 1.1.3 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + supports-color: 8.1.1 + supports-hyperlinks: 2.3.0 + widest-line: 3.1.0 + wordwrap: 1.0.0 + wrap-ansi: 7.0.0 + /@oclif/plugin-help@6.0.21: resolution: { integrity: sha512-w860r9d456xhw1GPaos9yQF+BZeFY9UKdrINbL3fZFX5ZHhr/zGT4Fep5wUkHogjjnSB8+ZHi3D6j2jScIizUw== } @@ -4891,12 +4976,30 @@ packages: - supports-color dev: false + /@oclif/plugin-update@4.2.7: + resolution: + { integrity: sha512-hhlRF2CePzz6R0Z8L8Aq4T1yKl7cTW5srXA9+LC9cIj9/4sCS1dhMixb2nu4AcBnz99RquAjwVA0fkcWm8ZswA== } + engines: { node: '>=18.0.0' } + dependencies: + '@inquirer/select': 2.3.1 + '@oclif/core': 3.26.4 + chalk: 5.3.0 + debug: 4.3.4(supports-color@9.4.0) + filesize: 6.4.0 + http-call: 5.3.0 + lodash.throttle: 4.1.1 + semver: 7.6.0 + tar-fs: 2.1.1 + transitivePeerDependencies: + - supports-color + dev: false + /@oclif/plugin-warn-if-update-available@3.0.15: resolution: { integrity: sha512-JtPTJFjL6izMCe5dDS2ix2PyWAD2DeJ5Atzd2HHRifbPcmOxaUE62FKTnarIwfPHLMF/nN33liwo9InAdirozg== } engines: { node: '>=18.0.0' } dependencies: - '@oclif/core': 3.26.3 + '@oclif/core': 3.26.4 chalk: 5.3.0 debug: 4.3.4(supports-color@9.4.0) http-call: 5.3.0 @@ -5542,6 +5645,92 @@ packages: dev: true optional: true + /@pnpm/constants@8.0.0: + resolution: + { integrity: sha512-yQosGUvYPpAjb1jOFcdbwekRjZRVxN6C0hHzfRCZrMKbxGjt/E0g0RcFlEDNVZ95tm4oMMcr7nEPa7H7LX3emw== } + engines: { node: '>=18.12' } + dev: false + + /@pnpm/error@6.0.0: + resolution: + { integrity: sha512-SKtHdV09k9+6jkohv9YuYmKMKNpxknoGjo0c6eN8x2Z3MHW2cuSt1OD/L16eCqdKQL+FUbvULxig0b9X9VK2/g== } + engines: { node: '>=18.12' } + dependencies: + '@pnpm/constants': 8.0.0 + dev: false + + /@pnpm/exportable-manifest@6.0.0: + resolution: + { integrity: sha512-5RLrRE4ZbIijBIXjTOtTVxTvO+lu0oh+kLi0WO/eEnoV50UfiG9h9VEUx5Sj5RW4cixTbnAQMlsRX1XYeDLTgQ== } + engines: { node: '>=18.12' } + dependencies: + '@pnpm/error': 6.0.0 + '@pnpm/read-project-manifest': 6.0.0 + '@pnpm/types': 10.0.0 + p-map-values: 1.0.0 + ramda: /@pnpm/ramda@0.28.1 + dev: false + + /@pnpm/graceful-fs@4.0.0: + resolution: + { integrity: sha512-933nhV2Prp51522poxX6Chvb7kEW3U3kzVWoqDU1+icB+QE7z/2qQ8wYHsBt4jm0Uil/sF67t77ugOr8bR63kg== } + engines: { node: '>=18.12' } + dependencies: + graceful-fs: 4.2.11 + dev: false + + /@pnpm/ramda@0.28.1: + resolution: + { integrity: sha512-zcAG+lvU0fMziNeGXpPyCyCJYp5ZVrPElEE4t14jAmViaihohocZ+dDkcRIyAomox8pQsuZnv1EyHR+pOhmUWw== } + dev: false + + /@pnpm/read-project-manifest@6.0.0: + resolution: + { integrity: sha512-X2LYdHErr7BQroRcV0LlilGXMA4SILf0D1adxQmr0CoEAxJThxcCEPIMLZqi9YukUF9oF5vV7qe/mdvI/r79Bw== } + engines: { node: '>=18.12' } + dependencies: + '@gwhitney/detect-indent': 7.0.1 + '@pnpm/error': 6.0.0 + '@pnpm/graceful-fs': 4.0.0 + '@pnpm/text.comments-parser': 3.0.0 + '@pnpm/types': 10.0.0 + '@pnpm/write-project-manifest': 6.0.0 + fast-deep-equal: 3.1.3 + is-windows: 1.0.2 + json5: 2.2.3 + lodash.clonedeep: 4.5.0 + parse-json: 5.2.0 + read-yaml-file: 2.1.0 + sort-keys: 4.2.0 + strip-bom: 4.0.0 + dev: false + + /@pnpm/text.comments-parser@3.0.0: + resolution: + { integrity: sha512-BSGvYd59kPKVTUk1InekEp+TiPnJ8650/bQyiOUFSvqHi61YipcR+E4H2i3xTnk2e+GHdGbXvEtAZbQmyxb0/g== } + engines: { node: '>=18.12' } + dependencies: + strip-comments-strings: 1.2.0 + dev: false + + /@pnpm/types@10.0.0: + resolution: + { integrity: sha512-P608MRTOExt5BkIN2hsrb/ycEchwaPW/x80ujJUAqxKZSXNVAOrlEu3KJ+2+jTCunyWmo/EcE01ZdwCw8jgVrQ== } + engines: { node: '>=18.12' } + dev: false + + /@pnpm/write-project-manifest@6.0.0: + resolution: + { integrity: sha512-DTjuH7Ls4v8CpfvOCtZkIIySpEKPGh7hEUpH5tqvVblzWQwfheoHfeBvyjGo975lvHsR2bCt2s8F7bv6DQ8o8g== } + engines: { node: '>=18.12' } + dependencies: + '@pnpm/text.comments-parser': 3.0.0 + '@pnpm/types': 10.0.0 + json5: 2.2.3 + write-file-atomic: 5.0.1 + write-yaml-file: 5.0.0 + dev: false + /@protobufjs/aspromise@1.1.2: resolution: { integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== } @@ -6125,21 +6314,6 @@ packages: tslib: 2.6.2 dev: true - /@smithy/signature-v4@2.2.0: - resolution: - { integrity: sha512-+B5TNzj/fRZzVW3z8UUJOkNx15+4E0CLuvJmJUA1JUIZFp3rdJ/M2H5r2SqltaVPXL0oIxv/6YK92T9TsFGbFg== } - engines: { node: '>=14.0.0' } - dependencies: - '@smithy/eventstream-codec': 2.2.0 - '@smithy/is-array-buffer': 2.2.0 - '@smithy/types': 2.12.0 - '@smithy/util-hex-encoding': 2.2.0 - '@smithy/util-middleware': 2.2.0 - '@smithy/util-uri-escape': 2.2.0 - '@smithy/util-utf8': 2.3.0 - tslib: 2.6.2 - dev: true - /@smithy/signature-v4@2.3.0: resolution: { integrity: sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q== } @@ -6226,18 +6400,6 @@ packages: tslib: 2.6.2 dev: true - /@smithy/util-defaults-mode-browser@2.2.0: - resolution: - { integrity: sha512-2okTdZaCBvOJszAPU/KSvlimMe35zLOKbQpHhamFJmR7t95HSe0K3C92jQPjKY3PmDBD+7iMkOnuW05F5OlF4g== } - engines: { node: '>= 10.0.0' } - dependencies: - '@smithy/property-provider': 2.2.0 - '@smithy/smithy-client': 2.5.1 - '@smithy/types': 2.12.0 - bowser: 2.11.0 - tslib: 2.6.2 - dev: true - /@smithy/util-defaults-mode-browser@2.2.1: resolution: { integrity: sha512-RtKW+8j8skk17SYowucwRUjeh4mCtnm5odCL0Lm2NtHQBsYKrNW0od9Rhopu9wF1gHMfHeWF7i90NwBz/U22Kw== } @@ -6250,20 +6412,6 @@ packages: tslib: 2.6.2 dev: true - /@smithy/util-defaults-mode-node@2.3.0: - resolution: - { integrity: sha512-hfKXnNLmsW9cmLb/JXKIvtuO6Cf4SuqN5PN1C2Ru/TBIws+m1wSgb+A53vo0r66xzB6E82inKG2J7qtwdi+Kkw== } - engines: { node: '>= 10.0.0' } - dependencies: - '@smithy/config-resolver': 2.2.0 - '@smithy/credential-provider-imds': 2.3.0 - '@smithy/node-config-provider': 2.3.0 - '@smithy/property-provider': 2.2.0 - '@smithy/smithy-client': 2.5.1 - '@smithy/types': 2.12.0 - tslib: 2.6.2 - dev: true - /@smithy/util-defaults-mode-node@2.3.1: resolution: { integrity: sha512-vkMXHQ0BcLFysBMWgSBLSk3+leMpFSyyFj8zQtv5ZyUBx8/owVh1/pPEkzmW/DR/Gy/5c8vjLDD9gZjXNKbrpA== } @@ -8200,6 +8348,11 @@ packages: fsevents: 2.3.3 dev: true + /chownr@1.1.4: + resolution: + { integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== } + dev: false + /chownr@2.0.0: resolution: { integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== } @@ -8531,7 +8684,6 @@ packages: resolution: { integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== } engines: { node: '>= 0.6' } - dev: true /convert-hrtime@3.0.0: resolution: @@ -9250,15 +9402,6 @@ packages: dependencies: jake: 10.8.7 - /ejs@3.1.9: - resolution: - { integrity: sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== } - engines: { node: '>=0.10.0' } - hasBin: true - dependencies: - jake: 10.8.7 - dev: true - /electron-to-chromium@1.4.715: resolution: { integrity: sha512-XzWNH4ZSa9BwVUQSDorPWAUQ5WGuYz7zJUNpNif40zFCiCl20t8zgylmreNmn26h5kiyw2lg7RfTmeMBsDklqg== } @@ -10328,6 +10471,12 @@ packages: dependencies: minimatch: 5.1.6 + /filesize@6.4.0: + resolution: + { integrity: sha512-mjFIpOHC4jbfcTfoh4rkWpI31mF7viw9ikj/JyLoKzqlwG/YsefKfvYlYhdYdg/9mtK2z1AzgN/0LvVQ3zdlSQ== } + engines: { node: '>= 0.4.0' } + dev: false + /fill-range@7.0.1: resolution: { integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== } @@ -11056,7 +11205,6 @@ packages: tunnel-agent: 0.6.0 transitivePeerDependencies: - supports-color - dev: true /http2-client@1.3.5: resolution: @@ -11168,7 +11316,6 @@ packages: resolution: { integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== } engines: { node: '>=0.8.19' } - dev: true /indent-string@4.0.0: resolution: @@ -11494,7 +11641,6 @@ packages: resolution: { integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== } engines: { node: '>=0.10.0' } - dev: true /is-shared-array-buffer@1.0.2: resolution: @@ -11573,7 +11719,6 @@ packages: resolution: { integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== } engines: { node: '>=0.10.0' } - dev: true /is-wsl@2.2.0: resolution: @@ -11737,7 +11882,6 @@ packages: /json-parse-better-errors@1.0.2: resolution: { integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== } - dev: true /json-parse-even-better-errors@2.3.1: resolution: @@ -12080,6 +12224,11 @@ packages: { integrity: sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w== } dev: false + /lodash.clonedeep@4.5.0: + resolution: + { integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== } + dev: false + /lodash.compact@3.0.1: resolution: { integrity: sha512-2ozeiPi+5eBXW1CLtzjk8XQFhQOEMwwfxblqeq6EGyTxZJ1bPATqilY0e6g2SLQpP4KuMeuioBhEnWz5Pr7ICQ== } @@ -12149,6 +12298,11 @@ packages: lodash._reinterpolate: 3.0.0 dev: true + /lodash.throttle@4.1.1: + resolution: + { integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== } + dev: false + /lodash.union@4.6.0: resolution: { integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== } @@ -12728,6 +12882,11 @@ packages: engines: { node: '>= 8.0.0' } dev: true + /mkdirp-classic@0.5.3: + resolution: + { integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== } + dev: false + /mkdirp@1.0.4: resolution: { integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== } @@ -13304,18 +13463,18 @@ packages: { integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== } dev: true - /oclif@4.8.5: + /oclif@4.8.8: resolution: - { integrity: sha512-7f6gYBAugi/+98lrsjnGtQnrva6JS2fDjyBzUZETi+EQHg/Gq55yvknHkMw4mLO5iA2MIEvClYdgyKR4keAdPA== } + { integrity: sha512-EZszrIY/rSa1fo0fq11rFAU7QvBX8FqAxyYIFTb19adSvxUwK8NKVn0b+lPlchibcpFHwde7ENFYSyJ1G+cWXg== } engines: { node: '>=18.0.0' } hasBin: true dependencies: '@aws-sdk/client-cloudfront': 3.535.0 '@aws-sdk/client-s3': 3.554.0 - '@inquirer/confirm': 3.1.4 + '@inquirer/confirm': 3.1.5 '@inquirer/input': 2.1.1 - '@inquirer/select': 2.2.1 - '@oclif/core': 3.26.3 + '@inquirer/select': 2.3.1 + '@oclif/core': 3.26.4 '@oclif/plugin-help': 6.0.21 '@oclif/plugin-not-found': 3.1.4 '@oclif/plugin-warn-if-update-available': 3.0.15 @@ -13323,7 +13482,7 @@ packages: chalk: 4.1.2 change-case: 4.1.2 debug: 4.3.4(supports-color@9.4.0) - ejs: 3.1.9 + ejs: 3.1.10 find-yarn-workspace-root: 2.0.0 fs-extra: 8.1.0 github-slugger: 1.5.0 @@ -13546,6 +13705,12 @@ packages: p-limit: 4.0.0 dev: false + /p-map-values@1.0.0: + resolution: + { integrity: sha512-/n8QJM4Os3HLRMSuQWwAocsMExENSQwWTgRi8m3JVEOWQ/4gud14igBcnYvSGQTbiyZbuizxEmwf0w3ITn67gg== } + engines: { node: '>=14' } + dev: false + /p-map@2.1.0: resolution: { integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== } @@ -13667,7 +13832,6 @@ packages: dependencies: error-ex: 1.3.2 json-parse-better-errors: 1.0.2 - dev: true /parse-json@5.2.0: resolution: @@ -14421,6 +14585,15 @@ packages: strip-bom: 3.0.0 dev: true + /read-yaml-file@2.1.0: + resolution: + { integrity: sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ== } + engines: { node: '>=10.13' } + dependencies: + js-yaml: 4.1.0 + strip-bom: 4.0.0 + dev: false + /readable-stream@1.0.34: resolution: { integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== } @@ -15284,6 +15457,14 @@ packages: tslib: 2.6.2 dev: true + /sort-keys@4.2.0: + resolution: + { integrity: sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg== } + engines: { node: '>=8' } + dependencies: + is-plain-obj: 2.1.0 + dev: false + /sort-object-keys@1.1.3: resolution: { integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg== } @@ -15528,6 +15709,17 @@ packages: engines: { node: '>=4' } dev: true + /strip-bom@4.0.0: + resolution: + { integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== } + engines: { node: '>=8' } + dev: false + + /strip-comments-strings@1.2.0: + resolution: + { integrity: sha512-zwF4bmnyEjZwRhaak9jUWNxc0DoeKBJ7lwSN/LEc8dQXZcUFG6auaaTQJokQWXopLdM3iTx01nQT8E4aL29DAQ== } + dev: false + /strip-final-newline@2.0.0: resolution: { integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== } @@ -15636,6 +15828,16 @@ packages: engines: { node: '>=6' } dev: true + /tar-fs@2.1.1: + resolution: + { integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== } + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + dev: false + /tar-stream@2.2.0: resolution: { integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== } @@ -15941,7 +16143,6 @@ packages: { integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== } dependencies: safe-buffer: 5.2.1 - dev: true /turbo-darwin-64@1.13.2: resolution: @@ -16685,6 +16886,24 @@ packages: resolution: { integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== } + /write-file-atomic@5.0.1: + resolution: + { integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + dev: false + + /write-yaml-file@5.0.0: + resolution: + { integrity: sha512-FdNA4RyH1L43TlvGG8qOMIfcEczwA5ij+zLXUy3Z83CjxhLvcV7/Q/8pk22wnCgYw7PJhtK+7lhO+qqyT4NdvQ== } + engines: { node: '>=16.14' } + dependencies: + js-yaml: 4.1.0 + write-file-atomic: 5.0.1 + dev: false + /ws@7.5.9: resolution: { integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== } From af44ab5c9fa3749971e698a197ce35ddc98aef04 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 23 Apr 2024 11:36:03 +0200 Subject: [PATCH 13/22] lock --- pnpm-lock.yaml | 72 +++++++++++--------------------------------------- 1 file changed, 15 insertions(+), 57 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 13f572dbe..74f9fb106 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -167,9 +167,6 @@ importers: '@oclif/plugin-plugins': specifier: ^5.0.9 version: 5.0.9 - '@oclif/plugin-update': - specifier: ^4.2.7 - version: 4.2.7 '@types/ini': specifier: ^4.1.0 version: 4.1.0 @@ -180,16 +177,16 @@ importers: specifier: ^7.5.8 version: 7.5.8 '@xata.io/client': - specifier: next + specifier: workspace:* version: link:../packages/client '@xata.io/codegen': - specifier: next + specifier: workspace:* version: link:../packages/codegen '@xata.io/importer': - specifier: latest + specifier: workspace:* version: link:../packages/importer '@xata.io/pgroll': - specifier: latest + specifier: workspace:* version: link:../packages/pgroll ansi-regex: specifier: ^6.0.1 @@ -298,7 +295,7 @@ importers: specifier: ^3.1.4 version: 3.1.4(eslint@9.0.0)(typescript@5.4.5) oclif: - specifier: ^4.8.8 + specifier: ^4.8.5 version: 4.8.8 shx: specifier: ^0.3.4 @@ -4139,6 +4136,7 @@ packages: signal-exit: 4.1.0 strip-ansi: 6.0.1 wrap-ansi: 6.2.0 + dev: true /@inquirer/figures@1.0.0: resolution: @@ -4149,6 +4147,7 @@ packages: resolution: { integrity: sha512-mtup3wVKia3ZwULPHcbs4Mor8Voi+iIXEWD7wCNbIO6lYR62oPCTQyrddi5OMYVXHzeCSoneZwJuS8sBvlEwDw== } engines: { node: '>=18' } + dev: true /@inquirer/input@2.1.1: resolution: @@ -4169,6 +4168,7 @@ packages: '@inquirer/type': 1.3.0 ansi-escapes: 4.3.2 chalk: 4.1.2 + dev: true /@inquirer/type@1.2.1: resolution: @@ -4941,6 +4941,7 @@ packages: widest-line: 3.1.0 wordwrap: 1.0.0 wrap-ansi: 7.0.0 + dev: true /@oclif/plugin-help@6.0.21: resolution: @@ -4976,24 +4977,6 @@ packages: - supports-color dev: false - /@oclif/plugin-update@4.2.7: - resolution: - { integrity: sha512-hhlRF2CePzz6R0Z8L8Aq4T1yKl7cTW5srXA9+LC9cIj9/4sCS1dhMixb2nu4AcBnz99RquAjwVA0fkcWm8ZswA== } - engines: { node: '>=18.0.0' } - dependencies: - '@inquirer/select': 2.3.1 - '@oclif/core': 3.26.4 - chalk: 5.3.0 - debug: 4.3.4(supports-color@9.4.0) - filesize: 6.4.0 - http-call: 5.3.0 - lodash.throttle: 4.1.1 - semver: 7.6.0 - tar-fs: 2.1.1 - transitivePeerDependencies: - - supports-color - dev: false - /@oclif/plugin-warn-if-update-available@3.0.15: resolution: { integrity: sha512-JtPTJFjL6izMCe5dDS2ix2PyWAD2DeJ5Atzd2HHRifbPcmOxaUE62FKTnarIwfPHLMF/nN33liwo9InAdirozg== } @@ -8348,11 +8331,6 @@ packages: fsevents: 2.3.3 dev: true - /chownr@1.1.4: - resolution: - { integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== } - dev: false - /chownr@2.0.0: resolution: { integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== } @@ -8684,6 +8662,7 @@ packages: resolution: { integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== } engines: { node: '>= 0.6' } + dev: true /convert-hrtime@3.0.0: resolution: @@ -10471,12 +10450,6 @@ packages: dependencies: minimatch: 5.1.6 - /filesize@6.4.0: - resolution: - { integrity: sha512-mjFIpOHC4jbfcTfoh4rkWpI31mF7viw9ikj/JyLoKzqlwG/YsefKfvYlYhdYdg/9mtK2z1AzgN/0LvVQ3zdlSQ== } - engines: { node: '>= 0.4.0' } - dev: false - /fill-range@7.0.1: resolution: { integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== } @@ -11205,6 +11178,7 @@ packages: tunnel-agent: 0.6.0 transitivePeerDependencies: - supports-color + dev: true /http2-client@1.3.5: resolution: @@ -11641,6 +11615,7 @@ packages: resolution: { integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== } engines: { node: '>=0.10.0' } + dev: true /is-shared-array-buffer@1.0.2: resolution: @@ -11882,6 +11857,7 @@ packages: /json-parse-better-errors@1.0.2: resolution: { integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== } + dev: true /json-parse-even-better-errors@2.3.1: resolution: @@ -12298,11 +12274,6 @@ packages: lodash._reinterpolate: 3.0.0 dev: true - /lodash.throttle@4.1.1: - resolution: - { integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== } - dev: false - /lodash.union@4.6.0: resolution: { integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== } @@ -12882,11 +12853,6 @@ packages: engines: { node: '>= 8.0.0' } dev: true - /mkdirp-classic@0.5.3: - resolution: - { integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== } - dev: false - /mkdirp@1.0.4: resolution: { integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== } @@ -13832,6 +13798,7 @@ packages: dependencies: error-ex: 1.3.2 json-parse-better-errors: 1.0.2 + dev: true /parse-json@5.2.0: resolution: @@ -15828,16 +15795,6 @@ packages: engines: { node: '>=6' } dev: true - /tar-fs@2.1.1: - resolution: - { integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== } - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.0 - tar-stream: 2.2.0 - dev: false - /tar-stream@2.2.0: resolution: { integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== } @@ -16143,6 +16100,7 @@ packages: { integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== } dependencies: safe-buffer: 5.2.1 + dev: true /turbo-darwin-64@1.13.2: resolution: From 95c7bfd72109b9dce9bc2f08c955c2260dc902af Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 23 Apr 2024 11:48:20 +0200 Subject: [PATCH 14/22] script --- scripts/release-cli.ts | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 scripts/release-cli.ts diff --git a/scripts/release-cli.ts b/scripts/release-cli.ts new file mode 100644 index 000000000..ee31ec86b --- /dev/null +++ b/scripts/release-cli.ts @@ -0,0 +1,45 @@ +import { createExportableManifest } from '@pnpm/exportable-manifest'; +import { readProjectManifest } from '@pnpm/read-project-manifest'; +import { writeProjectManifest } from '@pnpm/write-project-manifest'; +import { exec as execRaw } from 'child_process'; +import * as util from 'util'; +const exec = util.promisify(execRaw); + +const PATH_TO_CLI = process.cwd() + '/cli'; + +async function main() { + const { manifest, fileName } = await readProjectManifest(PATH_TO_CLI); + + const workspaceProtocolPackageManifest = await createExportableManifest(PATH_TO_CLI, { + ...manifest, + dependencies: { + ...manifest.dependencies, + '@xata.io/client': 'next', + '@xata.io/codegen': 'next', + '@xata.io/importer': 'latest', + '@xata.io/pgroll': 'latest' + } + }); + + await writeProjectManifest(`${PATH_TO_CLI}/${fileName}`, workspaceProtocolPackageManifest); + + process.chdir(PATH_TO_CLI); + + await exec(`rm -rf ${PATH_TO_CLI}/npm-shrinkwrap.json`); + const result = await exec(`touch ${PATH_TO_CLI}/npm-shrinkwrap.json`); + if (result.stderr) { + throw new Error(`Failed to make shrinkwrap: ${result.stderr}`); + } + console.log('Made shrinkwrap file', result.stdout); + + const pack = await exec(`pnpm oclif pack macos`); + if (pack.stderr) { + throw new Error(`Failed to pack: ${pack.stderr}`); + } + console.log('Packed CLI', pack.stdout); + + // TODO add built assets to release + // or s3 bucket +} + +main(); From 8f3adb98b336c294b3e9ff7d91bd814be4d07795 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 23 Apr 2024 12:00:49 +0200 Subject: [PATCH 15/22] separate action with matrix --- .github/workflows/release-cli-assets.yml | 45 ++++++++++++++++++++++++ .github/workflows/release.yml | 45 +++++++++++------------- scripts/release-cli.ts | 19 +++++++++- 3 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 .github/workflows/release-cli-assets.yml diff --git a/.github/workflows/release-cli-assets.yml b/.github/workflows/release-cli-assets.yml new file mode 100644 index 000000000..306604ba5 --- /dev/null +++ b/.github/workflows/release-cli-assets.yml @@ -0,0 +1,45 @@ +name: Release CLI Assets + +on: + push: + branches: + - release-assets + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + release: + name: Release CLI Assets + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + steps: + - uses: actions/checkout@v3 + with: + # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits + fetch-depth: 0 + # This makes the PR pushed to use GITHUB_TOKEN and trigger the checks + persist-credentials: false + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Use Node.js ${{ steps.config.outputs.NVMRC }} + uses: actions/setup-node@v3 + with: + node-version: ${{ steps.config.outputs.NVMRC }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm build + + - name: Release CLI + run: pnpm run release:cli + env: + RUNNER_OS: ${{ runner.os }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 93b5d27f7..9c4f6aa52 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,12 +1,10 @@ name: Release on: - pull_request: push: branches: - # - main - # - next - - release-assets + - main + - next concurrency: ${{ github.workflow }}-${{ github.ref }} @@ -49,25 +47,22 @@ jobs: - name: Build run: pnpm build - # - name: Update next channel - # if: github.ref_name == 'next' - # env: - # GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} - # run: | - # npx changeset pre exit - # npx changeset version --snapshot next - # npx changeset publish --tag next --no-git-tag - - # - name: Create Release Pull Request or Publish to npm - # uses: changesets/action@v1 - # if: github.ref_name == 'main' - # with: - # title: Release tracking - # publish: npx changeset publish - # version: node ./scripts/changeset-version.mjs - # env: - # GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} - # NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Update next channel + if: github.ref_name == 'next' + env: + GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} + run: | + npx changeset pre exit + npx changeset version --snapshot next + npx changeset publish --tag next --no-git-tag - - name: Release CLI - run: pnpm run release:cli + - name: Create Release Pull Request or Publish to npm + uses: changesets/action@v1 + if: github.ref_name == 'main' + with: + title: Release tracking + publish: npx changeset publish + version: node ./scripts/changeset-version.mjs + env: + GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/scripts/release-cli.ts b/scripts/release-cli.ts index ee31ec86b..0a922d38c 100644 --- a/scripts/release-cli.ts +++ b/scripts/release-cli.ts @@ -7,7 +7,24 @@ const exec = util.promisify(execRaw); const PATH_TO_CLI = process.cwd() + '/cli'; +const runnerToOclif = (runner: string) => { + switch (runner) { + case 'Windows': + return 'win'; + case 'macOS': + return 'macos'; + case 'Linux': + return 'deb'; + default: + throw new Error('Unsupported OS'); + } +}; + async function main() { + if (!process.env.RUNNER_OS) throw new Error('RUNNER_OS is not set'); + + const operatingSystem = runnerToOclif(process.env.RUNNER_OS); + const { manifest, fileName } = await readProjectManifest(PATH_TO_CLI); const workspaceProtocolPackageManifest = await createExportableManifest(PATH_TO_CLI, { @@ -32,7 +49,7 @@ async function main() { } console.log('Made shrinkwrap file', result.stdout); - const pack = await exec(`pnpm oclif pack macos`); + const pack = await exec(`pnpm oclif pack ${operatingSystem}`); if (pack.stderr) { throw new Error(`Failed to pack: ${pack.stderr}`); } From 91347b8aec610eaca4a9e14e926becd5cf50188e Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 23 Apr 2024 12:04:28 +0200 Subject: [PATCH 16/22] add identifiers --- cli/package.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cli/package.json b/cli/package.json index 9b9cb7f96..6662a8963 100644 --- a/cli/package.json +++ b/cli/package.json @@ -77,6 +77,15 @@ "hooks": { "init": "./dist/hooks/init/compatibility" }, + "macos": { + "identifier": "com.xata.cli" + }, + "deb": { + "identifier": "com.xata.cli" + }, + "win": { + "identifier": "com.xata.cli" + }, "dirname": "xata", "commands": "./dist/commands", "plugins": [ From ac923bdf13faf64e4ed2958eab5d5566135ee382 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 23 Apr 2024 13:46:51 +0200 Subject: [PATCH 17/22] use matrix --- .github/workflows/release-cli-assets.yml | 2 +- scripts/release-cli.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release-cli-assets.yml b/.github/workflows/release-cli-assets.yml index 306604ba5..4c0e1a985 100644 --- a/.github/workflows/release-cli-assets.yml +++ b/.github/workflows/release-cli-assets.yml @@ -42,4 +42,4 @@ jobs: - name: Release CLI run: pnpm run release:cli env: - RUNNER_OS: ${{ runner.os }} + MATRIX_OS: ${{ matrix.os }} diff --git a/scripts/release-cli.ts b/scripts/release-cli.ts index 0a922d38c..6a820f01e 100644 --- a/scripts/release-cli.ts +++ b/scripts/release-cli.ts @@ -7,13 +7,13 @@ const exec = util.promisify(execRaw); const PATH_TO_CLI = process.cwd() + '/cli'; -const runnerToOclif = (runner: string) => { - switch (runner) { - case 'Windows': +const matrixToOclif = (os: string) => { + switch (os) { + case 'windows-latest': return 'win'; - case 'macOS': + case 'macos-latest': return 'macos'; - case 'Linux': + case 'ubuntu-latest': return 'deb'; default: throw new Error('Unsupported OS'); @@ -21,9 +21,9 @@ const runnerToOclif = (runner: string) => { }; async function main() { - if (!process.env.RUNNER_OS) throw new Error('RUNNER_OS is not set'); + if (!process.env.MATRIX_OS) throw new Error('MATRIX_OS is not set'); - const operatingSystem = runnerToOclif(process.env.RUNNER_OS); + const operatingSystem = matrixToOclif(process.env.MATRIX_OS); const { manifest, fileName } = await readProjectManifest(PATH_TO_CLI); From 749cf14862aab7d583a39537bedfbf39727fc116 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 23 Apr 2024 13:53:08 +0200 Subject: [PATCH 18/22] test without windows --- .github/workflows/release-cli-assets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-cli-assets.yml b/.github/workflows/release-cli-assets.yml index 4c0e1a985..6f2e119bc 100644 --- a/.github/workflows/release-cli-assets.yml +++ b/.github/workflows/release-cli-assets.yml @@ -13,7 +13,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-latest] steps: - uses: actions/checkout@v3 with: From 0e3775381e5c968793be17e21fa498e2e9a86a63 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 23 Apr 2024 15:09:37 +0200 Subject: [PATCH 19/22] remove warnings --- scripts/release-cli.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/scripts/release-cli.ts b/scripts/release-cli.ts index 6a820f01e..e7543f47a 100644 --- a/scripts/release-cli.ts +++ b/scripts/release-cli.ts @@ -1,7 +1,7 @@ import { createExportableManifest } from '@pnpm/exportable-manifest'; import { readProjectManifest } from '@pnpm/read-project-manifest'; import { writeProjectManifest } from '@pnpm/write-project-manifest'; -import { exec as execRaw } from 'child_process'; +import { execFile, execFileSync, exec as execRaw } from 'child_process'; import * as util from 'util'; const exec = util.promisify(execRaw); @@ -42,21 +42,14 @@ async function main() { process.chdir(PATH_TO_CLI); - await exec(`rm -rf ${PATH_TO_CLI}/npm-shrinkwrap.json`); - const result = await exec(`touch ${PATH_TO_CLI}/npm-shrinkwrap.json`); - if (result.stderr) { - throw new Error(`Failed to make shrinkwrap: ${result.stderr}`); - } - console.log('Made shrinkwrap file', result.stdout); + execFile('rm', ['-rf', `${PATH_TO_CLI}/npm-shrinkwrap.json`]); + execFile('touch', [`${PATH_TO_CLI}/npm-shrinkwrap.json`]); const pack = await exec(`pnpm oclif pack ${operatingSystem}`); if (pack.stderr) { throw new Error(`Failed to pack: ${pack.stderr}`); } console.log('Packed CLI', pack.stdout); - - // TODO add built assets to release - // or s3 bucket } main(); From f2ba3d6d5019f81cd273252032fafd96a849a563 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 23 Apr 2024 15:41:10 +0200 Subject: [PATCH 20/22] upload assets --- .github/workflows/release-cli-assets.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/release-cli-assets.yml b/.github/workflows/release-cli-assets.yml index 6f2e119bc..6f4279e84 100644 --- a/.github/workflows/release-cli-assets.yml +++ b/.github/workflows/release-cli-assets.yml @@ -43,3 +43,17 @@ jobs: run: pnpm run release:cli env: MATRIX_OS: ${{ matrix.os }} + + - name: Upload artifacts MacOS + uses: actions/upload-artifact@v3 + if: matrix.os == 'macos-latest' + with: + name: upload-macos + path: 'cli/dist/macos/*' + + - name: Upload artifacts Linux + uses: actions/upload-artifact@v3 + if: matrix.os == 'ubuntu-latest' + with: + name: upload-deb + path: 'cli/dist/deb/*' From b6d084286e95b91e6cdd6f04d49039dc4d68d754 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 23 Apr 2024 16:32:54 +0200 Subject: [PATCH 21/22] use dynamic versions --- .github/workflows/release-cli-assets.yml | 20 ++++++------------ scripts/release-cli.ts | 27 ++++++++++++++++++++---- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/.github/workflows/release-cli-assets.yml b/.github/workflows/release-cli-assets.yml index 6f4279e84..f193dfa00 100644 --- a/.github/workflows/release-cli-assets.yml +++ b/.github/workflows/release-cli-assets.yml @@ -44,16 +44,10 @@ jobs: env: MATRIX_OS: ${{ matrix.os }} - - name: Upload artifacts MacOS - uses: actions/upload-artifact@v3 - if: matrix.os == 'macos-latest' - with: - name: upload-macos - path: 'cli/dist/macos/*' - - - name: Upload artifacts Linux - uses: actions/upload-artifact@v3 - if: matrix.os == 'ubuntu-latest' - with: - name: upload-deb - path: 'cli/dist/deb/*' + # - name: Upload assets to GH + # uses: softprops/action-gh-release@v2 + # if: startsWith(github.ref, 'refs/tags/') + # with: + # files: | + # cli/macos + # cli/deb diff --git a/scripts/release-cli.ts b/scripts/release-cli.ts index e7543f47a..52ef0e59d 100644 --- a/scripts/release-cli.ts +++ b/scripts/release-cli.ts @@ -6,6 +6,10 @@ import * as util from 'util'; const exec = util.promisify(execRaw); const PATH_TO_CLI = process.cwd() + '/cli'; +const PATH_TO_CLIENT = process.cwd() + '/packages/client'; +const PATH_TO_CODEGEN = process.cwd() + '/packages/codegen'; +const PATH_TO_IMPORTER = process.cwd() + '/packages/importer'; +const PATH_TO_PGROLL = process.cwd() + '/packages/pgroll'; const matrixToOclif = (os: string) => { switch (os) { @@ -26,15 +30,30 @@ async function main() { const operatingSystem = matrixToOclif(process.env.MATRIX_OS); const { manifest, fileName } = await readProjectManifest(PATH_TO_CLI); + const { + manifest: { version: clientVersion } + } = await readProjectManifest(PATH_TO_CLIENT); + const { + manifest: { version: codegenVersion } + } = await readProjectManifest(PATH_TO_CODEGEN); + const { + manifest: { version: importerVersion } + } = await readProjectManifest(PATH_TO_IMPORTER); + const { + manifest: { version: pgrollVersion } + } = await readProjectManifest(PATH_TO_PGROLL); + + // Assume changeset version has been called and all the + // versions in package jsons are up to date const workspaceProtocolPackageManifest = await createExportableManifest(PATH_TO_CLI, { ...manifest, dependencies: { ...manifest.dependencies, - '@xata.io/client': 'next', - '@xata.io/codegen': 'next', - '@xata.io/importer': 'latest', - '@xata.io/pgroll': 'latest' + '@xata.io/client': clientVersion ?? 'latest', + '@xata.io/codegen': codegenVersion ?? 'latest', + '@xata.io/importer': importerVersion ?? 'latest', + '@xata.io/pgroll': pgrollVersion ?? 'latest' } }); From 24be271dc9552a721c51d2a7e5ff74c883c04ce0 Mon Sep 17 00:00:00 2001 From: Emily Date: Wed, 24 Apr 2024 10:55:06 +0200 Subject: [PATCH 22/22] upload assets to release --- .github/workflows/release-cli-assets.yml | 53 --------------- .github/workflows/release.yml | 37 +++++++++++ package.json | 1 + pnpm-lock.yaml | 83 ++++++++++++++++++++++++ scripts/release-cli.ts | 45 ++++++++++++- 5 files changed, 164 insertions(+), 55 deletions(-) delete mode 100644 .github/workflows/release-cli-assets.yml diff --git a/.github/workflows/release-cli-assets.yml b/.github/workflows/release-cli-assets.yml deleted file mode 100644 index f193dfa00..000000000 --- a/.github/workflows/release-cli-assets.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Release CLI Assets - -on: - push: - branches: - - release-assets - -concurrency: ${{ github.workflow }}-${{ github.ref }} - -jobs: - release: - name: Release CLI Assets - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - steps: - - uses: actions/checkout@v3 - with: - # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits - fetch-depth: 0 - # This makes the PR pushed to use GITHUB_TOKEN and trigger the checks - persist-credentials: false - - - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: 8 - - - name: Use Node.js ${{ steps.config.outputs.NVMRC }} - uses: actions/setup-node@v3 - with: - node-version: ${{ steps.config.outputs.NVMRC }} - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build - run: pnpm build - - - name: Release CLI - run: pnpm run release:cli - env: - MATRIX_OS: ${{ matrix.os }} - - # - name: Upload assets to GH - # uses: softprops/action-gh-release@v2 - # if: startsWith(github.ref, 'refs/tags/') - # with: - # files: | - # cli/macos - # cli/deb diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9c4f6aa52..e3b48f417 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,3 +66,40 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + release-cli-assets: + name: Release CLI assets + needs: release + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + steps: + - uses: actions/checkout@v3 + with: + # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits + fetch-depth: 0 + # This makes the PR pushed to use GITHUB_TOKEN and trigger the checks + persist-credentials: false + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Use Node.js ${{ steps.config.outputs.NVMRC }} + uses: actions/setup-node@v3 + with: + node-version: ${{ steps.config.outputs.NVMRC }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm build + + - name: Release CLI Assets + run: npx changeset version && pnpm run release:cli + env: + MATRIX_OS: ${{ matrix.os }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index 6beabb32f..f4b0af7f2 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,7 @@ "pnpm": "8.x" }, "dependencies": { + "@octokit/core": "^6.1.2", "@pnpm/exportable-manifest": "^6.0.0", "@pnpm/read-project-manifest": "^6.0.0", "@pnpm/write-project-manifest": "^6.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 74f9fb106..9991d9360 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,9 @@ settings: importers: .: dependencies: + '@octokit/core': + specifier: ^6.1.2 + version: 6.1.2 '@pnpm/exportable-manifest': specifier: ^6.0.0 version: 6.0.0 @@ -4991,6 +4994,76 @@ packages: - supports-color dev: true + /@octokit/auth-token@5.1.1: + resolution: + { integrity: sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA== } + engines: { node: '>= 18' } + dev: false + + /@octokit/core@6.1.2: + resolution: + { integrity: sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg== } + engines: { node: '>= 18' } + dependencies: + '@octokit/auth-token': 5.1.1 + '@octokit/graphql': 8.1.1 + '@octokit/request': 9.1.1 + '@octokit/request-error': 6.1.1 + '@octokit/types': 13.4.1 + before-after-hook: 3.0.2 + universal-user-agent: 7.0.2 + dev: false + + /@octokit/endpoint@10.1.1: + resolution: + { integrity: sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q== } + engines: { node: '>= 18' } + dependencies: + '@octokit/types': 13.4.1 + universal-user-agent: 7.0.2 + dev: false + + /@octokit/graphql@8.1.1: + resolution: + { integrity: sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg== } + engines: { node: '>= 18' } + dependencies: + '@octokit/request': 9.1.1 + '@octokit/types': 13.4.1 + universal-user-agent: 7.0.2 + dev: false + + /@octokit/openapi-types@22.1.0: + resolution: + { integrity: sha512-pGUdSP+eEPfZiQHNkZI0U01HLipxncisdJQB4G//OAmfeO8sqTQ9KRa0KF03TUPCziNsoXUrTg4B2Q1EX++T0Q== } + dev: false + + /@octokit/request-error@6.1.1: + resolution: + { integrity: sha512-1mw1gqT3fR/WFvnoVpY/zUM2o/XkMs/2AszUUG9I69xn0JFLv6PGkPhNk5lbfvROs79wiS0bqiJNxfCZcRJJdg== } + engines: { node: '>= 18' } + dependencies: + '@octokit/types': 13.4.1 + dev: false + + /@octokit/request@9.1.1: + resolution: + { integrity: sha512-pyAguc0p+f+GbQho0uNetNQMmLG1e80WjkIaqqgUkihqUp0boRU6nKItXO4VWnr+nbZiLGEyy4TeKRwqaLvYgw== } + engines: { node: '>= 18' } + dependencies: + '@octokit/endpoint': 10.1.1 + '@octokit/request-error': 6.1.1 + '@octokit/types': 13.4.1 + universal-user-agent: 7.0.2 + dev: false + + /@octokit/types@13.4.1: + resolution: + { integrity: sha512-Y73oOAzRBAUzR/iRAbGULzpNkX8vaxKCqEtg6K74Ff3w9f5apFnWtE/2nade7dMWWW3bS5Kkd6DJS4HF04xreg== } + dependencies: + '@octokit/openapi-types': 22.1.0 + dev: false + /@open-draft/deferred-promise@2.2.0: resolution: { integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA== } @@ -7882,6 +7955,11 @@ packages: { integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== } dev: false + /before-after-hook@3.0.2: + resolution: + { integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A== } + dev: false + /better-ajv-errors@1.2.0(ajv@8.12.0): resolution: { integrity: sha512-UW+IsFycygIo7bclP9h5ugkNH8EjCSgqyFB/yQ4Hqqa1OEYDtb0uFIkYE0b6+CjkgJYVM5UKI/pJPxjYe9EZlA== } @@ -16428,6 +16506,11 @@ packages: unist-util-is: 4.1.0 dev: true + /universal-user-agent@7.0.2: + resolution: + { integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q== } + dev: false + /universalify@0.1.2: resolution: { integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== } diff --git a/scripts/release-cli.ts b/scripts/release-cli.ts index 52ef0e59d..193f187d9 100644 --- a/scripts/release-cli.ts +++ b/scripts/release-cli.ts @@ -1,7 +1,9 @@ import { createExportableManifest } from '@pnpm/exportable-manifest'; import { readProjectManifest } from '@pnpm/read-project-manifest'; import { writeProjectManifest } from '@pnpm/write-project-manifest'; -import { execFile, execFileSync, exec as execRaw } from 'child_process'; +import { execFile, exec as execRaw } from 'child_process'; +import { Octokit } from '@octokit/core'; +import fs from 'fs'; import * as util from 'util'; const exec = util.promisify(execRaw); @@ -11,6 +13,14 @@ const PATH_TO_CODEGEN = process.cwd() + '/packages/codegen'; const PATH_TO_IMPORTER = process.cwd() + '/packages/importer'; const PATH_TO_PGROLL = process.cwd() + '/packages/pgroll'; +const base = { + owner: 'xataio', + repo: 'client-ts', + headers: { + 'X-GitHub-Api-Version': '2022-11-28' + } +}; + const matrixToOclif = (os: string) => { switch (os) { case 'windows-latest': @@ -26,6 +36,7 @@ const matrixToOclif = (os: string) => { async function main() { if (!process.env.MATRIX_OS) throw new Error('MATRIX_OS is not set'); + if (!process.env.GITHUB_TOKEN) throw new Error('GITHUB_TOKEN is not set'); const operatingSystem = matrixToOclif(process.env.MATRIX_OS); @@ -68,7 +79,37 @@ async function main() { if (pack.stderr) { throw new Error(`Failed to pack: ${pack.stderr}`); } - console.log('Packed CLI', pack.stdout); + console.log('Successfully packed CLI', pack.stdout); + + const octokit = new Octokit({ + auth: process.env.GITHUB_TOKEN + }); + + const tag = encodeURIComponent(`@xata.io/cli@${manifest.version}`); + + const release = await octokit.request('GET /repos/{owner}/{repo}/releases/tags/{tag}', { + ...base, + tag + }); + + if (!release.data) throw new Error('Release not found'); + + const pathToAsset = `${PATH_TO_CLI}/dist/${operatingSystem}`; + + const files = fs.readdirSync(pathToAsset); + + for (const file of files) { + const data = fs.readFileSync(pathToAsset + `/${file}`); + const upload = await octokit.request('POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}', { + ...base, + name: file, + label: file, + release_id: release.data.id, + data: data, + baseUrl: 'https://uploads.github.com' + }); + console.log('Finished uploading asset', upload.status); + } } main();