Pure template rendering functions for module generation.
This namespace provides pure functions for transforming entity definitions into code templates. All functions are deterministic and have no side effects.
Pure template rendering functions for module generation. This namespace provides pure functions for transforming entity definitions into code templates. All functions are deterministic and have no side effects.
(build-entity-context entity-def module-name)Build template context for an entity.
Args: entity-def - Entity definition map module-name - Module name string
Returns: Map with template placeholders for the entity
Pure: true
Build template context for an entity. Args: entity-def - Entity definition map module-name - Module name string Returns: Map with template placeholders for the entity Pure: true
(build-field-context field-def)Build template context for a single field.
Args: field-def - Field definition map
Returns: Map with template placeholders for the field
Pure: true
Build template context for a single field. Args: field-def - Field definition map Returns: Map with template placeholders for the field Pure: true
(build-module-context request)Build complete template context for module generation.
Args: request - Module generation request map
Returns: Map with all template placeholders
Pure: true
Build complete template context for module generation. Args: request - Module generation request map Returns: Map with all template placeholders Pure: true
What a relation may name as its target.
references is interpolated into DDL, so it is an allowlist rather than a
blocklist: letters, digits and single interior hyphens, starting with a
letter. invoice);drop/**/table/**/users;-- passed a blankness check, came
through pascal->kebab intact, and closed the CREATE TABLE at invoice)
with a DROP behind it (BOU-480 review).
What a relation may name as its target. `references` is interpolated into DDL, so it is an allowlist rather than a blocklist: letters, digits and single interior hyphens, starting with a letter. `invoice);drop/**/table/**/users;--` passed a blankness check, came through `pascal->kebab` intact, and closed the CREATE TABLE at `invoice)` with a DROP behind it (BOU-480 review).
(field-type->malli {:keys [type enum-values]})Convert scaffolder field type to Malli schema type.
Args: field-def - Field definition map with :type key
Returns: Malli schema keyword or vector
Pure: true
Example: (field-type->malli {:type :string}) => :string (field-type->malli {:type :enum :enum-values [:a :b]}) => [:enum :a :b]
Convert scaffolder field type to Malli schema type.
Args:
field-def - Field definition map with :type key
Returns:
Malli schema keyword or vector
Pure: true
Example:
(field-type->malli {:type :string}) => :string
(field-type->malli {:type :enum :enum-values [:a :b]}) => [:enum :a :b](field-type->sql {:keys [type]})Convert scaffolder field type to SQL type.
Generates PostgreSQL-compatible types. The production DDL generator in platform/utils/schema.clj handles dialect-specific conversions.
Args: field-def - Field definition map with :type key
Returns: SQL type string
Pure: true
Example: (field-type->sql {:type :string}) => "VARCHAR(255)" (field-type->sql {:type :uuid}) => "UUID"
Convert scaffolder field type to SQL type.
Generates PostgreSQL-compatible types. The production DDL generator
in platform/utils/schema.clj handles dialect-specific conversions.
Args:
field-def - Field definition map with :type key
Returns:
SQL type string
Pure: true
Example:
(field-type->sql {:type :string}) => "VARCHAR(255)"
(field-type->sql {:type :uuid}) => "UUID"(kebab->pascal s)Convert kebab-case to PascalCase.
Args: s - String in kebab-case
Returns: String in PascalCase
Pure: true
Example: (kebab->pascal "user-profile") => "UserProfile"
Convert kebab-case to PascalCase. Args: s - String in kebab-case Returns: String in PascalCase Pure: true Example: (kebab->pascal "user-profile") => "UserProfile"
(kebab->snake s)Convert kebab-case to snake_case.
Args: s - String in kebab-case
Returns: String in snake_case
Pure: true
Example: (kebab->snake "user-profile") => "user_profile"
Convert kebab-case to snake_case. Args: s - String in kebab-case Returns: String in snake_case Pure: true Example: (kebab->snake "user-profile") => "user_profile"
(ns->path s)Filesystem path for a namespace: dots become slashes, hyphens underscores.
The rule Clojure itself uses to find a namespace's file. A module called
invoice-line-item has namespaces <base>.invoice-line-item.*, so its
sources have to live in invoice_line_item/ — written with the hyphen they
were unloadable (BOU-447).
Pure: true
Example: (ns->path "my-app.invoice-line-item") => "my_app/invoice_line_item"
Filesystem path for a namespace: dots become slashes, hyphens underscores. The rule Clojure itself uses to find a namespace's file. A module called `invoice-line-item` has namespaces `<base>.invoice-line-item.*`, so its sources have to live in `invoice_line_item/` — written with the hyphen they were unloadable (BOU-447). Pure: true Example: (ns->path "my-app.invoice-line-item") => "my_app/invoice_line_item"
The ON DELETE actions a relation field may ask for.
An unknown one is refused at parse time rather than pasted into the DDL, where it would fail at migration time in whatever words the database chooses.
The `ON DELETE` actions a relation field may ask for. An unknown one is refused at parse time rather than pasted into the DDL, where it would fail at migration time in whatever words the database chooses.
(pascal->kebab s)Convert PascalCase to kebab-case.
The inverse of kebab->pascal, and the thing str/lower-case cannot do:
lowercasing InvoiceLineItem gives invoicelineitem, and every name
derived from that — the table, the core file, the protocol methods — lost
the word boundaries the entity name carried (BOU-480).
A run of capitals is one word, so HTTPRequest is http-request rather
than h-t-t-p-request. Digits stay attached to the word they follow.
Pure: true
Example: (pascal->kebab "InvoiceLineItem") => "invoice-line-item" (pascal->kebab "HTTPRequest") => "http-request" (pascal->kebab "Product") => "product"
Convert PascalCase to kebab-case. The inverse of `kebab->pascal`, and the thing `str/lower-case` cannot do: lowercasing `InvoiceLineItem` gives `invoicelineitem`, and every name derived from that — the table, the core file, the protocol methods — lost the word boundaries the entity name carried (BOU-480). A run of capitals is one word, so `HTTPRequest` is `http-request` rather than `h-t-t-p-request`. Digits stay attached to the word they follow. Pure: true Example: (pascal->kebab "InvoiceLineItem") => "invoice-line-item" (pascal->kebab "HTTPRequest") => "http-request" (pascal->kebab "Product") => "product"
(pluralize s)Simple pluralization (just adds 's' for now).
Args: s - Singular string
Returns: Plural string
Pure: true
Example: (pluralize "customer") => "customers"
Simple pluralization (just adds 's' for now). Args: s - Singular string Returns: Plural string Pure: true Example: (pluralize "customer") => "customers"
(relation-table references)(relation-table references references-table)The table a relation references.
references names an entity — invoice and InvoiceLineItem both work —
and the table is the default pluralisation of it, which is what the target
module's own generator would have produced.
references-table overrides that. An entity is free to declare a
:plural, and the scaffolder generates one module at a time, so it cannot
see that a Person in another module decided its table is people rather
than persons (BOU-480 review).
Returns nil for anything that is not a valid identifier; the request schema refuses those before generation, and core does not throw.
Pure: true
Example: (relation-table "invoice" nil) => "invoices" (relation-table "InvoiceLineItem" nil) => "invoice_line_items" (relation-table "person" "people") => "people"
The table a relation references. `references` names an entity — `invoice` and `InvoiceLineItem` both work — and the table is the default pluralisation of it, which is what the target module's own generator would have produced. `references-table` overrides that. An entity is free to declare a `:plural`, and the scaffolder generates one module at a time, so it cannot see that a `Person` in another module decided its table is `people` rather than `persons` (BOU-480 review). Returns nil for anything that is not a valid identifier; the request schema refuses those before generation, and core does not throw. Pure: true Example: (relation-table "invoice" nil) => "invoices" (relation-table "InvoiceLineItem" nil) => "invoice_line_items" (relation-table "person" "people") => "people"
What references-table may be: a lowercase SQL identifier.
What `references-table` may be: a lowercase SQL identifier.
(valid-entity-name? s)Whether s is something a relation may reference.
Pure: true
Whether `s` is something a relation may reference. Pure: true
(valid-table-name? s)Whether s is something that may be written as a table identifier.
Pure: true
Whether `s` is something that may be written as a table identifier. Pure: true
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |