-
-
Notifications
You must be signed in to change notification settings - Fork 207
Open
Description
Package version
21.6.1
Describe the bug
The nullable column "clientId" does not get initialized so the logical "null" check on the model is not executed as expected.
// The model
export default class CognitoUserPoolClient extends BaseModel {
@column({ isPrimary: true })
declare id: string;
/* ... */
@column()
declare isDefault: boolean;
@column()
declare userPoolId: string;
@column()
declare clientName: string;
@column()
declare clientId: string | null; // <-----
}
// The code
const defaultCognitoUserPoolClient = await CognitoUserPoolClient.firstOrCreate(
{ isDefault: true },
{
userPoolId: 'foo',
clientName: 'bar',
},
);
console.log(defaultCognitoUserPoolClient); // log 1 <--
await defaultCognitoUserPoolClient.refresh();
console.log(defaultCognitoUserPoolClient); // log 2 <--
if (defaultCognitoUserPoolClient.clientId === null) {
// consider null clientId as not created UserPoolClient.
const userPoolClient = await cognitoIdentityProvider.createUserPoolClient(
/* ... */
);
await defaultCognitoUserPoolClient.merge({ clientId: userPoolClient.ClientId }).save();
}
The Problem: the defaultCognitoUserPoolClient.clientId === null
is always false when not calling await defaultCognitoUserPoolClient.refresh();
! The clientId
is just missing in the model.
see log 1 output (BEFORE refresh):
CognitoUserPoolClient {
modelOptions: { connection: 'postgres' },
modelTrx: undefined,
transactionListener: [Function: bound listener],
fillInvoked: false,
cachedGetters: {},
forceUpdate: false,
'$columns': {},
'$attributes': {
isDefault: true,
userPoolId: 'foo',
clientName: 'bar',
id: '019840bf-6aa3-75e6-bee8-7c931db59490',
createdAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US },
updatedAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US }
},
'$original': {
isDefault: true,
userPoolId: 'foo',
clientName: 'bar',
id: '019840bf-6aa3-75e6-bee8-7c931db59490',
createdAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US },
updatedAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US }
},
'$preloaded': {},
'$extras': {},
'$sideloaded': {},
'$isPersisted': true,
'$isDeleted': false,
'$isLocal': true,
isDefault: true,
userPoolId: 'foo',
clientName: 'bar',
id: '019840bf-6aa3-75e6-bee8-7c931db59490',
createdAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US },
updatedAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US }
}
and log 2 output (AFTER refresh):
CognitoUserPoolClient {
modelOptions: { connection: 'postgres' },
modelTrx: undefined,
transactionListener: [Function: bound listener],
fillInvoked: true,
cachedGetters: {},
forceUpdate: false,
'$columns': {},
'$attributes': {
id: '019840bf-6aa3-75e6-bee8-7c931db59490',
createdAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US },
updatedAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US },
isDefault: true,
userPoolId: 'foo',
clientName: 'bar',
clientId: null
},
'$original': {
id: '019840bf-6aa3-75e6-bee8-7c931db59490',
createdAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US },
updatedAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US },
isDefault: true,
userPoolId: 'foo',
clientName: 'bar',
clientId: null
},
'$preloaded': {},
'$extras': {},
'$sideloaded': {},
'$isPersisted': true,
'$isDeleted': false,
'$isLocal': true,
isDefault: true,
userPoolId: 'foo',
clientName: 'bar',
id: '019840bf-6aa3-75e6-bee8-7c931db59490',
createdAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US },
updatedAt: DateTime { ts: 2025-07-25T08:42:23.270+00:00, zone: UTC, locale: en-US },
clientId: null // <-- Exists with correct null value as expected!
}
It is weird that the nullable clientId is just... not there in the model. Of course my IDE will say it is string | null
and that the if-clause work as expected, but the truth is that the expected behavior of Lucid does not match the reality.
Reproduction repo
No response
Metadata
Metadata
Assignees
Labels
No labels