puerto 0.14.0

Puerto — Rust full-stack DDD framework CLI. Scaffolds Clean Architecture projects with auto-wired DI, SQLx support, and zero manual wiring. Formerly puerto-framework.
import { {{ pascal }}Error } from "../domain/{{ kebab }}/errors";
import type { {{ pascal }}, {{ pascal }}Draft } from "../domain/{{ kebab }}/model";
import type { {{ pascal }}Repository } from "../domain/{{ kebab }}/repository";

/** Valid {{ words_plural }} for tests; pass `overrides` for the fields a test is about. */
export const {{ pascal }}Mother = {
  draft(overrides: Partial<{{ pascal }}Draft> = {}): {{ pascal }}Draft {
    return {
{%- for f in fields %}
      {{ f.camel }}: {{ f.mother }},
{%- endfor %}
      ...overrides,
    };
  },

  random(overrides: Partial<{{ pascal }}> = {}): {{ pascal }} {
    return { id: crypto.randomUUID(), ...{{ pascal }}Mother.draft(), ...overrides };
  },
};

/** An in-memory `{{ pascal }}Repository`. Override a method to make it fail. */
export function fake{{ pascal }}Repository(seed: {{ pascal }}[] = []): {{ pascal }}Repository {
  const store = new Map(seed.map((item) => [item.id, item]));
  const find = (id: string) => {
    const found = store.get(id);
    if (found === undefined) throw new {{ pascal }}Error("{{ snake }}.not_found");
    return found;
  };
  return {
    list: async ({ limit, offset }) => {
      const all = [...store.values()];
      return { items: all.slice(offset, offset + limit), total: all.length, limit, offset };
    },
    get: async (id) => find(id),
    create: async (draft) => {
      const created = { id: crypto.randomUUID(), ...draft };
      store.set(created.id, created);
      return created;
    },
    update: async (id, draft) => {
      const updated = { ...find(id), ...draft };
      store.set(id, updated);
      return updated;
    },
    remove: async (id) => {
      find(id);
      store.delete(id);
    },
  };
}