import { z } from "zod";
const defaultCreateResponseSchema = z.object({ id: z.string().uuid().nullable() });
const defaultOkResponseSchema = z.object({ ok: z.literal(true) });
function createPagedListResponseSchema(itemSchema, options = {}) {
  const paginationMetaOptional = options.paginationMetaOptional ?? false;
  return z.object({
    items: z.array(itemSchema),
    total: z.number(),
    page: paginationMetaOptional ? z.number().optional() : z.number(),
    pageSize: paginationMetaOptional ? z.number().optional() : z.number(),
    totalPages: z.number(),
    // Present (true) only when the list count was bounded at OM_LIST_COUNT_CAP:
    // `total` is then a floor, not an exact value.
    totalIsCapped: z.boolean().optional()
  });
}
function withIdsQueryParam(schema) {
  if (!schema) return schema;
  if (!(schema instanceof z.ZodObject)) return schema;
  return schema.extend({
    ids: z.string().optional().describe("Comma-separated list of record UUIDs to filter by (max 200).")
  });
}
function resolveDefault(factory, ctx, fallback) {
  if (typeof factory === "function") return factory(ctx);
  return fallback;
}
function createCrudOpenApiFactory(config) {
  return function createCrudOpenApi(options) {
    const {
      resourceName,
      pluralName,
      tag,
      description,
      querySchema,
      listResponseSchema,
      create,
      update,
      del
    } = options;
    const plural = pluralName ?? `${resourceName}s`;
    const resourceLower = resourceName.toLowerCase();
    const pluralLower = plural.toLowerCase();
    const context = {
      resourceName,
      resourceLower,
      pluralName: plural,
      pluralLower
    };
    const fallbackCreateResponseSchema = config.defaultCreateResponseSchema ?? defaultCreateResponseSchema;
    const fallbackOkResponseSchema = config.defaultOkResponseSchema ?? defaultOkResponseSchema;
    const methods = {};
    methods.GET = {
      summary: `List ${pluralLower}`,
      description: description ?? resolveDefault(config.makeListDescription, context, `Returns a paginated collection of ${pluralLower}.`),
      query: withIdsQueryParam(querySchema),
      responses: [
        {
          status: 200,
          description: `Paginated ${pluralLower}`,
          schema: listResponseSchema
        }
      ]
    };
    if (create) {
      const createDescription = create.description ?? resolveDefault(config.makeCreateDescription, context, `Creates a new ${resourceLower}.`);
      const createBodyDescription = resolveDefault(
        config.makeCreateRequestBodyDescription,
        context,
        create.description ?? `Payload describing the ${resourceLower} to create.`
      );
      methods.POST = {
        summary: `Create ${resourceLower}`,
        description: createDescription,
        requestBody: {
          schema: create.schema,
          description: createBodyDescription
        },
        responses: [
          {
            status: create.status ?? 201,
            description: `${resourceName} created`,
            schema: create.responseSchema ?? fallbackCreateResponseSchema
          }
        ]
      };
    }
    if (update) {
      const updateDescription = update.description ?? resolveDefault(config.makeUpdateDescription, context, `Updates an existing ${resourceLower} by id.`);
      const updateBodyDescription = resolveDefault(
        config.makeUpdateRequestBodyDescription,
        context,
        update.description ?? `Fields to update on the ${resourceLower}.`
      );
      methods.PUT = {
        summary: `Update ${resourceLower}`,
        description: updateDescription,
        requestBody: {
          schema: update.schema,
          description: updateBodyDescription
        },
        responses: [
          {
            status: 200,
            description: `${resourceName} updated`,
            schema: update.responseSchema ?? fallbackOkResponseSchema
          }
        ]
      };
    }
    if (del) {
      const deleteDescription = del.description ?? resolveDefault(config.makeDeleteDescription, context, `Deletes a ${resourceLower} identified by id.`);
      const deleteBodyDescription = resolveDefault(
        config.makeDeleteRequestBodyDescription,
        context,
        del.description ?? "Identifier payload."
      );
      methods.DELETE = {
        summary: `Delete ${resourceLower}`,
        description: deleteDescription,
        requestBody: del.schema ? {
          schema: del.schema,
          description: deleteBodyDescription
        } : void 0,
        responses: [
          {
            status: 200,
            description: `${resourceName} deleted`,
            schema: del.responseSchema ?? fallbackOkResponseSchema
          }
        ],
        ...del.errors && del.errors.length > 0 ? { errors: del.errors } : {}
      };
    }
    return {
      tag: tag ?? config.defaultTag,
      summary: `${resourceName} management`,
      methods
    };
  };
}
export {
  createCrudOpenApiFactory,
  createPagedListResponseSchema,
  defaultCreateResponseSchema,
  defaultOkResponseSchema
};
//# sourceMappingURL=crud.js.map
