Skip to content

Releases: cleverbrush/framework

@cleverbrush/server@4.0.0

29 Apr 08:22
12f4aa6

Choose a tag to compare

Major Changes

  • 9235c76: Add contract composition utilities — mergeContracts, pickGroups, and omitGroups.

    @cleverbrush/server — contract composition

    Three new functions exported from both @cleverbrush/server and
    @cleverbrush/server/contract make it straightforward to define
    audience-scoped API bundles.

    mergeContracts<A, B>(a, b)

    Combines two ApiContract objects into one frozen contract. Groups that
    only exist in one source are passed through unchanged; groups whose key
    appears in both have their endpoint maps shallowly merged. The TypeScript
    return type is MergedContracts<A, B> — a precise mapped type that reflects
    the combined shape.

    const publicApi  = defineApi({ todos: {...}, auth: {...} });
    const adminApi   = defineApi({ admin: { activityLog: ... } });
    const fullApi    = mergeContracts(publicApi, adminApi);
    // TypeScript: { todos, auth, admin }

    pickGroups<T, K>(contract, ...groups)

    Returns a new frozen contract containing only the listed groups. The return
    type is Pick<T, K> — the compiler sees exactly those groups and nothing
    else.

    const clientApi = pickGroups(fullApi, "todos", "auth");
    // TypeScript: { todos, auth }
    // 'admin' is absent at both the type level and runtime

    omitGroups<T, K>(contract, ...groups)

    Inverse of pickGroups — strips the listed groups and keeps everything else.
    Return type is Omit<T, K>.

    const publicApi = omitGroups(fullApi, "admin", "debug");
    // TypeScript: { todos, auth }

    Bundle isolation pattern

    Define separate entry-point files that export different contract slices:

    shared-contracts/src/public.ts  → export const publicApi  = defineApi({ ... })
    shared-contracts/src/full.ts    → export const fullApi    = mergeContracts(publicApi, adminApi)
    

    Client apps import publicApi; admin apps import fullApi. Admin schemas
    are never included in the client bundle.

Patch Changes

  • Updated dependencies [3bfc1e1]
  • Updated dependencies [cbdfa69]
    • @cleverbrush/schema@4.0.0
    • @cleverbrush/auth@4.0.0
    • @cleverbrush/di@4.0.0

@cleverbrush/server-openapi@4.0.0

29 Apr 08:22
12f4aa6

Choose a tag to compare

Patch Changes

  • Updated dependencies [9235c76]
  • Updated dependencies [3bfc1e1]
  • Updated dependencies [cbdfa69]
    • @cleverbrush/server@4.0.0
    • @cleverbrush/schema@4.0.0
    • @cleverbrush/schema-json@4.0.0
    • @cleverbrush/auth@4.0.0

@cleverbrush/schema@4.0.0

29 Apr 08:23
12f4aa6

Choose a tag to compare

