diff --git a/integration-tests/lts/literals.test.ts b/integration-tests/lts/literals.test.ts index 99c7c3bed..a9e5e165a 100644 --- a/integration-tests/lts/literals.test.ts +++ b/integration-tests/lts/literals.test.ts @@ -2,7 +2,7 @@ import assert from "node:assert/strict"; import * as edgedb from "edgedb"; import { TypeKind } from "edgedb/dist/reflection"; import e from "./dbschema/edgeql-js"; -import { setupTests } from "./setupTeardown"; +import { setupTests, versionGTE } from "./setupTeardown"; describe("literals", () => { test("literals", () => { @@ -68,26 +68,50 @@ describe("literals", () => { e.std.uuid(uuid).toEdgeQL(), `"317fee4c-0da5-45aa-9980-fedac211bfb6"`, ); - assert.equal( - e.cal.local_date(localdate).toEdgeQL(), - `'2021-10-31'`, - ); - assert.equal( - e.cal.local_datetime(localdatetime).toEdgeQL(), - `'2021-10-31T21:45:30'`, - ); - assert.equal( - e.cal.local_time(localtime).toEdgeQL(), - `'15:15:00'`, - ); - assert.equal( - e.cal.relative_duration(relduration).toEdgeQL(), - `'P1Y2M21D'`, - ); - assert.equal( - e.cal.date_duration(dateduration).toEdgeQL(), - `'P1Y2M25D'`, - ); + + if (versionGTE(6)) { + assert.equal( + e.cal.local_date(localdate).toEdgeQL(), + `'2021-10-31'`, + ); + assert.equal( + e.cal.local_datetime(localdatetime).toEdgeQL(), + `'2021-10-31T21:45:30'`, + ); + assert.equal( + e.cal.local_time(localtime).toEdgeQL(), + `'15:15:00'`, + ); + assert.equal( + e.cal.relative_duration(relduration).toEdgeQL(), + `'P1Y2M21D'`, + ); + assert.equal( + e.cal.date_duration(dateduration).toEdgeQL(), + `'P1Y2M25D'`, + ); + } else { + assert.equal( + e.cal.local_date(localdate).toEdgeQL(), + `'2021-10-31'`, + ); + assert.equal( + e.cal.local_datetime(localdatetime).toEdgeQL(), + `'2021-10-31T21:45:30'`, + ); + assert.equal( + e.cal.local_time(localtime).toEdgeQL(), + `'15:15:00'`, + ); + assert.equal( + e.cal.relative_duration(relduration).toEdgeQL(), + `'P1Y2M21D'`, + ); + assert.equal( + e.cal.date_duration(dateduration).toEdgeQL(), + `'P1Y2M25D'`, + ); + } }); test("collection type literals", () => { diff --git a/integration-tests/lts/params.test.ts b/integration-tests/lts/params.test.ts index faa22b122..44ce54247 100644 --- a/integration-tests/lts/params.test.ts +++ b/integration-tests/lts/params.test.ts @@ -103,9 +103,11 @@ SELECT (SELECT { tuple: readonly [string, number, readonly boolean[]]; namedTuple: Readonly<{ a: number; b: readonly bigint[]; c: string }>; jsonTuple: readonly [unknown]; - people: Readonly< - { name: string; age: number; tags: readonly string[] }[] - >; + people: readonly { + name: string; + age: number; + tags: readonly string[]; + }[]; } > >(true); diff --git a/packages/generate/src/edgeql-js.ts b/packages/generate/src/edgeql-js.ts index 144d0ccf0..e72a4919e 100644 --- a/packages/generate/src/edgeql-js.ts +++ b/packages/generate/src/edgeql-js.ts @@ -179,6 +179,25 @@ export async function generateQueryBuilder(params: { throw new Error(`Error: no syntax files found for target "${target}"`); } + // libs that existed in modules/[lib] and in server v6 moved to modules/std/[lib] + const stdLibs = ["cal", "fts", "math", "pg"]; + + // instead of hardcoding we can check generated files inside modules/std + // if (version.major > 5) { + // const stdPath = path.join(prettyOutputDir, "modules", "std"); + // const filenames = await fs.readdir(stdPath); + + // for (const fname of filenames) { + // const fullPath = path.join(stdPath, fname); + // const fileStat = await fs.stat(fullPath); + + // if (fileStat.isFile()) { + // const libName = path.parse(fname).name; + // stdLibs.push(libName); + // } + // } + // } + for (const f of syntaxFiles) { const outputPath = path.join(syntaxOutDir, f.path); written.add(outputPath); @@ -187,7 +206,18 @@ export async function generateQueryBuilder(params: { .then((content) => content) .catch(() => ""); - const newContents = headerComment + f.content; + let newContents = headerComment + f.content; + + // in server versions >=6 cal, fts, math and pg are moved inside std module + if (version.major > 5) { + stdLibs.forEach((lib) => { + newContents = newContents.replace( + `modules/${lib}`, + `modules/std/${lib}`, + ); + }); + } + if (oldContents !== newContents) { await fs.writeFile(outputPath, newContents); } diff --git a/packages/generate/src/edgeql-js/generateCastMaps.ts b/packages/generate/src/edgeql-js/generateCastMaps.ts index 479ceb79a..d7a506f47 100644 --- a/packages/generate/src/edgeql-js/generateCastMaps.ts +++ b/packages/generate/src/edgeql-js/generateCastMaps.ts @@ -3,7 +3,7 @@ import type { GeneratorParams } from "../genutil"; import { getRef, joinFrags, - literalToScalarMapping, + getLiteralToScalarMapping, quote, scalarToLiteralMapping, } from "../genutil"; @@ -13,9 +13,11 @@ import { getStringRepresentation } from "./generateObjectTypes"; const getRuntimeRef = (name: string) => getRef(name, { prefix: "" }); export const generateCastMaps = (params: GeneratorParams) => { - const { dir, types, casts, typesByName } = params; + const { dir, types, casts, typesByName, edgedbVersion } = params; const { implicitCastMap } = casts; + const literalToScalarMapping = getLiteralToScalarMapping(edgedbVersion); + const f = dir.getPath("castMaps"); f.addImportStar("edgedb", "edgedb"); f.addImportStar("$", "./reflection", { @@ -349,6 +351,7 @@ export const generateCastMaps = (params: GeneratorParams) => { f.writeln([ t` T extends edgedb.MultiRange ? $.MultiRangeType> :`, ]); + // todo probably should be ScalarType or never f.writeln([t` $.BaseType;\n\n`]); f.writeln([ diff --git a/packages/generate/src/genutil.ts b/packages/generate/src/genutil.ts index 6d73c43b9..ba9e5d2fc 100644 --- a/packages/generate/src/genutil.ts +++ b/packages/generate/src/genutil.ts @@ -73,58 +73,91 @@ export const scalarToLiteralMapping: { literalKind: "instanceof", extraTypes: ["string"], }, - "cal::local_datetime": { + "cfg::memory": { + type: "edgedb.ConfigMemory", + literalKind: "instanceof", + extraTypes: ["string"], + }, + "ext::pgvector::vector": { + type: "Float32Array", + literalKind: "instanceof", + extraTypes: ["number[]"], + argTypes: ["number[]"], + }, + // server version >= 6 + // keep this order of mapping, adding firstly mapping as it is in v6 and greater + // then also add mappings as they are in < v6 + "std::cal::local_datetime": { type: "edgedb.LocalDateTime", literalKind: "instanceof", extraTypes: ["string"], }, - "cal::local_date": { + "std::cal::local_date": { type: "edgedb.LocalDate", literalKind: "instanceof", extraTypes: ["string"], }, - "cal::local_time": { + "std::cal::local_time": { type: "edgedb.LocalTime", literalKind: "instanceof", extraTypes: ["string"], }, - "cal::relative_duration": { + "std::cal::relative_duration": { type: "edgedb.RelativeDuration", literalKind: "instanceof", extraTypes: ["string"], }, - "cal::date_duration": { + "std::cal::date_duration": { type: "edgedb.DateDuration", literalKind: "instanceof", extraTypes: ["string"], }, - "cfg::memory": { - type: "edgedb.ConfigMemory", + // server version < 6 + "cal::local_datetime": { + type: "edgedb.LocalDateTime", literalKind: "instanceof", extraTypes: ["string"], }, - "ext::pgvector::vector": { - type: "Float32Array", + "cal::local_date": { + type: "edgedb.LocalDate", literalKind: "instanceof", - extraTypes: ["number[]"], - argTypes: ["number[]"], + extraTypes: ["string"], + }, + "cal::local_time": { + type: "edgedb.LocalTime", + literalKind: "instanceof", + extraTypes: ["string"], + }, + "cal::relative_duration": { + type: "edgedb.RelativeDuration", + literalKind: "instanceof", + extraTypes: ["string"], + }, + "cal::date_duration": { + type: "edgedb.DateDuration", + literalKind: "instanceof", + extraTypes: ["string"], }, }; -export const literalToScalarMapping: { - [key: string]: { type: string; literalKind: "typeof" | "instanceof" }; -} = {}; -for (const [scalarType, { type, literalKind }] of Object.entries( - scalarToLiteralMapping, -)) { - if (literalKind) { - if (literalToScalarMapping[type]) { - throw new Error( - `literal type '${type}' cannot be mapped to multiple scalar types`, - ); +export function getLiteralToScalarMapping(version: Version) { + const literalToScalarMapping: { + [key: string]: { type: string; literalKind: "typeof" | "instanceof" }; + } = {}; + + for (const [scalarType, { type, literalKind }] of Object.entries( + scalarToLiteralMapping, + )) { + if (literalKind) { + if (literalToScalarMapping[type] && version.major > 5) { + // there's for example edgedb.LocalTime that maps to the std::cal::local_time + // if the server version > 5 continue, otherwise overwrite this mapping with cal::local_time + continue; + } + literalToScalarMapping[type] = { type: scalarType, literalKind }; } - literalToScalarMapping[type] = { type: scalarType, literalKind }; } + return literalToScalarMapping; } export function toTSScalarType( diff --git a/packages/generate/tsconfig.build.json b/packages/generate/tsconfig.build.json index c1ee44b3f..8ba8068ad 100644 --- a/packages/generate/tsconfig.build.json +++ b/packages/generate/tsconfig.build.json @@ -1,12 +1,8 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "outDir": "dist", + "outDir": "dist" }, - "include": [ - "src" - ], - "exclude": [ - "dist" - ] + "include": ["src"], + "exclude": ["dist"] }