Files
Sipro-Marketplaces/pkg/api/wb/client/oas_handlers_gen.go

8244 lines
255 KiB
Go
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Code generated by ogen, DO NOT EDIT.
package api
import (
"context"
"net/http"
"time"
"github.com/go-faster/errors"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/metric"
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
"go.opentelemetry.io/otel/trace"
ht "github.com/ogen-go/ogen/http"
"github.com/ogen-go/ogen/middleware"
"github.com/ogen-go/ogen/ogenerrors"
)
type codeRecorder struct {
http.ResponseWriter
status int
}
func (c *codeRecorder) WriteHeader(status int) {
c.status = status
c.ResponseWriter.WriteHeader(status)
}
// handleAPIV2BufferGoodsTaskGetRequest handles GET /api/v2/buffer/goods/task operation.
//
// Метод предоставляет информацию о товарах и ошибках в
// товарах из загрузки в обработке.
// <div class="description_important">
// Необработанная загрузка — это загрузка скидок для <a
// href="/openapi/promotion#tag/Kalendar-akcij">календаря акций</a>. Такие
// скидки применятся к товарам только в момент начала
// акции.
// </div>
// <div class="description_limit">
// Максимум 10 запросов за 6 <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
// на один аккаунт продавца
// </div>.
//
// GET /api/v2/buffer/goods/task
func (s *Server) handleAPIV2BufferGoodsTaskGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/api/v2/buffer/goods/task"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2BufferGoodsTaskGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV2BufferGoodsTaskGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2BufferGoodsTaskGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV2BufferGoodsTaskGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response APIV2BufferGoodsTaskGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV2BufferGoodsTaskGetOperation,
OperationSummary: "Детализация необработанной загрузки",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "limit",
In: "query",
}: params.Limit,
{
Name: "offset",
In: "query",
}: params.Offset,
{
Name: "uploadID",
In: "query",
}: params.UploadID,
},
Raw: r,
}
type (
Request = struct{}
Params = APIV2BufferGoodsTaskGetParams
Response = APIV2BufferGoodsTaskGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV2BufferGoodsTaskGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV2BufferGoodsTaskGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.APIV2BufferGoodsTaskGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV2BufferGoodsTaskGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV2BufferTasksGetRequest handles GET /api/v2/buffer/tasks operation.
//
// Метод предоставляет информацию про загрузку скидок в
// обработке.
// <div class="description_important">
// Необработанная загрузка — это загрузка скидок для <a
// href="/openapi/promotion#tag/Kalendar-akcij">календаря акций</a>. Такие
// скидки применятся к товарам только в момент начала
// акции.
// </div>
// <div class="description_limit">
// Максимум 10 запросов за 6 <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
// на один аккаунт продавца
// </div>.
//
// GET /api/v2/buffer/tasks
func (s *Server) handleAPIV2BufferTasksGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/api/v2/buffer/tasks"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2BufferTasksGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV2BufferTasksGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2BufferTasksGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV2BufferTasksGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response APIV2BufferTasksGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV2BufferTasksGetOperation,
OperationSummary: "Состояние необработанной загрузки",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "uploadID",
In: "query",
}: params.UploadID,
},
Raw: r,
}
type (
Request = struct{}
Params = APIV2BufferTasksGetParams
Response = APIV2BufferTasksGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV2BufferTasksGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV2BufferTasksGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.APIV2BufferTasksGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV2BufferTasksGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV2HistoryGoodsTaskGetRequest handles GET /api/v2/history/goods/task operation.
//
// Метод предоставляет информацию о товарах и об
// ошибках в товарах в обработанной загрузке.
// <div class="description_important">
// Обработанная загрузка — это загрузка цен и скидок
// для <a
// href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task/post">товаров</a> и <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post">размеров товаров</a>, а также скидок <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post">WB Клуба</a>.
// </div>
// <div class="description_limit">
// Максимум 10 запросов за 6 <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
// на один аккаунт продавца
// </div>.
//
// GET /api/v2/history/goods/task
func (s *Server) handleAPIV2HistoryGoodsTaskGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/api/v2/history/goods/task"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2HistoryGoodsTaskGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV2HistoryGoodsTaskGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2HistoryGoodsTaskGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV2HistoryGoodsTaskGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response APIV2HistoryGoodsTaskGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV2HistoryGoodsTaskGetOperation,
OperationSummary: "Детализация обработанной загрузки",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "limit",
In: "query",
}: params.Limit,
{
Name: "offset",
In: "query",
}: params.Offset,
{
Name: "uploadID",
In: "query",
}: params.UploadID,
},
Raw: r,
}
type (
Request = struct{}
Params = APIV2HistoryGoodsTaskGetParams
Response = APIV2HistoryGoodsTaskGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV2HistoryGoodsTaskGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV2HistoryGoodsTaskGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.APIV2HistoryGoodsTaskGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV2HistoryGoodsTaskGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV2HistoryTasksGetRequest handles GET /api/v2/history/tasks operation.
//
// Метод предоставляет информацию об обработанной
// загрузке цен и скидок.
// <div class="description_important">
// Обработанная загрузка — это загрузка цен и скидок
// для <a
// href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task/post">товаров</a> и <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post">размеров товаров</a>, а также скидок <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post">WB Клуба</a>.
// </div>
// <div class="description_limit">
// Максимум 10 запросов за 6 <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
// на один аккаунт продавца
// </div>.
//
// GET /api/v2/history/tasks
func (s *Server) handleAPIV2HistoryTasksGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/api/v2/history/tasks"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2HistoryTasksGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV2HistoryTasksGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2HistoryTasksGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV2HistoryTasksGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response APIV2HistoryTasksGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV2HistoryTasksGetOperation,
OperationSummary: "Состояние обработанной загрузки",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "uploadID",
In: "query",
}: params.UploadID,
},
Raw: r,
}
type (
Request = struct{}
Params = APIV2HistoryTasksGetParams
Response = APIV2HistoryTasksGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV2HistoryTasksGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV2HistoryTasksGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.APIV2HistoryTasksGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV2HistoryTasksGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV2ListGoodsFilterGetRequest handles GET /api/v2/list/goods/filter operation.
//
// Метод предоставляет информацию о товарах по их
// артикулам: цены, валюту, общие скидки и скидки для [WB
// Клуба](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post).
// <br><br>
// Чтобы получить информацию обо всех товарах продавца,
// оставьте артикул пустым, установите `limit=1000`, в
// параметре `offset` установите смещение по количеству
// записей. Количество нужно рассчитать по формуле: `offset`
// плюс `limit` из предыдущего запроса. Повторяйте запрос,
// пока вы не получите ответ с пустым массивом.<br> Чтобы
// получить информацию о размерах товара, используйте
// [отдельный
// метод](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1size~1nm/get).
// <div class="description_limit">
// Максимум 10 запросов за 6 <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
// на один аккаунт продавца
// </div>.
//
// GET /api/v2/list/goods/filter
func (s *Server) handleAPIV2ListGoodsFilterGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/api/v2/list/goods/filter"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2ListGoodsFilterGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV2ListGoodsFilterGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2ListGoodsFilterGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV2ListGoodsFilterGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response APIV2ListGoodsFilterGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV2ListGoodsFilterGetOperation,
OperationSummary: "Получить товары с ценами",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "limit",
In: "query",
}: params.Limit,
{
Name: "offset",
In: "query",
}: params.Offset,
{
Name: "filterNmID",
In: "query",
}: params.FilterNmID,
},
Raw: r,
}
type (
Request = struct{}
Params = APIV2ListGoodsFilterGetParams
Response = APIV2ListGoodsFilterGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV2ListGoodsFilterGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV2ListGoodsFilterGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.APIV2ListGoodsFilterGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV2ListGoodsFilterGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV2ListGoodsSizeNmGetRequest handles GET /api/v2/list/goods/size/nm operation.
//
// Метод предоставляет информацию обо всех размерах
// одного товарам: цены, валюту, общие скидки и скидки
// для [WB
// Клуба](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post).
// <br><br>
// Работает только для товаров из категорий, где можно
// устанавливать цены отдельно для разных размеров. Для
// таких товаров `editableSizePrice: true`.
// <br><br>
// Чтобы получить информацию о самом товаре,
// используйте [отдельный
// метод](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1filter/get).
// <div class="description_limit">
// Максимум 10 запросов за 6 <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
// на один аккаунт продавца
// </div>.
//
// GET /api/v2/list/goods/size/nm
func (s *Server) handleAPIV2ListGoodsSizeNmGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/api/v2/list/goods/size/nm"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2ListGoodsSizeNmGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV2ListGoodsSizeNmGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2ListGoodsSizeNmGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV2ListGoodsSizeNmGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response APIV2ListGoodsSizeNmGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV2ListGoodsSizeNmGetOperation,
OperationSummary: "Получить размеры товара с ценами",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "limit",
In: "query",
}: params.Limit,
{
Name: "offset",
In: "query",
}: params.Offset,
{
Name: "nmID",
In: "query",
}: params.NmID,
},
Raw: r,
}
type (
Request = struct{}
Params = APIV2ListGoodsSizeNmGetParams
Response = APIV2ListGoodsSizeNmGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV2ListGoodsSizeNmGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV2ListGoodsSizeNmGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.APIV2ListGoodsSizeNmGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV2ListGoodsSizeNmGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV2QuarantineGoodsGetRequest handles GET /api/v2/quarantine/goods operation.
//
// Метод предоставляет информацию о товарах в карантине.
// <br><br>
// Если новая цена товара со скидкой будет минимум в 3
// раза меньше старой, товар попадёт [в
// карантин](https://seller.wildberries.ru/discount-and-prices/quarantine) и будет
// продаваться по старой цене. Ошибка об этом будет в
// ответах методов [состояний
// загрузок](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get).
// <br><br>
// Вы можете изменить цену или скидку с помощью API либо
// вывести товар из карантина [в личном
// кабинете](https://seller.wildberries.ru/discount-and-prices/quarantine).
// <br><br>
// Для товаров с [поразмерной установкой
// цен](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post)
// карантин не применяется.
// <div class="description_limit">
// Максимум 10 запросов за 6 <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
// на один аккаунт продавца
// </div>.
//
// GET /api/v2/quarantine/goods
func (s *Server) handleAPIV2QuarantineGoodsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/api/v2/quarantine/goods"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2QuarantineGoodsGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV2QuarantineGoodsGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2QuarantineGoodsGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV2QuarantineGoodsGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response APIV2QuarantineGoodsGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV2QuarantineGoodsGetOperation,
OperationSummary: "Получить товары в карантине",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "limit",
In: "query",
}: params.Limit,
{
Name: "offset",
In: "query",
}: params.Offset,
},
Raw: r,
}
type (
Request = struct{}
Params = APIV2QuarantineGoodsGetParams
Response = APIV2QuarantineGoodsGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV2QuarantineGoodsGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV2QuarantineGoodsGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.APIV2QuarantineGoodsGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV2QuarantineGoodsGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV2UploadTaskClubDiscountPostRequest handles POST /api/v2/upload/task/club-discount operation.
//
// Устанавливает скидки для товаров в рамках подписки [WB
// Клуб](https://seller.wildberries.ru/help-center/article/A-337).
// <div class="description_important">
// Получить информацию о процессе установки цен и
// скидок можно с помощью методов <a
// href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get">состояния</a> и <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1goods~1task/get">детализации</a> обработанной загрузки.
// </div>
// <div class="description_limit">
// Максимум 10 запросов за 6 <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
// на один аккаунт продавца
// </div>.
//
// POST /api/v2/upload/task/club-discount
func (s *Server) handleAPIV2UploadTaskClubDiscountPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/api/v2/upload/task/club-discount"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2UploadTaskClubDiscountPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV2UploadTaskClubDiscountPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2UploadTaskClubDiscountPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeAPIV2UploadTaskClubDiscountPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response APIV2UploadTaskClubDiscountPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV2UploadTaskClubDiscountPostOperation,
OperationSummary: "Установить скидки WB Клуба",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = *APIV2UploadTaskClubDiscountPostReq
Params = struct{}
Response = APIV2UploadTaskClubDiscountPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV2UploadTaskClubDiscountPost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.APIV2UploadTaskClubDiscountPost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV2UploadTaskClubDiscountPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV2UploadTaskPostRequest handles POST /api/v2/upload/task operation.
//
// Метод устанавливает цены и скидки для товаров.
// <br><br>
// Чтобы установить цены и скидки для размеров товара,
// используйте [отдельный
// метод](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post).
// <div class="description_important">
// Получить информацию о процессе установки цен и
// скидок можно с помощью методов <a
// href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get">состояния</a> и <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1goods~1task/get">детализации</a> обработанной загрузки.
// </div>
// <div class="description_limit">
// Максимум 10 запросов за 6 <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
// на один аккаунт продавца
// </div>.
//
// POST /api/v2/upload/task
func (s *Server) handleAPIV2UploadTaskPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/api/v2/upload/task"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2UploadTaskPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV2UploadTaskPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2UploadTaskPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeAPIV2UploadTaskPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response APIV2UploadTaskPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV2UploadTaskPostOperation,
OperationSummary: "Установить цены и скидки",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = *APIV2UploadTaskPostReq
Params = struct{}
Response = APIV2UploadTaskPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV2UploadTaskPost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.APIV2UploadTaskPost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV2UploadTaskPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV2UploadTaskSizePostRequest handles POST /api/v2/upload/task/size operation.
//
// Метод устанавливает цены отдельно для размеров
// товаров.
// Работает только для товаров из категорий, где можно
// устанавливать цены отдельно для разных размеров. Для
// [таких
// товаров](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1size~1nm/get) `editableSizePrice: true`.
// Чтобы установить цены и скидки для самих товаров,
// используйте [отдельный
// метод](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task/post).
// <div class="description_important">
// Получить информацию о процессе установки цен и
// скидок можно с помощью методов <a
// href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get">состояния</a> и <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1goods~1task/get">детализации</a> обработанной загрузки.
// </div>
// <div class="description_limit">
// Максимум 10 запросов за 6 <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
// на один аккаунт продавца
// </div>.
//
// POST /api/v2/upload/task/size
func (s *Server) handleAPIV2UploadTaskSizePostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/api/v2/upload/task/size"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2UploadTaskSizePostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV2UploadTaskSizePostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2UploadTaskSizePostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeAPIV2UploadTaskSizePostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response APIV2UploadTaskSizePostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV2UploadTaskSizePostOperation,
OperationSummary: "Установить цены для размеров",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = *APIV2UploadTaskSizePostReq
Params = struct{}
Response = APIV2UploadTaskSizePostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV2UploadTaskSizePost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.APIV2UploadTaskSizePost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV2UploadTaskSizePostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV3OfficesGetRequest handles GET /api/v3/offices operation.
//
// Метод предоставляет список всех складов WB для
// привязки к складам продавца. Предназначен для
// определения складов WB, чтобы сдавать готовые заказы
// по схеме [FBS](/openapi/orders-fbs#tag/Zakazy-FBS) (Fulfillment by Seller).
// <div class="description_limit">
// Максимум 300 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
// один аккаунт продавца.
// <br><br>
// Один запрос с кодом ответа <code>409</code> учитывается как 5
// запросов
// </div>.
//
// GET /api/v3/offices
func (s *Server) handleAPIV3OfficesGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/api/v3/offices"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3OfficesGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV3OfficesGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3OfficesGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
var response APIV3OfficesGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV3OfficesGetOperation,
OperationSummary: "Получить список складов WB",
OperationID: "",
Body: nil,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = struct{}
Params = struct{}
Response = APIV3OfficesGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV3OfficesGet(ctx)
return response, err
},
)
} else {
response, err = s.h.APIV3OfficesGet(ctx)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV3OfficesGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV3StocksWarehouseIdDeleteRequest handles DELETE /api/v3/stocks/{warehouseId} operation.
//
// Метод удаляет запись об остатках товаров продавца из
// [списка
// остатков](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post).
// <div class="description_important">
// <strong>Действие необратимо</strong>. Удаленный остаток
// будет необходимо загрузить повторно для
// возобновления продаж.
// </div>
// <div class="description_limit">
// Максимум 300 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
// один аккаунт продавца.
// <br><br>
// Один запрос с кодом ответа <code>409</code> учитывается как 5
// запросов
// </div>.
//
// DELETE /api/v3/stocks/{warehouseId}
func (s *Server) handleAPIV3StocksWarehouseIdDeleteRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("DELETE"),
semconv.HTTPRouteKey.String("/api/v3/stocks/{warehouseId}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3StocksWarehouseIdDeleteOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV3StocksWarehouseIdDeleteOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3StocksWarehouseIdDeleteOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV3StocksWarehouseIdDeleteParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
request, close, err := s.decodeAPIV3StocksWarehouseIdDeleteRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response APIV3StocksWarehouseIdDeleteRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV3StocksWarehouseIdDeleteOperation,
OperationSummary: "Удалить остатки товаров",
OperationID: "",
Body: request,
Params: middleware.Parameters{
{
Name: "warehouseId",
In: "path",
}: params.WarehouseId,
},
Raw: r,
}
type (
Request = *APIV3StocksWarehouseIdDeleteReq
Params = APIV3StocksWarehouseIdDeleteParams
Response = APIV3StocksWarehouseIdDeleteRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV3StocksWarehouseIdDeleteParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV3StocksWarehouseIdDelete(ctx, request, params)
return response, err
},
)
} else {
response, err = s.h.APIV3StocksWarehouseIdDelete(ctx, request, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV3StocksWarehouseIdDeleteResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV3StocksWarehouseIdPostRequest handles POST /api/v3/stocks/{warehouseId} operation.
//
// Метод предоставляет данные об остатках товаров на
// [складах продавца](/openapi/work-with-products#tag/Sklady-prodavca).
// <div class="description_limit">
// Максимум 300 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
// один аккаунт продавца.
// <br><br>
// Один запрос с кодом ответа <code>409</code> учитывается как 5
// запросов
// </div>.
//
// POST /api/v3/stocks/{warehouseId}
func (s *Server) handleAPIV3StocksWarehouseIdPostRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/api/v3/stocks/{warehouseId}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3StocksWarehouseIdPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV3StocksWarehouseIdPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3StocksWarehouseIdPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV3StocksWarehouseIdPostParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
request, close, err := s.decodeAPIV3StocksWarehouseIdPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response APIV3StocksWarehouseIdPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV3StocksWarehouseIdPostOperation,
OperationSummary: "Получить остатки товаров",
OperationID: "",
Body: request,
Params: middleware.Parameters{
{
Name: "warehouseId",
In: "path",
}: params.WarehouseId,
},
Raw: r,
}
type (
Request = *APIV3StocksWarehouseIdPostReq
Params = APIV3StocksWarehouseIdPostParams
Response = APIV3StocksWarehouseIdPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV3StocksWarehouseIdPostParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV3StocksWarehouseIdPost(ctx, request, params)
return response, err
},
)
} else {
response, err = s.h.APIV3StocksWarehouseIdPost(ctx, request, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV3StocksWarehouseIdPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV3StocksWarehouseIdPutRequest handles PUT /api/v3/stocks/{warehouseId} operation.
//
// Метод обновляет количество остатков товаров
// продавца [в
// списке](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post).
// <div class="description_important">
// Названия параметров запроса не валидируются. При
// отправке некорректных названий вы получите успешный
// ответ (<code>204</code>), но остатки не обновятся.
// </div>
// <div class="description_limit">
// Максимум 300 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
// один аккаунт продавца.
// <br><br>
// Один запрос с кодом ответа <code>409</code> учитывается как 5
// запросов
// </div>.
//
// PUT /api/v3/stocks/{warehouseId}
func (s *Server) handleAPIV3StocksWarehouseIdPutRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("PUT"),
semconv.HTTPRouteKey.String("/api/v3/stocks/{warehouseId}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3StocksWarehouseIdPutOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV3StocksWarehouseIdPutOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3StocksWarehouseIdPutOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV3StocksWarehouseIdPutParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
request, close, err := s.decodeAPIV3StocksWarehouseIdPutRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response APIV3StocksWarehouseIdPutRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV3StocksWarehouseIdPutOperation,
OperationSummary: "Обновить остатки товаров",
OperationID: "",
Body: request,
Params: middleware.Parameters{
{
Name: "warehouseId",
In: "path",
}: params.WarehouseId,
},
Raw: r,
}
type (
Request = OptAPIV3StocksWarehouseIdPutReq
Params = APIV3StocksWarehouseIdPutParams
Response = APIV3StocksWarehouseIdPutRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV3StocksWarehouseIdPutParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV3StocksWarehouseIdPut(ctx, request, params)
return response, err
},
)
} else {
response, err = s.h.APIV3StocksWarehouseIdPut(ctx, request, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV3StocksWarehouseIdPutResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV3WarehousesGetRequest handles GET /api/v3/warehouses operation.
//
// Метод предоставляет список всех складов продавца.
// Может использоваться для получения [остатков
// товаров](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post).
// <div class="description_limit">
// Максимум 300 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
// один аккаунт продавца.
// <br><br>
// Один запрос с кодом ответа <code>409</code> учитывается как 5
// запросов
// </div>.
//
// GET /api/v3/warehouses
func (s *Server) handleAPIV3WarehousesGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/api/v3/warehouses"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3WarehousesGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV3WarehousesGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3WarehousesGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
var response APIV3WarehousesGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV3WarehousesGetOperation,
OperationSummary: "Получить список складов продавца",
OperationID: "",
Body: nil,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = struct{}
Params = struct{}
Response = APIV3WarehousesGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV3WarehousesGet(ctx)
return response, err
},
)
} else {
response, err = s.h.APIV3WarehousesGet(ctx)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV3WarehousesGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV3WarehousesPostRequest handles POST /api/v3/warehouses operation.
//
// Метод создаёт склад продавца для работы с [остатками
// товаров](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post). Нужно привязать к складу продавца [склад WB](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1offices/get) для работы по схеме [FBS](/openapi/orders-fbs#tag/Zakazy-FBS) (Fulfillment by Seller).
// <div class="description_important">
// Нельзя привязывать склад WB, который уже используется
// </div>
// <div class="description_limit">
// Максимум 300 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
// один аккаунт продавца.
// <br><br>
// Один запрос с кодом ответа <code>409</code> учитывается как 5
// запросов
// </div>.
//
// POST /api/v3/warehouses
func (s *Server) handleAPIV3WarehousesPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/api/v3/warehouses"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3WarehousesPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV3WarehousesPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3WarehousesPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeAPIV3WarehousesPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response APIV3WarehousesPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV3WarehousesPostOperation,
OperationSummary: "Создать склад продавца",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = *APIV3WarehousesPostReq
Params = struct{}
Response = APIV3WarehousesPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV3WarehousesPost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.APIV3WarehousesPost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV3WarehousesPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV3WarehousesWarehouseIdDeleteRequest handles DELETE /api/v3/warehouses/{warehouseId} operation.
//
// Метод удаляет склад продавца из [списка
// складов](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1warehouses/get).
// <div class="description_limit">
// Максимум 300 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
// один аккаунт продавца.
// <br><br>
// Один запрос с кодом ответа <code>409</code> учитывается как 5
// запросов
// </div>.
//
// DELETE /api/v3/warehouses/{warehouseId}
func (s *Server) handleAPIV3WarehousesWarehouseIdDeleteRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("DELETE"),
semconv.HTTPRouteKey.String("/api/v3/warehouses/{warehouseId}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3WarehousesWarehouseIdDeleteOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV3WarehousesWarehouseIdDeleteOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3WarehousesWarehouseIdDeleteOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV3WarehousesWarehouseIdDeleteParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response APIV3WarehousesWarehouseIdDeleteRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV3WarehousesWarehouseIdDeleteOperation,
OperationSummary: "Удалить склад продавца",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "warehouseId",
In: "path",
}: params.WarehouseId,
},
Raw: r,
}
type (
Request = struct{}
Params = APIV3WarehousesWarehouseIdDeleteParams
Response = APIV3WarehousesWarehouseIdDeleteRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV3WarehousesWarehouseIdDeleteParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV3WarehousesWarehouseIdDelete(ctx, params)
return response, err
},
)
} else {
response, err = s.h.APIV3WarehousesWarehouseIdDelete(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV3WarehousesWarehouseIdDeleteResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleAPIV3WarehousesWarehouseIdPutRequest handles PUT /api/v3/warehouses/{warehouseId} operation.
//
// Метод обновляет данные склада продавца в [списке
// складов](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1warehouses/get).
// Данные о привязанном [складе
// WB](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1offices/get) можно
// изменить один раз в сутки.
// <div class="description_important">
// Нельзя привязывать склад WB, который уже используется
// </div>
// <div class="description_limit">
// Максимум 300 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
// один аккаунт продавца.
// <br><br>
// Один запрос с кодом ответа <code>409</code> учитывается как 5
// запросов
// </div>.
//
// PUT /api/v3/warehouses/{warehouseId}
func (s *Server) handleAPIV3WarehousesWarehouseIdPutRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("PUT"),
semconv.HTTPRouteKey.String("/api/v3/warehouses/{warehouseId}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3WarehousesWarehouseIdPutOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: APIV3WarehousesWarehouseIdPutOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3WarehousesWarehouseIdPutOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeAPIV3WarehousesWarehouseIdPutParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
request, close, err := s.decodeAPIV3WarehousesWarehouseIdPutRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response APIV3WarehousesWarehouseIdPutRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: APIV3WarehousesWarehouseIdPutOperation,
OperationSummary: "Обновить склад продавца",
OperationID: "",
Body: request,
Params: middleware.Parameters{
{
Name: "warehouseId",
In: "path",
}: params.WarehouseId,
},
Raw: r,
}
type (
Request = *APIV3WarehousesWarehouseIdPutReq
Params = APIV3WarehousesWarehouseIdPutParams
Response = APIV3WarehousesWarehouseIdPutRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackAPIV3WarehousesWarehouseIdPutParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.APIV3WarehousesWarehouseIdPut(ctx, request, params)
return response, err
},
)
} else {
response, err = s.h.APIV3WarehousesWarehouseIdPut(ctx, request, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeAPIV3WarehousesWarehouseIdPutResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2BarcodesPostRequest handles POST /content/v2/barcodes operation.
//
// Метод генерирует массив уникальных баркодов для
// создания размера в [карточке
// товара](/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post). Можно использовать, если у вас нет собственных баркодов.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// POST /content/v2/barcodes
func (s *Server) handleContentV2BarcodesPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/content/v2/barcodes"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2BarcodesPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2BarcodesPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2BarcodesPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeContentV2BarcodesPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response ContentV2BarcodesPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2BarcodesPostOperation,
OperationSummary: "Генерация баркодов",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = *ContentV2BarcodesPostReq
Params = struct{}
Response = ContentV2BarcodesPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2BarcodesPost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.ContentV2BarcodesPost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2BarcodesPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2CardsDeleteTrashPostRequest handles POST /content/v2/cards/delete/trash operation.
//
// Метод переносит [карточки товаров в
// корзину](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post). При этом карточки товаров не удаляются, их можно [восстановить](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1recover/post).
// <div class="description_important">
// После переноса в корзину карточке товара
// присваивается новый <code>imtID</code>.
// </div>
// Карточки товаров удаляются автоматически, если лежат
// в корзине больше 30 дней. Очистка корзины происходит
// каждую ночь по московскому времени.<br>
// Карточки товаров можно удалить в любое время в
// [личном кабинете](https://seller.wildberries.ru/new-goods/basket-cards).
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// POST /content/v2/cards/delete/trash
func (s *Server) handleContentV2CardsDeleteTrashPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/content/v2/cards/delete/trash"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsDeleteTrashPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2CardsDeleteTrashPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsDeleteTrashPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeContentV2CardsDeleteTrashPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response ContentV2CardsDeleteTrashPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2CardsDeleteTrashPostOperation,
OperationSummary: "Перенос карточек товаров в корзину",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = *ContentV2CardsDeleteTrashPostReq
Params = struct{}
Response = ContentV2CardsDeleteTrashPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2CardsDeleteTrashPost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.ContentV2CardsDeleteTrashPost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2CardsDeleteTrashPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2CardsErrorListGetRequest handles GET /content/v2/cards/error/list operation.
//
// Метод предоставляет список карточек товаров, при
// создании или редактировании которых произошли
// ошибки, с описанием этих ошибок.
// <div class="description_important">
// Чтобы убрать карточку товара из списка, нужно
// повторно сделать запрос на <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создание</a> или редактирование карточки товара с исправленными ошибками.
// </div>
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/cards/error/list
func (s *Server) handleContentV2CardsErrorListGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/cards/error/list"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsErrorListGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2CardsErrorListGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsErrorListGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2CardsErrorListGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response ContentV2CardsErrorListGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2CardsErrorListGetOperation,
OperationSummary: "Список несозданных карточек товаров с ошибками",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "locale",
In: "query",
}: params.Locale,
},
Raw: r,
}
type (
Request = struct{}
Params = ContentV2CardsErrorListGetParams
Response = ContentV2CardsErrorListGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2CardsErrorListGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2CardsErrorListGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2CardsErrorListGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2CardsErrorListGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2CardsLimitsGetRequest handles GET /content/v2/cards/limits operation.
//
// Возвращает бесплатные и платные лимиты продавца на
// [создание карточек
// товаров](/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post).<br><br>
// Формула для получения количества карточек, которые
// можно создать:
// > (`freeLimits` + `paidLimits`) - количество созданных карточек
// Созданными считаются карточки, которые можно
// получить через методы [список карточек
// товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1list/post) и [список карточек товаров в корзине](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post).
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/cards/limits
func (s *Server) handleContentV2CardsLimitsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/cards/limits"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsLimitsGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2CardsLimitsGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsLimitsGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
var response ContentV2CardsLimitsGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2CardsLimitsGetOperation,
OperationSummary: "Лимиты карточек товаров",
OperationID: "",
Body: nil,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = struct{}
Params = struct{}
Response = ContentV2CardsLimitsGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2CardsLimitsGet(ctx)
return response, err
},
)
} else {
response, err = s.h.ContentV2CardsLimitsGet(ctx)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2CardsLimitsGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2CardsRecoverPostRequest handles POST /content/v2/cards/recover operation.
//
// Метод восстанавливает [карточки товаров из
// корзины](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post).
// <div class="description_important">
// Карточка товара сохраняет тот же <code>imtID</code>, что был
// присвоен ей при <a
// href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1delete~1trash/post">перемещении в корзину</a>.
// </div>
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// POST /content/v2/cards/recover
func (s *Server) handleContentV2CardsRecoverPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/content/v2/cards/recover"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsRecoverPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2CardsRecoverPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsRecoverPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeContentV2CardsRecoverPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response ContentV2CardsRecoverPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2CardsRecoverPostOperation,
OperationSummary: "Восстановление карточек товаров из корзины",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = *ContentV2CardsRecoverPostReq
Params = struct{}
Response = ContentV2CardsRecoverPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2CardsRecoverPost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.ContentV2CardsRecoverPost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2CardsRecoverPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2CardsUpdatePostRequest handles POST /content/v2/cards/update operation.
//
// Метод обновляет карточки товаров. Данные для
// обновления можно получить через [список карточек
// товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1list/post) и [список карточек товаров в корзине](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post).
// <div class="description_important">
// Карточка товара перезаписывается при обновлении.
// Поэтому в запросе нужно передать <strong>все</strong>
// параметры карточки, в том числе те, которые вы не
// собираетесь обновлять.
// </div>
// Нельзя редактировать или удалять баркоды, но можно
// добавить дополнительный баркод к карточке товара.
// Параметры `photos`, `video` и `tags` редактировать или удалять
// через данный метод нельзя.<br>
// Габариты товаров можно указать только в `сантиметрах`,
//
// вес товара с упаковкой — в `килограммах`.
//
// <br><br>
// В одном запросе можно отредактировать максимум 3000
// карточек товаров (`nmID`). Максимальный размер запроса 10
// Мб.<br>
// Если ответ `Успешно` (`200`), но какие-то карточки не
// обновились, получите [список несозданных карточек
// товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/get).
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня для метода будет отдельный
// лимит — 10 запросов в минуту на один аккаунт продавца
// </div>.
//
// POST /content/v2/cards/update
func (s *Server) handleContentV2CardsUpdatePostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/content/v2/cards/update"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsUpdatePostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2CardsUpdatePostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsUpdatePostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeContentV2CardsUpdatePostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response ContentV2CardsUpdatePostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2CardsUpdatePostOperation,
OperationSummary: "Редактирование карточек товаров",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = []ContentV2CardsUpdatePostReqItem
Params = struct{}
Response = ContentV2CardsUpdatePostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2CardsUpdatePost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.ContentV2CardsUpdatePost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2CardsUpdatePostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2CardsUploadAddPostRequest handles POST /content/v2/cards/upload/add operation.
//
// Метод создаёт новые карточки товаров, присоединяя их
// к существующим карточкам.
// Габариты товаров можно указать только в `сантиметрах`,
//
// вес товара с упаковкой — в `килограммах`.
//
// <br><br>
// Создание карточки товара происходит асинхронно.
// После отправки запрос становится в очередь на
// обработку.<br>Максимальный размер запроса 10 Мб.<br>
// Если ответ `Успешно` (`200`), но какие-то карточки не
// обновились, получите [список несозданных карточек
// товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/get).
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня для метода будет отдельный
// лимит — 10 запросов в минуту на один аккаунт продавца
// </div>.
//
// POST /content/v2/cards/upload/add
func (s *Server) handleContentV2CardsUploadAddPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/content/v2/cards/upload/add"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsUploadAddPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2CardsUploadAddPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsUploadAddPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeContentV2CardsUploadAddPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response ContentV2CardsUploadAddPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2CardsUploadAddPostOperation,
OperationSummary: "Создание карточек товаров с присоединением",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = OptContentV2CardsUploadAddPostReq
Params = struct{}
Response = ContentV2CardsUploadAddPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2CardsUploadAddPost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.ContentV2CardsUploadAddPost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2CardsUploadAddPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2CardsUploadPostRequest handles POST /content/v2/cards/upload operation.
//
// Метод создаёт карточки товаров c указанием описаний и
// характеристик товаров.<br>
// <div class="description_important">
// Есть две формы запроса: для создания отдельных и
// объединённых карточек товаров.
// </div>
// Габариты товаров можно указать только в `сантиметрах`,
//
// вес товара с упаковкой — в `килограммах`.
//
// <br><br>
// Создание карточки товара происходит асинхронно.
// После отправки запрос становится в очередь на
// обработку.<br>
// В одном запросе можно создать максимум 100
// объединённых карточек товаров (`imtID`), по 30 карточек
// товаров в каждой. Максимальный размер запроса 10 Мб.<br>
// Если ответ `Успешно` (`200`), но какие-то карточки не
// обновились, получите [список несозданных карточек
// товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/get).
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня для метода будет отдельный
// лимит — 10 запросов в минуту на один аккаунт продавца
// </div>.
//
// POST /content/v2/cards/upload
func (s *Server) handleContentV2CardsUploadPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/content/v2/cards/upload"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsUploadPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2CardsUploadPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsUploadPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeContentV2CardsUploadPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response ContentV2CardsUploadPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2CardsUploadPostOperation,
OperationSummary: "Создание карточек товаров",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = []ContentV2CardsUploadPostReqItem
Params = struct{}
Response = ContentV2CardsUploadPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2CardsUploadPost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.ContentV2CardsUploadPost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2CardsUploadPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2DirectoryColorsGetRequest handles GET /content/v2/directory/colors operation.
//
// Метод предоставляет возможные значения
// [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Цвет`.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/directory/colors
func (s *Server) handleContentV2DirectoryColorsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/directory/colors"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectoryColorsGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2DirectoryColorsGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectoryColorsGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2DirectoryColorsGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response ContentV2DirectoryColorsGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2DirectoryColorsGetOperation,
OperationSummary: "Цвет",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "locale",
In: "query",
}: params.Locale,
},
Raw: r,
}
type (
Request = struct{}
Params = ContentV2DirectoryColorsGetParams
Response = ContentV2DirectoryColorsGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2DirectoryColorsGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2DirectoryColorsGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2DirectoryColorsGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2DirectoryColorsGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2DirectoryCountriesGetRequest handles GET /content/v2/directory/countries operation.
//
// Метод предоставляет возможные значения
// [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Страна производства`.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/directory/countries
func (s *Server) handleContentV2DirectoryCountriesGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/directory/countries"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectoryCountriesGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2DirectoryCountriesGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectoryCountriesGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2DirectoryCountriesGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response ContentV2DirectoryCountriesGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2DirectoryCountriesGetOperation,
OperationSummary: "Страна производства",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "locale",
In: "query",
}: params.Locale,
},
Raw: r,
}
type (
Request = struct{}
Params = ContentV2DirectoryCountriesGetParams
Response = ContentV2DirectoryCountriesGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2DirectoryCountriesGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2DirectoryCountriesGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2DirectoryCountriesGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2DirectoryCountriesGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2DirectoryKindsGetRequest handles GET /content/v2/directory/kinds operation.
//
// Метод предоставляет возможные значения
// [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Пол`.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/directory/kinds
func (s *Server) handleContentV2DirectoryKindsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/directory/kinds"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectoryKindsGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2DirectoryKindsGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectoryKindsGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2DirectoryKindsGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response ContentV2DirectoryKindsGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2DirectoryKindsGetOperation,
OperationSummary: "Пол",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "locale",
In: "query",
}: params.Locale,
},
Raw: r,
}
type (
Request = struct{}
Params = ContentV2DirectoryKindsGetParams
Response = ContentV2DirectoryKindsGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2DirectoryKindsGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2DirectoryKindsGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2DirectoryKindsGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2DirectoryKindsGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2DirectorySeasonsGetRequest handles GET /content/v2/directory/seasons operation.
//
// Метод предоставляет возможные значения
// [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Сезон`.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/directory/seasons
func (s *Server) handleContentV2DirectorySeasonsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/directory/seasons"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectorySeasonsGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2DirectorySeasonsGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectorySeasonsGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2DirectorySeasonsGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response ContentV2DirectorySeasonsGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2DirectorySeasonsGetOperation,
OperationSummary: "Сезон",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "locale",
In: "query",
}: params.Locale,
},
Raw: r,
}
type (
Request = struct{}
Params = ContentV2DirectorySeasonsGetParams
Response = ContentV2DirectorySeasonsGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2DirectorySeasonsGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2DirectorySeasonsGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2DirectorySeasonsGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2DirectorySeasonsGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2DirectoryTnvedGetRequest handles GET /content/v2/directory/tnved operation.
//
// Метод предоставляет список ТНВЭД-кодов по ID
// [предмета](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1all/get) и фрагменту ТНВЭД-кода.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/directory/tnved
func (s *Server) handleContentV2DirectoryTnvedGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/directory/tnved"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectoryTnvedGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2DirectoryTnvedGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectoryTnvedGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2DirectoryTnvedGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response ContentV2DirectoryTnvedGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2DirectoryTnvedGetOperation,
OperationSummary: "ТНВЭД-код",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "subjectID",
In: "query",
}: params.SubjectID,
{
Name: "search",
In: "query",
}: params.Search,
{
Name: "locale",
In: "query",
}: params.Locale,
},
Raw: r,
}
type (
Request = struct{}
Params = ContentV2DirectoryTnvedGetParams
Response = ContentV2DirectoryTnvedGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2DirectoryTnvedGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2DirectoryTnvedGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2DirectoryTnvedGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2DirectoryTnvedGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2DirectoryVatGetRequest handles GET /content/v2/directory/vat operation.
//
// Метод предоставляет возможные значения
// [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Ставка НДС`.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/directory/vat
func (s *Server) handleContentV2DirectoryVatGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/directory/vat"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectoryVatGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2DirectoryVatGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectoryVatGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2DirectoryVatGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response ContentV2DirectoryVatGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2DirectoryVatGetOperation,
OperationSummary: "Ставка НДС",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "locale",
In: "query",
}: params.Locale,
},
Raw: r,
}
type (
Request = struct{}
Params = ContentV2DirectoryVatGetParams
Response = ContentV2DirectoryVatGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2DirectoryVatGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2DirectoryVatGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2DirectoryVatGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2DirectoryVatGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2GetCardsListPostRequest handles POST /content/v2/get/cards/list operation.
//
// <div class="description_auth">
// Метод доступен по <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">токену</a> с
// категорией <strong>Контент</strong> или <strong>Продвижение</strong>
// </div>
// Метод предоставляет список созданных карточек
// товаров.
// <div class="description_important">
// В ответе метода не будет карточек, находящихся в
// корзине. Получить такие карточки можно через <a
// href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post">отдельный метод</a>.
// </div>
// Чтобы получить **больше 100** карточек товаров,
// воспользуйтесь пагинацией:
// <ol>
// <li>Сделайте первый запрос: <br>
// <pre style="background-color: rgb(38 50 56 / 5%); color: #e53935">
// {
// "settings": {
// "cursor": {
// "limit": 100
// },
// "filter": {
// "withPhoto": -1
// }
// }
// }</pre>
// </li>
// <li>Пройдите в конец полученного списка карточек
// товаров.</li>
// <li>Скопируйте из <code>cursor</code> две строки:
// <ul>
// <li><code>"updatedAt": "***"</code></li>
// <li><code>"nmID": ***</code></li>
// </ul></li>
// <li>Вставьте скопированные строки в параметр запроса
// <code>cursor</code>.</li>
// <li>Повторите запрос. </li>
// <li>Повторяйте пункты со <b>2</b> по <b>5</b>, пока поле
// <code>total</code> в ответе не станет меньше чем параметр
// <code>limit</code> в запросе. Это будет означать, что вы
// получили все карточки.
// </ol>
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// POST /content/v2/get/cards/list
func (s *Server) handleContentV2GetCardsListPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/content/v2/get/cards/list"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2GetCardsListPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2GetCardsListPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2GetCardsListPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2GetCardsListPostParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
request, close, err := s.decodeContentV2GetCardsListPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response ContentV2GetCardsListPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2GetCardsListPostOperation,
OperationSummary: "Список карточек товаров",
OperationID: "",
Body: request,
Params: middleware.Parameters{
{
Name: "locale",
In: "query",
}: params.Locale,
},
Raw: r,
}
type (
Request = *ContentV2GetCardsListPostReq
Params = ContentV2GetCardsListPostParams
Response = ContentV2GetCardsListPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2GetCardsListPostParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2GetCardsListPost(ctx, request, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2GetCardsListPost(ctx, request, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2GetCardsListPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2GetCardsTrashPostRequest handles POST /content/v2/get/cards/trash operation.
//
// <div class="description_auth">
// Метод доступен по <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">токену</a> с
// категорией <strong>Контент</strong> или <strong>Продвижение</strong>
// </div>
// Метод предоставляет список карточек товаров в
// корзине.<br><br>
// Чтобы получить **больше 100** карточек товаров,
// воспользуйтесь пагинацией:
// <ol>
// <li>Сделайте первый запрос: <br>
// <pre style="background-color: rgb(38 50 56 / 5%); color: #e53935">
// {
// "settings": {
// "cursor": {
// "limit": 100
// },
// "filter": {
// "withPhoto": -1
// }
// }
// }</pre>
// </li>
// <li>Пройдите в конец полученного списка карточек
// товаров.</li>
// <li>Скопируйте из <code>cursor</code> две строки:
// <ul>
// <li><code>"trashedAt": "***"</code></li>
// <li><code>"nmID": ***</code></li>
// </ul></li>
// <li>Вставьте скопированные строки в параметр запроса
// <code>cursor</code>.</li>
// <li>Повторите запрос. </li>
// <li>Повторяйте пункты со <b>2</b> по <b>5</b>, пока поле
// <code>total</code> в ответе не станет меньше чем параметр
// <code>limit</code> в запросе. Это будет означать, что вы
// получили все карточки.
// </ol>
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// POST /content/v2/get/cards/trash
func (s *Server) handleContentV2GetCardsTrashPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/content/v2/get/cards/trash"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2GetCardsTrashPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2GetCardsTrashPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2GetCardsTrashPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2GetCardsTrashPostParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
request, close, err := s.decodeContentV2GetCardsTrashPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response ContentV2GetCardsTrashPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2GetCardsTrashPostOperation,
OperationSummary: "Список карточек товаров в корзине",
OperationID: "",
Body: request,
Params: middleware.Parameters{
{
Name: "locale",
In: "query",
}: params.Locale,
},
Raw: r,
}
type (
Request = *ContentV2GetCardsTrashPostReq
Params = ContentV2GetCardsTrashPostParams
Response = ContentV2GetCardsTrashPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2GetCardsTrashPostParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2GetCardsTrashPost(ctx, request, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2GetCardsTrashPost(ctx, request, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2GetCardsTrashPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2ObjectAllGetRequest handles GET /content/v2/object/all operation.
//
// Метод предоставляет список названий [родительских
// категорий
// предметов](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1parent~1all/get) и их предметов с ID. Например, у категории `Игрушки` будут предметы `Калейдоскопы`, `Куклы`, `Мячики`.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/object/all
func (s *Server) handleContentV2ObjectAllGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/object/all"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2ObjectAllGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2ObjectAllGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2ObjectAllGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2ObjectAllGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response ContentV2ObjectAllGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2ObjectAllGetOperation,
OperationSummary: "Список предметов",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "locale",
In: "query",
}: params.Locale,
{
Name: "name",
In: "query",
}: params.Name,
{
Name: "limit",
In: "query",
}: params.Limit,
{
Name: "offset",
In: "query",
}: params.Offset,
{
Name: "parentID",
In: "query",
}: params.ParentID,
},
Raw: r,
}
type (
Request = struct{}
Params = ContentV2ObjectAllGetParams
Response = ContentV2ObjectAllGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2ObjectAllGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2ObjectAllGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2ObjectAllGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2ObjectAllGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2ObjectCharcsSubjectIdGetRequest handles GET /content/v2/object/charcs/{subjectId} operation.
//
// Метод предоставляет параметры характеристик
// предмета: названия, типы данных, единицы измерения и
// так далее. В запросе необходимо указать ID
// [предмета](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1all/get).
// <div class="description_important">
// Для получения характеристик <a
// href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1colors/get">Цвет</a>, <a href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1kinds/get">Пол</a>, <a href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1countries/get">Страна производства</a>, <a href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1seasons/get">Сезон</a>, <a href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1vat/get">Ставка НДС</a> и <a href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1tnved/get">ТНВЭД-код</a> используйте отдельные методы
// </div>
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/object/charcs/{subjectId}
func (s *Server) handleContentV2ObjectCharcsSubjectIdGetRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/object/charcs/{subjectId}"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2ObjectCharcsSubjectIdGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2ObjectCharcsSubjectIdGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2ObjectCharcsSubjectIdGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2ObjectCharcsSubjectIdGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response ContentV2ObjectCharcsSubjectIdGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2ObjectCharcsSubjectIdGetOperation,
OperationSummary: "Характеристики предмета",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "subjectId",
In: "path",
}: params.SubjectId,
{
Name: "locale",
In: "query",
}: params.Locale,
},
Raw: r,
}
type (
Request = struct{}
Params = ContentV2ObjectCharcsSubjectIdGetParams
Response = ContentV2ObjectCharcsSubjectIdGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2ObjectCharcsSubjectIdGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2ObjectCharcsSubjectIdGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2ObjectCharcsSubjectIdGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2ObjectCharcsSubjectIdGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2ObjectParentAllGetRequest handles GET /content/v2/object/parent/all operation.
//
// Метод предоставляет названия и ID всех родительских
// категорий для [создания карточек
// товаров](/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov): например,
// `Электроника`, `Бытовая химия`, `Рукоделие`.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/object/parent/all
func (s *Server) handleContentV2ObjectParentAllGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/object/parent/all"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2ObjectParentAllGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2ObjectParentAllGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2ObjectParentAllGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV2ObjectParentAllGetParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
var response ContentV2ObjectParentAllGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2ObjectParentAllGetOperation,
OperationSummary: "Родительские категории товаров",
OperationID: "",
Body: nil,
Params: middleware.Parameters{
{
Name: "locale",
In: "query",
}: params.Locale,
},
Raw: r,
}
type (
Request = struct{}
Params = ContentV2ObjectParentAllGetParams
Response = ContentV2ObjectParentAllGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV2ObjectParentAllGetParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2ObjectParentAllGet(ctx, params)
return response, err
},
)
} else {
response, err = s.h.ContentV2ObjectParentAllGet(ctx, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2ObjectParentAllGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2TagNomenclatureLinkPostRequest handles POST /content/v2/tag/nomenclature/link operation.
//
// Метод добавляет или снимает ярлык с карточки товара.
// К карточке можно добавить максимум 15 ярлыков.<br>
// При удалении ярлыка из карточки товара он не
// удаляется из [списка
// ярлыков](/openapi/work-with-products#tag/Yarlyki/paths/~1content~1v2~1tags/get)
// продавца.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// POST /content/v2/tag/nomenclature/link
func (s *Server) handleContentV2TagNomenclatureLinkPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/content/v2/tag/nomenclature/link"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2TagNomenclatureLinkPostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2TagNomenclatureLinkPostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2TagNomenclatureLinkPostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeContentV2TagNomenclatureLinkPostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response ContentV2TagNomenclatureLinkPostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2TagNomenclatureLinkPostOperation,
OperationSummary: "Управление ярлыками в карточке товара",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = *ContentV2TagNomenclatureLinkPostReq
Params = struct{}
Response = ContentV2TagNomenclatureLinkPostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2TagNomenclatureLinkPost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.ContentV2TagNomenclatureLinkPost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2TagNomenclatureLinkPostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV2TagsGetRequest handles GET /content/v2/tags operation.
//
// Метод предоставляет список и характеристики всех
// ярлыков продавца для группировки и фильтрации
// товаров.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// GET /content/v2/tags
func (s *Server) handleContentV2TagsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/content/v2/tags"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2TagsGetOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV2TagsGetOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2TagsGetOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
var response ContentV2TagsGetRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV2TagsGetOperation,
OperationSummary: "Список ярлыков",
OperationID: "",
Body: nil,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = struct{}
Params = struct{}
Response = ContentV2TagsGetRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV2TagsGet(ctx)
return response, err
},
)
} else {
response, err = s.h.ContentV2TagsGet(ctx)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV2TagsGetResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV3MediaFilePostRequest handles POST /content/v3/media/file operation.
//
// Метод загружает и добавляет один медиафайл к
// карточке товара.
// Требования к изображениям:
// * максимум изображений для одной карточки товара — 30
// * минимальное разрешение — 700x900 px
// * максимальный размер — 32 Мб
// * минимальное качество — 65%
// * форматы — JPG, PNG, BMP, GIF (статичные), WebP
// Требования к видео:
// * максимум одно видео для одной карточки товара
// * максимальный размер — 50 Мб
// * форматы — MOV, MP4
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// POST /content/v3/media/file
func (s *Server) handleContentV3MediaFilePostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/content/v3/media/file"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV3MediaFilePostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV3MediaFilePostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV3MediaFilePostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
params, err := decodeContentV3MediaFilePostParams(args, argsEscaped, r)
if err != nil {
err = &ogenerrors.DecodeParamsError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeParams", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
request, close, err := s.decodeContentV3MediaFilePostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response ContentV3MediaFilePostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV3MediaFilePostOperation,
OperationSummary: "Загрузить медиафайл",
OperationID: "",
Body: request,
Params: middleware.Parameters{
{
Name: "X-Nm-Id",
In: "header",
}: params.XNmID,
{
Name: "X-Photo-Number",
In: "header",
}: params.XPhotoNumber,
},
Raw: r,
}
type (
Request = *ContentV3MediaFilePostReq
Params = ContentV3MediaFilePostParams
Response = ContentV3MediaFilePostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
unpackContentV3MediaFilePostParams,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV3MediaFilePost(ctx, request, params)
return response, err
},
)
} else {
response, err = s.h.ContentV3MediaFilePost(ctx, request, params)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV3MediaFilePostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}
// handleContentV3MediaSavePostRequest handles POST /content/v3/media/save operation.
//
// Метод загружает набор медиафайлов в карточку товара
// через указание ссылок в запросе.
// <div class="description_important">
// Новые медиафайлы полностью заменяют старые. Чтобы
// добавить новые медиафайлы, укажите в запросе ссылки
// одновременно на новые и старые медиафайлы.
// </div>
// Требования к изображениям:
// * максимум изображений для одной карточки товара — 30
// * минимальное разрешение — 700×900 px
// * максимальный размер — 32 Мб
// * минимальное качество — 65%
// * форматы — JPG, PNG, BMP, GIF (статичные), WebP
// Требования к видео:
// * максимум одно видео для одной карточки товара
// * максимальный размер — 50 Мб
// * форматы — MOV, MP4
// Если видео или хотя бы одно изображение в запросе не
// соответствует требованиям, то даже при успешном
// ответе ни одно изображение/видео не загрузится.
// <div class="description_limit">
// Максимум 100 запросов в <a
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
// методов категории <a
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
// аккаунт продавца. С 5 июня — за исключением методов <a
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
// </div>.
//
// POST /content/v3/media/save
func (s *Server) handleContentV3MediaSavePostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
statusWriter := &codeRecorder{ResponseWriter: w}
w = statusWriter
otelAttrs := []attribute.KeyValue{
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/content/v3/media/save"),
}
// Start a span for this request.
ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV3MediaSavePostOperation,
trace.WithAttributes(otelAttrs...),
serverSpanKind,
)
defer span.End()
// Add Labeler to context.
labeler := &Labeler{attrs: otelAttrs}
ctx = contextWithLabeler(ctx, labeler)
// Run stopwatch.
startTime := time.Now()
defer func() {
elapsedDuration := time.Since(startTime)
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
code := statusWriter.status
if code != 0 {
codeAttr := semconv.HTTPResponseStatusCode(code)
attrs = append(attrs, codeAttr)
span.SetAttributes(codeAttr)
}
attrOpt := metric.WithAttributes(attrs...)
// Increment request counter.
s.requests.Add(ctx, 1, attrOpt)
// Use floating point division here for higher precision (instead of Millisecond method).
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
}()
var (
recordError = func(stage string, err error) {
span.RecordError(err)
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
// max redirects exceeded), in which case status MUST be set to Error.
code := statusWriter.status
if code >= 100 && code < 500 {
span.SetStatus(codes.Error, stage)
}
attrSet := labeler.AttributeSet()
attrs := attrSet.ToSlice()
if code != 0 {
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
}
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
}
err error
opErrContext = ogenerrors.OperationContext{
Name: ContentV3MediaSavePostOperation,
ID: "",
}
)
{
type bitset = [1]uint8
var satisfied bitset
{
sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV3MediaSavePostOperation, r)
if err != nil {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Security: "HeaderApiKey",
Err: err,
}
defer recordError("Security:HeaderApiKey", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if ok {
satisfied[0] |= 1 << 0
ctx = sctx
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
err = &ogenerrors.SecurityError{
OperationContext: opErrContext,
Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied,
}
defer recordError("Security", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
}
request, close, err := s.decodeContentV3MediaSavePostRequest(r)
if err != nil {
err = &ogenerrors.DecodeRequestError{
OperationContext: opErrContext,
Err: err,
}
defer recordError("DecodeRequest", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
defer func() {
if err := close(); err != nil {
recordError("CloseRequest", err)
}
}()
var response ContentV3MediaSavePostRes
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
OperationName: ContentV3MediaSavePostOperation,
OperationSummary: "Загрузить медиафайлы по ссылкам",
OperationID: "",
Body: request,
Params: middleware.Parameters{},
Raw: r,
}
type (
Request = *ContentV3MediaSavePostReq
Params = struct{}
Response = ContentV3MediaSavePostRes
)
response, err = middleware.HookMiddleware[
Request,
Params,
Response,
](
m,
mreq,
nil,
func(ctx context.Context, request Request, params Params) (response Response, err error) {
response, err = s.h.ContentV3MediaSavePost(ctx, request)
return response, err
},
)
} else {
response, err = s.h.ContentV3MediaSavePost(ctx, request)
}
if err != nil {
defer recordError("Internal", err)
s.cfg.ErrorHandler(ctx, w, r, err)
return
}
if err := encodeContentV3MediaSavePostResponse(response, w, span); err != nil {
defer recordError("EncodeResponse", err)
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
s.cfg.ErrorHandler(ctx, w, r, err)
}
return
}
}