Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: gajus/slonik
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v31.2.0
Choose a base ref
...
head repository: gajus/slonik
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v31.2.1
Choose a head ref
  • 3 commits
  • 5 files changed
  • 2 contributors

Commits on Sep 10, 2022

  1. Copy the full SHA
    d66b76c View commit details
  2. fix: remove ts-expect-error

    gajus committed Sep 10, 2022
    Copy the full SHA
    a1cb585 View commit details
  3. fix: correct test

    gajus committed Sep 10, 2022
    Copy the full SHA
    81a91c0 View commit details
Showing with 44 additions and 14 deletions.
  1. +12 −10 src/factories/createSqlTag.ts
  2. +6 −3 src/types.ts
  3. +1 −1 src/utilities/parseDsn.ts
  4. +19 −0 test/slonik/templateTags/sql/typeAlias.ts
  5. +6 −0 test/slonik/utilities/parseDsn.ts
22 changes: 12 additions & 10 deletions src/factories/createSqlTag.ts
Original file line number Diff line number Diff line change
@@ -109,12 +109,15 @@ const createQuery = (
};
};

type SqlTagConfiguration<B> = {
typeAliases?: Record<string, B>,
};

export const createSqlTag = <B extends ZodTypeAny, T extends QueryResultRow = QueryResultRow>(configuration: SqlTagConfiguration<B> = {}) => {
const typeAliases = configuration.typeAliases ?? {};
export const createSqlTag = <
K extends keyof Z,
P extends ZodTypeAny,
Z extends Record<K, P>,
T extends QueryResultRow = QueryResultRow
>(configuration: {
typeAliases?: Z,
} = {}) => {
const typeAliases = configuration.typeAliases;

const sql = (
parts: readonly string[],
@@ -263,8 +266,8 @@ export const createSqlTag = <B extends ZodTypeAny, T extends QueryResultRow = Qu
};

sql.typeAlias = <Y extends keyof typeof typeAliases>(parserAlias: Y) => {
if (!typeAliases[parserAlias]) {
throw new Error('Type alias "' + parserAlias + '" does not exist.');
if (!typeAliases?.[parserAlias]) {
throw new Error('Type alias "' + String(parserAlias) + '" does not exist.');
}

return sql.type(typeAliases[parserAlias]);
@@ -281,6 +284,5 @@ export const createSqlTag = <B extends ZodTypeAny, T extends QueryResultRow = Qu
};
};

// @ts-expect-error TODO fix
return sql as SqlTaggedTemplate<typeof typeAliases, T>;
return sql as SqlTaggedTemplate<Z, T>;
};
9 changes: 6 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -373,8 +373,11 @@ export type NamedAssignment = {
readonly [key: string]: ValueExpression,
};

export type SqlTaggedTemplate<TypeAliases extends Record<string, ZodTypeAny>, Z extends QueryResultRow = QueryResultRow> = {
<U extends QueryResultRow = Z>(template: TemplateStringsArray, ...values: ValueExpression[]): SqlSqlToken<U>,
export type SqlTaggedTemplate<
Z extends Record<string, ZodTypeAny>,
R extends QueryResultRow = QueryResultRow
> = {
<U extends QueryResultRow = R>(template: TemplateStringsArray, ...values: ValueExpression[]): SqlSqlToken<U>,
array: (
values: readonly PrimitiveValueExpression[],
memberType: SqlToken | TypeNameIdentifier,
@@ -389,7 +392,7 @@ export type SqlTaggedTemplate<TypeAliases extends Record<string, ZodTypeAny>, Z
literalValue: (value: string) => SqlSqlToken,
timestamp: (date: Date) => TimestampSqlToken,
type: <Y extends ZodTypeAny>(parser: Y) => (template: TemplateStringsArray, ...values: ValueExpression[]) => SqlSqlToken<Y>,
typeAlias: <Y extends keyof TypeAliases>(typeAlias: Y) => (template: TemplateStringsArray, ...values: ValueExpression[]) => SqlSqlToken<TypeAliases[Y]>,
typeAlias: <K extends keyof Z>(typeAlias: K) => (template: TemplateStringsArray, ...values: ValueExpression[]) => SqlSqlToken<Z[K]>,
unnest: (
// Value might be ReadonlyArray<ReadonlyArray<PrimitiveValueExpression>>,
// or it can be infinitely nested array, e.g.
2 changes: 1 addition & 1 deletion src/utilities/parseDsn.ts
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ export const parseDsn = (dsn: string): ConnectionOptions => {
const connectionOptions: ConnectionOptions = {};

if (url.host) {
connectionOptions.host = url.hostname;
connectionOptions.host = decodeURIComponent(url.hostname);
}

if (url.port) {
19 changes: 19 additions & 0 deletions test/slonik/templateTags/sql/typeAlias.ts
Original file line number Diff line number Diff line change
@@ -40,3 +40,22 @@ test('describes zod object associated with the query', (t) => {

t.is(query.parser, typeAliases.id);
});

test('cannot alias unknown fields', (t) => {
const typeAliases = {
id: z.object({
id: z.number(),
}),
};

const sql = createSqlTag({
typeAliases,
});

t.throws(() => {
// @ts-expect-error
sql.typeAlias('void')`
SELECT 1 id
`;
});
});
6 changes: 6 additions & 0 deletions test/slonik/utilities/parseDsn.ts
Original file line number Diff line number Diff line change
@@ -41,3 +41,9 @@ test('postgresql://fo%2Fo:b%2Far@localhost/ba%2Fz', testParse, {
password: 'b/ar',
username: 'fo/o',
});
test('postgresql://db_user:db_password@%2Fcloudsql%2Fproject-id%3Aregion-id1%3Acloudsqlinstance-name/dbname', testParse, {
databaseName: 'dbname',
host: '/cloudsql/project-id:region-id1:cloudsqlinstance-name',
password: 'db_password',
username: 'db_user',
});