TLDR;
All-together usage example: caseSources.ts
ts
// @webitel/api-services/api/.../caseSources.ts
import {
getSources, // service
CreateSourceBody, // zod
ListSourcesQueryParams, // zod
UpdateSourceBody, // zod
} from '../../../gen-wire'; // services + request zod live in the wire pass
import {
getShallowFieldsToSendFromZodSchema, // util script
} from '@webitel/api-services/gen/utils'; // absolute import, inside @webitel/api-services/api
import {
getDefaultGetListResponse,
getDefaultGetParams,
} from '../../defaults'; // relative import, avoid circular deps
import {
applyTransform,
camelToSnake,
merge,
notify,
sanitizeToWire,
snakeToCamel,
} from '../../transformers'; // relative import, avoid circular deps
const getSourcesList = async (params) => {
// dynamically, from generated
const fieldsToSend = getShallowFieldsToSendFromZodSchema(
ListSourcesQueryParams,
);
const { page, size, fields, sort, id, q, type } = applyTransform(params, [
merge(getDefaultGetParams()), // static defaults, not generated (for now)
sanitizeToWire(fieldsToSend), // renames to wire names, then whitelists
camelToSnake(), // converts the remaining VALUES, not keys
]);
try {
const response = await getSources() // call fn () to get api functions
.listSources({ // params passed as OBJECT!
page,
size,
fields,
sort,
id,
q: q || params.search, // it is Object, so key names matter!!
type,
});
const { items, next } = applyTransform(response.data, [
merge(getDefaultGetListResponse()), // static default, as for now
]);
return {
items: applyTransform(items, []),
next,
};
} catch (err) {
throw applyTransform(err, [notify]);
}
};
const getSource = async ({ itemId: id }) => {
try {
const response = await getSources() // call fn() too
.locateSource(id);
return applyTransform(response.data, [snakeToCamel(), itemResponseHandler]);
} catch (err) {
throw applyTransform(err, [notify]);
}
};
const addSource = async ({ itemInstance }) => {
const item = applyTransform(itemInstance, [
sanitizeToWire(getShallowFieldsToSendFromZodSchema(CreateSourceBody)),
camelToSnake(),
]);
try {
const response = await getSources() // call fn() too
.createSource(item);
return applyTransform(response.data, [snakeToCamel()]);
} catch (err) {
throw applyTransform(err, [notify]);
}
};
const updateSource = async ({ itemInstance, itemId: id }) => {
const fieldsToSend = getShallowFieldsToSendFromZodSchema(UpdateSourceBody);
const item = applyTransform(itemInstance, [
sanitizeToWire(fieldsToSend),
camelToSnake(),
]);
try {
const response = await getSources() // call fn() too
.updateSource(id, item);
return applyTransform(response.data, [snakeToCamel()]);
} catch (err) {
throw applyTransform(err, [notify]);
}
};
const deleteSource = async ({ id }) => {
try {
const response = await getSources() // call fn() too
.deleteSource(id);
return applyTransform(response.data, []);
} catch (err) {
throw applyTransform(err, [notify]);
}
};
const getLookup = (params) =>
getSourcesList({
...params,
fields: params.fields || ['id', 'name', 'type'],
});
export const CaseSourcesAPI = { // named export!
getList: getSourcesList,
get: getSource,
add: addSource,
update: updateSource,
delete: deleteSource,
getLookup,
};IMPORTANT
Сервіси і zod запитів імпортуються з gen-wire (в межах пакета — відносним шляхом, ззовні — @webitel/api-services/gen-wire), а sanitize замінено на sanitizeToWire, бо fieldsToSend тепер містить wire-імена (uploaded_at.from, via.id). Порядок кроків важливий — деталі в camelCase типи і snake_case дріт.