Patch Changes

  • 3bfc1e1: Add named projections to @cleverbrush/knex-schema.

    @cleverbrush/knex-schema — new feature

    • ObjectSchemaBuilder.projection(name, columns) — define a named column subset on the schema.
      Two forms are supported:
      • String-tuple form: .projection('summary', ['id', 'title'] as const) — the column list
        is a readonly string[] const that TypeScript uses to narrow the query result type.
      • Accessor form: .projection('detail', t => [t.id, t.title]) — refactor-safe accessor that
        resolves property names at runtime via the schema's property-descriptor tree.
    • SchemaQueryBuilder.projected(name) — apply a named projection at query time.
      • Restricts the SELECT clause to the registered columns (respecting hasColumnName() mappings).
      • Narrows the TypeScript result type to Pick<Row, Keys> for tuple-form projections.
      • Registered projection names are constrained at the type level — unregistered names are a
        compile-time error.
      • Throws at runtime if combined with .select(), .distinct(), or any aggregate method
        (.count(), .min(), etc.) on the same query.
    • Calling .projection() with a name that is already registered on the schema throws immediately.

    @cleverbrush/schema — internal extension

    • PROJECTION_BRAND unique symbol exported from the core extension system.
    • FixedMethods updated with a 4th TProjections type parameter that accumulates the
      name → keys map as .projection() calls are chained, enabling SchemaQueryBuilder to
      extract the column list at the type level.
    • PropertyDescriptor / PropertyDescriptorInner now accept an optional 4th type parameter
      TPropertyKey extends string = string that carries the property key literal so accessor-form
      descriptors can propagate their key name through the type system.
  • cbdfa69: Add @cleverbrush/otel — OpenTelemetry instrumentation for the framework.

    @cleverbrush/otel (new library)

    End-to-end OpenTelemetry support for @cleverbrush/server, @cleverbrush/orm,
    and @cleverbrush/log. Ships traces, logs, and runtime metrics over OTLP/HTTP
    to any compatible backend (ClickStack, Grafana Tempo, Jaeger, …).

    • setupOtel(config) — bootstraps the Node SDK (traces + logs + metrics)
      with sensible defaults and a single shutdown() hook for graceful exit.
    • tracingMiddleware()@cleverbrush/server middleware that opens a
      SpanKind.SERVER span per request, names it from the endpoint metadata
      (operationId or METHOD route), tags it with HTTP semantic-convention
      attributes, and extracts inbound W3C traceparent headers.
    • instrumentKnex(knex) — wires Knex query / query-response /
      query-error events into SpanKind.CLIENT spans with db.system.name,
      db.namespace, db.operation.name, and db.query.text. Spans are
      automatically parented under the active request span.
    • otelLogSink()@cleverbrush/log sink that emits OTLP log records
      with severity, body, structured attributes, and exception info.
    • traceEnricher() — log enricher that attaches TraceId / SpanId /
      TraceFlags to every event when a span is active.
    • configureOtel(services) — registers ITracer and IMeter in
      @cleverbrush/di.
    • outboundHttpInstrumentations() / runtimeMetrics() — opt-in
      lazy loaders for HTTP / undici / Node runtime metrics auto-instrumentation
      (declared as optional peer dependencies).

    The todo-backend demo is fully wired and ships traces / logs / metrics to
    a ClickStack container included in demos/docker-compose.yml.

    @cleverbrush/log

    • TypedTemplate.template — new optional property on the TypedTemplate<T>
      interface. When present, the Logger uses it as the raw {Property} pattern
      string for messageTemplate, so log events with the same shape are grouped
      correctly in Seq, ClickStack, and other structured-log UIs. ParseStringSchemaBuilder
      now implements this property automatically.
    • correlationIdMiddleware / useLoggingresponseHeader (and the new
      UseLoggingOptions.correlationResponseHeader) now accept false to suppress
      the X-Correlation-Id response header entirely. Useful when OTel's
      traceparent / traceresponse header already provides traceability and a
      second correlation header would be redundant.
    • traceEnricher removed — the globalThis.opentelemetry-based enricher
      that was included in earlier builds has been removed. Use traceEnricher
      from @cleverbrush/otel instead — it reads the active span via
      @opentelemetry/api directly and also captures TraceFlags.

    @cleverbrush/schema

    • ParseStringSchemaBuilder.template — new read-only getter that returns
      the human-readable {Property} pattern string (e.g.
      "Todo created: #{TodoId} \"{Title}\" by user {UserId}"). This satisfies the
      TypedTemplate.template contract, so schema-parsed log templates are
      automatically grouped by shape in structured-log UIs.

@cleverbrush/schema-json@4.0.0

29 Apr 08:23
12f4aa6

Choose a tag to compare

Patch Changes

  • Updated dependencies [3bfc1e1]
  • Updated dependencies [cbdfa69]
    • @cleverbrush/schema@4.0.0

@cleverbrush/scheduler@4.0.0

29 Apr 08:22
12f4aa6

Choose a tag to compare

Patch Changes

  • Updated dependencies [3bfc1e1]
  • Updated dependencies [cbdfa69]
    • @cleverbrush/schema@4.0.0

@cleverbrush/react-form@4.0.0

29 Apr 08:22
12f4aa6

Choose a tag to compare

Patch Changes

  • Updated dependencies [3bfc1e1]
  • Updated dependencies [cbdfa69]
    • @cleverbrush/schema@4.0.0

@cleverbrush/otel@4.0.0

29 Apr 08:22
12f4aa6

Choose a tag to compare

