Skip to content
This repository was archived by the owner on Mar 1, 2026. It is now read-only.
10 changes: 5 additions & 5 deletions packages/language/res/stdlib.zmodel
Original file line number Diff line number Diff line change
Expand Up @@ -83,25 +83,25 @@ function now(): DateTime {
/**
* Generates a globally unique identifier based on the UUID specs.
*/
function uuid(version: Int?): String {
function uuid(version: Int?, format: String?): String {
} @@@expressionContext([DefaultValue])
Comment thread
sanny-io marked this conversation as resolved.

/**
* Generates a globally unique identifier based on the CUID spec.
*/
function cuid(version: Int?): String {
function cuid(version: Int?, format: String?): String {
} @@@expressionContext([DefaultValue])
Comment thread
sanny-io marked this conversation as resolved.

/**
* Generates an identifier based on the nanoid spec.
*/
function nanoid(length: Int?): String {
function nanoid(length: Int?, format: String?): String {
} @@@expressionContext([DefaultValue])
Comment thread
sanny-io marked this conversation as resolved.

/**
* Generates an identifier based on the ulid spec.
*/
function ulid(): String {
function ulid(format: String?): String {
} @@@expressionContext([DefaultValue])
Comment thread
sanny-io marked this conversation as resolved.

/**
Expand Down Expand Up @@ -356,7 +356,7 @@ enum SortOrder {
attribute @@index(_ fields: FieldReference[], name: String?, map: String?, length: Int?, sort: SortOrder?, clustered: Boolean?, type: IndexType?) @@@prisma

/**
* Defines meta information about the relation.
* Defines meta information about the F.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
*
* @param name: Sometimes (e.g. to disambiguate a relation) Defines the name of the relationship. In an m-n-relation, it also determines the name of the underlying relation table.
* @param fields: A list of fields of the current model
Expand Down
30 changes: 24 additions & 6 deletions packages/orm/src/client/crud/operations/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -860,22 +860,22 @@ export abstract class BaseOperationHandler<Schema extends SchemaDef> {
private evalGenerator(defaultValue: Expression) {
if (ExpressionUtils.isCall(defaultValue)) {
return match(defaultValue.function)
.with('cuid', () => createId())
.with('cuid', () => this.formatGeneratedValue(createId(), defaultValue.args?.[1]))
.with('uuid', () =>
defaultValue.args?.[0] &&
ExpressionUtils.isLiteral(defaultValue.args?.[0]) &&
defaultValue.args[0].value === 7
this.formatGeneratedValue(defaultValue.args[0].value === 7
? uuid.v7()
: uuid.v4(),
: uuid.v4(), defaultValue.args?.[1]),
)
.with('nanoid', () =>
defaultValue.args?.[0] &&
ExpressionUtils.isLiteral(defaultValue.args[0]) &&
typeof defaultValue.args[0].value === 'number'
this.formatGeneratedValue(typeof defaultValue.args[0].value === 'number'
? nanoid(defaultValue.args[0].value)
: nanoid(),
: nanoid(), defaultValue.args?.[1]),
)
.with('ulid', () => ulid())
.with('ulid', () => this.formatGeneratedValue(ulid(), defaultValue.args?.[0]))
.otherwise(() => undefined);
} else if (
ExpressionUtils.isMember(defaultValue) &&
Expand All @@ -893,6 +893,24 @@ export abstract class BaseOperationHandler<Schema extends SchemaDef> {
}
}

private formatGeneratedValue(generated?: string, expr?: Expression) {
if (!generated) {
return undefined;
}

if (!expr || !ExpressionUtils.isLiteral(expr)) {
return generated;
}

const format = expr.value;

invariant(typeof format === 'string', 'generated identifier format value must be a string');
invariant(format.includes('%s'), 'generated identifier format strings must include "%s"');

// replaceAll instead? Does anyone even need that...?
return format.replace('%s', generated);
}

protected async update(
kysely: AnyKysely,
model: string,
Expand Down
Loading
Loading