Major Changes

  • cbdfa69: Add @cleverbrush/otel — OpenTelemetry instrumentation for the framework.

    @cleverbrush/otel (new library)

    End-to-end OpenTelemetry support for @cleverbrush/server, @cleverbrush/orm,
    and @cleverbrush/log. Ships traces, logs, and runtime metrics over OTLP/HTTP
    to any compatible backend (ClickStack, Grafana Tempo, Jaeger, …).

    • setupOtel(config) — bootstraps the Node SDK (traces + logs + metrics)
      with sensible defaults and a single shutdown() hook for graceful exit.
    • tracingMiddleware()@cleverbrush/server middleware that opens a
      SpanKind.SERVER span per request, names it from the endpoint metadata
      (operationId or METHOD route), tags it with HTTP semantic-convention
      attributes, and extracts inbound W3C traceparent headers.
    • instrumentKnex(knex) — wires Knex query / query-response /
      query-error events into SpanKind.CLIENT spans with db.system.name,
      db.namespace, db.operation.name, and db.query.text. Spans are
      automatically parented under the active request span.
    • otelLogSink()@cleverbrush/log sink that emits OTLP log records
      with severity, body, structured attributes, and exception info.
    • traceEnricher() — log enricher that attaches TraceId / SpanId /
      TraceFlags to every event when a span is active.
    • configureOtel(services) — registers ITracer and IMeter in
      @cleverbrush/di.
    • outboundHttpInstrumentations() / runtimeMetrics() — opt-in
      lazy loaders for HTTP / undici / Node runtime metrics auto-instrumentation
      (declared as optional peer dependencies).

    The todo-backend demo is fully wired and ships traces / logs / metrics to
    a ClickStack container included in demos/docker-compose.yml.

    @cleverbrush/log

    • TypedTemplate.template — new optional property on the TypedTemplate<T>
      interface. When present, the Logger uses it as the raw {Property} pattern
      string for messageTemplate, so log events with the same shape are grouped
      correctly in Seq, ClickStack, and other structured-log UIs. ParseStringSchemaBuilder
      now implements this property automatically.
    • correlationIdMiddleware / useLoggingresponseHeader (and the new
      UseLoggingOptions.correlationResponseHeader) now accept false to suppress
      the X-Correlation-Id response header entirely. Useful when OTel's
      traceparent / traceresponse header already provides traceability and a
      second correlation header would be redundant.
    • traceEnricher removed — the globalThis.opentelemetry-based enricher
      that was included in earlier builds has been removed. Use traceEnricher
      from @cleverbrush/otel instead — it reads the active span via
      @opentelemetry/api directly and also captures TraceFlags.

    @cleverbrush/schema

    • ParseStringSchemaBuilder.template — new read-only getter that returns
      the human-readable {Property} pattern string (e.g.
      "Todo created: #{TodoId} \"{Title}\" by user {UserId}"). This satisfies the
      TypedTemplate.template contract, so schema-parsed log templates are
      automatically grouped by shape in structured-log UIs.

Patch Changes

  • Updated dependencies [9235c76]
  • Updated dependencies [cbdfa69]
    • @cleverbrush/server@4.0.0
    • @cleverbrush/log@4.0.0
    • @cleverbrush/di@4.0.0

@cleverbrush/orm@1.0.0

29 Apr 08:22
12f4aa6

Choose a tag to compare

Major Changes

  • 6e66e9a: Add @cleverbrush/orm — EF-Core-like typed ORM — and @cleverbrush/orm-cli migration tooling.

    @cleverbrush/orm (new library)

    A typed ORM layer built on top of @cleverbrush/knex-schema that provides:

    • createDb(knex, entityMap, opts?) — creates a DbContext with typed DbSet<TEntity>
      properties for each entry in the entity map. Pass { tracking: true } to get a
      TrackedDbContext with an identity map and change tracker.

    • defineEntity(schema) — wraps a @cleverbrush/knex-schema schema and enables
      fluent relation and variant declarations:

      • .hasOne(sel, EntityDef, fkKey) / .hasMany(sel, EntityDef, fkKey) — child relations
      • .belongsTo(sel, fkKey) — parent relation
      • .belongsToMany(sel, EntityDef, opts) — many-to-many via pivot table
      • .discriminator(key) — marks the entity as polymorphic
      • .stiVariant(key, schema) — Single-Table Inheritance variant (shared table)
      • .ctiVariant(key, EntityDef, fkSel, opts?) — Class-Table Inheritance variant (separate table)
    • DbSet<TEntity> — typed query starter with:

      • .find(pk) / .findOrFail(pk) / .findMany([pk…]) — PK-based lookups
      • .save(graph) — transactional graph persistence with FK propagation
      • .ofVariant(key) — return a typed VariantDbSet scoped to a polymorphic variant
        (analogous to EF Core's Set<DerivedType>())
      • All SchemaQueryBuilder methods (.where(), .include(), .execute(), etc.)
    • VariantDbSet<TEntity, K> — typed handle for a single polymorphic variant:

      • .insert(payload) — insert with discriminator set automatically (STI/CTI aware)
      • .update(patch) / .delete() — scoped writes for rows matched by .where()
      • .find(pk) / .findOrFail(pk) / .findMany([pk…]) — variant-typed lookups
      • .where() / .include() / .withTransaction() — full chain support
      • Calling .insert() / .update() / .delete() on the base polymorphic DbSet
        throws a runtime error; use .ofVariant(key) instead
    • TrackedDbContext additions:

      • Identity map — same PK always returns the same object reference
      • Automatic change detection — mutate entities normally; flush with saveChanges()
      • .attach(key, entity) / .detach(entity) / .entry(entity) — manual tracker control
      • .remove(entity) — mark entity for deletion
      • .saveChanges() — flush all Added / Modified / Deleted entries in one transaction
      • .discardChanges() — roll back all in-memory changes
      • .reload(entity) — re-fetch from DB and refresh snapshot
      • .onSavingChanges(hook) — pre-flush callback for audit fields, etc.
      • [Symbol.asyncDispose]()await using support; throws PendingChangesError on unsaved changes
      • .rowVersion() column support — auto-increments on UPDATE, throws ConcurrencyError on conflict
    • Error classes: EntityNotFoundError, ConcurrencyError, InvariantViolationError,
      PendingChangesError

    @cleverbrush/orm-cli (new library)

    CLI tool for managing PostgreSQL schema migrations from entity definitions:

    • cb-orm migrate generate [name] — diff entity schemas vs live DB, emit typed TS migration file
    • cb-orm migrate run [--to <file>] — apply pending migrations via knex.migrate.latest
    • cb-orm migrate rollback [--all] — roll back last (or all) migration batch(es)
    • cb-orm migrate status — list applied and pending migration files
    • cb-orm db push [--yes] — apply schema diff in-place without a migration file (dev only)

    Config is loaded from db.config.ts in the working directory via defineConfig({ knex, entities, migrations }).

    @cleverbrush/knex-schema (extensions for ORM)

    New schema extension points consumed by @cleverbrush/orm:

    • Entity & relation extensionsdefineEntity, Entity, POLYMORPHIC_TYPE_BRAND,
      getVariants, getPolymorphicVariantSchemas and the full relation-registration API
      (RelationInfo, EntityRelations, EntityPropSelector, etc.)
    • Migration supporttableExistsInDb, introspectDatabase, diffSchema,
      generateCreateTableSource, generateMigration, applyDiff
    • DDL helpersbuildColumnMap, getPrimaryKeyColumns, extractPkValues, buildPkKey
    • Snapshot utilitiessnapshotEntity for change-tracker baseline capture
    • rowVersion() column extension on NumberSchemaBuilder

Patch Changes

  • Updated dependencies [3bfc1e1]
  • Updated dependencies [6e66e9a]
  • Updated dependencies [cbdfa69]
    • @cleverbrush/knex-schema@4.0.0
    • @cleverbrush/schema@4.0.0

@cleverbrush/orm-cli@1.0.0

29 Apr 08:23
12f4aa6

Choose a tag to compare

Major Changes

  • 6e66e9a: Add @cleverbrush/orm — EF-Core-like typed ORM — and @cleverbrush/orm-cli migration tooling.

    @cleverbrush/orm (new library)

    A typed ORM layer built on top of @cleverbrush/knex-schema that provides:

    • createDb(knex, entityMap, opts?) — creates a DbContext with typed DbSet<TEntity>
      properties for each entry in the entity map. Pass { tracking: true } to get a
      TrackedDbContext with an identity map and change tracker.

    • defineEntity(schema) — wraps a @cleverbrush/knex-schema schema and enables
      fluent relation and variant declarations:

      • .hasOne(sel, EntityDef, fkKey) / .hasMany(sel, EntityDef, fkKey) — child relations
      • .belongsTo(sel, fkKey) — parent relation
      • .belongsToMany(sel, EntityDef, opts) — many-to-many via pivot table
      • .discriminator(key) — marks the entity as polymorphic
      • .stiVariant(key, schema) — Single-Table Inheritance variant (shared table)
      • .ctiVariant(key, EntityDef, fkSel, opts?) — Class-Table Inheritance variant (separate table)
    • DbSet<TEntity> — typed query starter with:

      • .find(pk) / .findOrFail(pk) / .findMany([pk…]) — PK-based lookups
      • .save(graph) — transactional graph persistence with FK propagation
      • .ofVariant(key) — return a typed VariantDbSet scoped to a polymorphic variant
        (analogous to EF Core's Set<DerivedType>())
      • All SchemaQueryBuilder methods (.where(), .include(), .execute(), etc.)
    • VariantDbSet<TEntity, K> — typed handle for a single polymorphic variant:

      • .insert(payload) — insert with discriminator set automatically (STI/CTI aware)
      • .update(patch) / .delete() — scoped writes for rows matched by .where()
      • .find(pk) / .findOrFail(pk) / .findMany([pk…]) — variant-typed lookups
      • .where() / .include() / .withTransaction() — full chain support
      • Calling .insert() / .update() / .delete() on the base polymorphic DbSet
        throws a runtime error; use .ofVariant(key) instead
    • TrackedDbContext additions:

      • Identity map — same PK always returns the same object reference
      • Automatic change detection — mutate entities normally; flush with saveChanges()
      • .attach(key, entity) / .detach(entity) / .entry(entity) — manual tracker control
      • .remove(entity) — mark entity for deletion
      • .saveChanges() — flush all Added / Modified / Deleted entries in one transaction
      • .discardChanges() — roll back all in-memory changes
      • .reload(entity) — re-fetch from DB and refresh snapshot
      • .onSavingChanges(hook) — pre-flush callback for audit fields, etc.
      • [Symbol.asyncDispose]()await using support; throws PendingChangesError on unsaved changes
      • .rowVersion() column support — auto-increments on UPDATE, throws ConcurrencyError on conflict
    • Error classes: EntityNotFoundError, ConcurrencyError, InvariantViolationError,
      PendingChangesError

    @cleverbrush/orm-cli (new library)

    CLI tool for managing PostgreSQL schema migrations from entity definitions:

    • cb-orm migrate generate [name] — diff entity schemas vs live DB, emit typed TS migration file
    • cb-orm migrate run [--to <file>] — apply pending migrations via knex.migrate.latest
    • cb-orm migrate rollback [--all] — roll back last (or all) migration batch(es)
    • cb-orm migrate status — list applied and pending migration files
    • cb-orm db push [--yes] — apply schema diff in-place without a migration file (dev only)

    Config is loaded from db.config.ts in the working directory via defineConfig({ knex, entities, migrations }).

    @cleverbrush/knex-schema (extensions for ORM)

    New schema extension points consumed by @cleverbrush/orm:

    • Entity & relation extensionsdefineEntity, Entity, POLYMORPHIC_TYPE_BRAND,
      getVariants, getPolymorphicVariantSchemas and the full relation-registration API
      (RelationInfo, EntityRelations, EntityPropSelector, etc.)
    • Migration supporttableExistsInDb, introspectDatabase, diffSchema,
      generateCreateTableSource, generateMigration, applyDiff
    • DDL helpersbuildColumnMap, getPrimaryKeyColumns, extractPkValues, buildPkKey
    • Snapshot utilitiessnapshotEntity for change-tracker baseline capture
    • rowVersion() column extension on NumberSchemaBuilder

Patch Changes

  • Updated dependencies [3bfc1e1]
  • Updated dependencies [6e66e9a]
    • @cleverbrush/knex-schema@4.0.0

@cleverbrush/mapper@4.0.0

29 Apr 08:22
12f4aa6

Choose a tag to compare

Patch Changes

  • Updated dependencies [3bfc1e1]
  • Updated dependencies [cbdfa69]
    • @cleverbrush/schema@4.0.0