@greatapps/common 1.1.605 → 1.1.607

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,8 +4,25 @@ import { ApiError } from "../../../infra/api/types";
4
4
  import { buildQueryParams } from "../../../infra/utils/params";
5
5
  import { assertManagementPermission } from "../../auth/utils/assert-management-permission";
6
6
  import { getUserContext } from "../../auth/utils/get-user-context";
7
- import { CardSchema } from "../types";
7
+ import { CardSchema, SetupIntentSchema } from "../types";
8
8
  class CardsService {
9
+ async createSetupIntent() {
10
+ await assertManagementPermission("manage_cards");
11
+ const { id_account } = await getUserContext();
12
+ const response = await api.apps.post(
13
+ `/accounts/${id_account}/cards/action/setup-intent`,
14
+ {}
15
+ );
16
+ if (response.status === 0) {
17
+ throw new ApiError(
18
+ response.message || "Erro ao criar SetupIntent",
19
+ "CREATE_SETUP_INTENT_FAILED",
20
+ 400
21
+ );
22
+ }
23
+ const data = SetupIntentSchema.parse(response.data[0]);
24
+ return { success: true, data };
25
+ }
9
26
  async listCards() {
10
27
  await assertManagementPermission("view_cards");
11
28
  const { id_account } = await getUserContext();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/cards/services/cards.service.ts"],"sourcesContent":["import 'server-only';\n\nimport { api } from '../../../infra/api/client';\nimport { ApiError, ApiActionResult, ApiPaginatedActionResult, PaginatedSuccessResult, SuccessResult } from '../../../infra/api/types';\nimport { buildQueryParams } from '../../../infra/utils/params';\nimport { assertManagementPermission } from '../../auth/utils/assert-management-permission';\nimport { getUserContext } from '../../auth/utils/get-user-context';\nimport { Card, CardSchema, CreateCardRequest } from '../types';\n\nclass CardsService {\n async listCards(): Promise<PaginatedSuccessResult<Card>> {\n await assertManagementPermission('view_cards');\n const { id_account } = await getUserContext();\n\n const query = buildQueryParams({ id_account });\n const response = await api.apps.get<ApiPaginatedActionResult<Card>>(\n `/accounts/${id_account}/cards?${query}`\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao listar cartões',\n 'LIST_CARDS_FAILED',\n 400\n );\n }\n\n const data = response.data.map((item) => CardSchema.parse(item));\n\n return { data, total: response.total, success: true };\n }\n\n async findCardById(id: number): Promise<SuccessResult<Card>> {\n await assertManagementPermission('view_cards');\n const { id_account } = await getUserContext();\n\n const response = await api.apps.get<ApiPaginatedActionResult<Card>>(\n `/accounts/${id_account}/cards/${id}`\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao buscar cartão',\n 'FIND_CARD_BY_ID_FAILED',\n 400\n );\n }\n\n if (!response.data?.length) {\n throw new ApiError('Cartão não encontrado', 'CARD_NOT_FOUND', 404);\n }\n\n const data = CardSchema.parse(response.data[0]);\n\n return { success: true, data };\n }\n\n async createCard(data: CreateCardRequest): Promise<SuccessResult<Card>> {\n await assertManagementPermission('manage_cards');\n const { id_account } = await getUserContext();\n\n const response = await api.apps.post<ApiPaginatedActionResult<Card>>(\n `/accounts/${id_account}/cards`,\n data\n );\n\n if (response.status === 0) {\n throw new ApiError(response.message || 'Erro ao criar cartão', 'CREATE_CARD_FAILED', 400);\n }\n\n const cardData = CardSchema.parse(response.data[0]);\n\n return { success: true, data: cardData };\n }\n\n async setDefaultCard(cardId: string): Promise<SuccessResult<Card>> {\n await assertManagementPermission('manage_cards');\n const { id_account } = await getUserContext();\n\n const response = await api.apps.put<ApiPaginatedActionResult<Card>>(\n `/accounts/${id_account}/cards/${cardId}`,\n { set_default: true }\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao definir cartão padrão',\n 'SET_DEFAULT_CARD_FAILED',\n 400\n );\n }\n\n const data = CardSchema.parse(response.data[0]);\n\n return { success: true, data };\n }\n\n async deleteCard(id: string): Promise<SuccessResult<void>> {\n await assertManagementPermission('manage_cards');\n const { id_account } = await getUserContext();\n\n const response = await api.apps.delete<ApiActionResult<void>>(\n `/accounts/${id_account}/cards/${id}`\n );\n\n if (response.status === 0) {\n throw new ApiError(response.message || 'Erro ao excluir cartão', 'DELETE_CARD_FAILED', 400);\n }\n\n return { success: true };\n }\n}\n\nexport const cardsService = new CardsService();\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,WAAW;AACpB,SAAS,gBAAkG;AAC3G,SAAS,wBAAwB;AACjC,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;AAC/B,SAAe,kBAAqC;AAEpD,MAAM,aAAa;AAAA,EACjB,MAAM,YAAmD;AACvD,UAAM,2BAA2B,YAAY;AAC7C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,QAAQ,iBAAiB,EAAE,WAAW,CAAC;AAC7C,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,aAAa,UAAU,UAAU,KAAK;AAAA,IACxC;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,SAAS,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO,SAAS,KAAK,IAAI,CAAC,SAAS,WAAW,MAAM,IAAI,CAAC;AAE/D,WAAO,EAAE,MAAM,OAAO,SAAS,OAAO,SAAS,KAAK;AAAA,EACtD;AAAA,EAEA,MAAM,aAAa,IAA0C;AAC3D,UAAM,2BAA2B,YAAY;AAC7C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,aAAa,UAAU,UAAU,EAAE;AAAA,IACrC;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,SAAS,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,MAAM,QAAQ;AAC1B,YAAM,IAAI,SAAS,+BAAyB,kBAAkB,GAAG;AAAA,IACnE;AAEA,UAAM,OAAO,WAAW,MAAM,SAAS,KAAK,CAAC,CAAC;AAE9C,WAAO,EAAE,SAAS,MAAM,KAAK;AAAA,EAC/B;AAAA,EAEA,MAAM,WAAW,MAAuD;AACtE,UAAM,2BAA2B,cAAc;AAC/C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,aAAa,UAAU;AAAA,MACvB;AAAA,IACF;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI,SAAS,SAAS,WAAW,2BAAwB,sBAAsB,GAAG;AAAA,IAC1F;AAEA,UAAM,WAAW,WAAW,MAAM,SAAS,KAAK,CAAC,CAAC;AAElD,WAAO,EAAE,SAAS,MAAM,MAAM,SAAS;AAAA,EACzC;AAAA,EAEA,MAAM,eAAe,QAA8C;AACjE,UAAM,2BAA2B,cAAc;AAC/C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,aAAa,UAAU,UAAU,MAAM;AAAA,MACvC,EAAE,aAAa,KAAK;AAAA,IACtB;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,SAAS,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO,WAAW,MAAM,SAAS,KAAK,CAAC,CAAC;AAE9C,WAAO,EAAE,SAAS,MAAM,KAAK;AAAA,EAC/B;AAAA,EAEA,MAAM,WAAW,IAA0C;AACzD,UAAM,2BAA2B,cAAc;AAC/C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,aAAa,UAAU,UAAU,EAAE;AAAA,IACrC;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI,SAAS,SAAS,WAAW,6BAA0B,sBAAsB,GAAG;AAAA,IAC5F;AAEA,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AACF;AAEO,MAAM,eAAe,IAAI,aAAa;","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/cards/services/cards.service.ts"],"sourcesContent":["import 'server-only';\n\nimport { api } from '../../../infra/api/client';\nimport { ApiError, ApiActionResult, ApiPaginatedActionResult, PaginatedSuccessResult, SuccessResult } from '../../../infra/api/types';\nimport { buildQueryParams } from '../../../infra/utils/params';\nimport { assertManagementPermission } from '../../auth/utils/assert-management-permission';\nimport { getUserContext } from '../../auth/utils/get-user-context';\nimport { Card, CardSchema, CreateCardRequest, SetupIntent, SetupIntentSchema } from '../types';\n\nclass CardsService {\n async createSetupIntent(): Promise<SuccessResult<SetupIntent>> {\n await assertManagementPermission('manage_cards');\n const { id_account } = await getUserContext();\n\n const response = await api.apps.post<ApiPaginatedActionResult<SetupIntent>>(\n `/accounts/${id_account}/cards/action/setup-intent`,\n {}\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao criar SetupIntent',\n 'CREATE_SETUP_INTENT_FAILED',\n 400\n );\n }\n\n const data = SetupIntentSchema.parse(response.data[0]);\n\n return { success: true, data };\n }\n\n async listCards(): Promise<PaginatedSuccessResult<Card>> {\n await assertManagementPermission('view_cards');\n const { id_account } = await getUserContext();\n\n const query = buildQueryParams({ id_account });\n const response = await api.apps.get<ApiPaginatedActionResult<Card>>(\n `/accounts/${id_account}/cards?${query}`\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao listar cartões',\n 'LIST_CARDS_FAILED',\n 400\n );\n }\n\n const data = response.data.map((item) => CardSchema.parse(item));\n\n return { data, total: response.total, success: true };\n }\n\n async findCardById(id: number): Promise<SuccessResult<Card>> {\n await assertManagementPermission('view_cards');\n const { id_account } = await getUserContext();\n\n const response = await api.apps.get<ApiPaginatedActionResult<Card>>(\n `/accounts/${id_account}/cards/${id}`\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao buscar cartão',\n 'FIND_CARD_BY_ID_FAILED',\n 400\n );\n }\n\n if (!response.data?.length) {\n throw new ApiError('Cartão não encontrado', 'CARD_NOT_FOUND', 404);\n }\n\n const data = CardSchema.parse(response.data[0]);\n\n return { success: true, data };\n }\n\n async createCard(data: CreateCardRequest): Promise<SuccessResult<Card>> {\n await assertManagementPermission('manage_cards');\n const { id_account } = await getUserContext();\n\n const response = await api.apps.post<ApiPaginatedActionResult<Card>>(\n `/accounts/${id_account}/cards`,\n data\n );\n\n if (response.status === 0) {\n throw new ApiError(response.message || 'Erro ao criar cartão', 'CREATE_CARD_FAILED', 400);\n }\n\n const cardData = CardSchema.parse(response.data[0]);\n\n return { success: true, data: cardData };\n }\n\n async setDefaultCard(cardId: string): Promise<SuccessResult<Card>> {\n await assertManagementPermission('manage_cards');\n const { id_account } = await getUserContext();\n\n const response = await api.apps.put<ApiPaginatedActionResult<Card>>(\n `/accounts/${id_account}/cards/${cardId}`,\n { set_default: true }\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao definir cartão padrão',\n 'SET_DEFAULT_CARD_FAILED',\n 400\n );\n }\n\n const data = CardSchema.parse(response.data[0]);\n\n return { success: true, data };\n }\n\n async deleteCard(id: string): Promise<SuccessResult<void>> {\n await assertManagementPermission('manage_cards');\n const { id_account } = await getUserContext();\n\n const response = await api.apps.delete<ApiActionResult<void>>(\n `/accounts/${id_account}/cards/${id}`\n );\n\n if (response.status === 0) {\n throw new ApiError(response.message || 'Erro ao excluir cartão', 'DELETE_CARD_FAILED', 400);\n }\n\n return { success: true };\n }\n}\n\nexport const cardsService = new CardsService();\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,WAAW;AACpB,SAAS,gBAAkG;AAC3G,SAAS,wBAAwB;AACjC,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;AAC/B,SAAe,YAA4C,yBAAyB;AAEpF,MAAM,aAAa;AAAA,EACjB,MAAM,oBAAyD;AAC7D,UAAM,2BAA2B,cAAc;AAC/C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,aAAa,UAAU;AAAA,MACvB,CAAC;AAAA,IACH;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,SAAS,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO,kBAAkB,MAAM,SAAS,KAAK,CAAC,CAAC;AAErD,WAAO,EAAE,SAAS,MAAM,KAAK;AAAA,EAC/B;AAAA,EAEA,MAAM,YAAmD;AACvD,UAAM,2BAA2B,YAAY;AAC7C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,QAAQ,iBAAiB,EAAE,WAAW,CAAC;AAC7C,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,aAAa,UAAU,UAAU,KAAK;AAAA,IACxC;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,SAAS,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO,SAAS,KAAK,IAAI,CAAC,SAAS,WAAW,MAAM,IAAI,CAAC;AAE/D,WAAO,EAAE,MAAM,OAAO,SAAS,OAAO,SAAS,KAAK;AAAA,EACtD;AAAA,EAEA,MAAM,aAAa,IAA0C;AAC3D,UAAM,2BAA2B,YAAY;AAC7C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,aAAa,UAAU,UAAU,EAAE;AAAA,IACrC;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,SAAS,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,MAAM,QAAQ;AAC1B,YAAM,IAAI,SAAS,+BAAyB,kBAAkB,GAAG;AAAA,IACnE;AAEA,UAAM,OAAO,WAAW,MAAM,SAAS,KAAK,CAAC,CAAC;AAE9C,WAAO,EAAE,SAAS,MAAM,KAAK;AAAA,EAC/B;AAAA,EAEA,MAAM,WAAW,MAAuD;AACtE,UAAM,2BAA2B,cAAc;AAC/C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,aAAa,UAAU;AAAA,MACvB;AAAA,IACF;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI,SAAS,SAAS,WAAW,2BAAwB,sBAAsB,GAAG;AAAA,IAC1F;AAEA,UAAM,WAAW,WAAW,MAAM,SAAS,KAAK,CAAC,CAAC;AAElD,WAAO,EAAE,SAAS,MAAM,MAAM,SAAS;AAAA,EACzC;AAAA,EAEA,MAAM,eAAe,QAA8C;AACjE,UAAM,2BAA2B,cAAc;AAC/C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,aAAa,UAAU,UAAU,MAAM;AAAA,MACvC,EAAE,aAAa,KAAK;AAAA,IACtB;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,SAAS,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO,WAAW,MAAM,SAAS,KAAK,CAAC,CAAC;AAE9C,WAAO,EAAE,SAAS,MAAM,KAAK;AAAA,EAC/B;AAAA,EAEA,MAAM,WAAW,IAA0C;AACzD,UAAM,2BAA2B,cAAc;AAC/C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,WAAW,MAAM,IAAI,KAAK;AAAA,MAC9B,aAAa,UAAU,UAAU,EAAE;AAAA,IACrC;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI,SAAS,SAAS,WAAW,6BAA0B,sBAAsB,GAAG;AAAA,IAC5F;AAEA,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AACF;AAEO,MAAM,eAAe,IAAI,aAAa;","names":[]}
@@ -22,15 +22,21 @@ const CardSchema = z.object({
22
22
  datetime_del: z.union([z.date(), z.coerce.date()]).nullable().optional()
23
23
  });
24
24
  const CreateCardRequestSchema = z.object({
25
- payment_method_id: z.string().min(1, "payment_method_id \xE9 obrigat\xF3rio"),
25
+ setup_intent_id: z.string().min(1, "setup_intent_id \xE9 obrigat\xF3rio"),
26
+ name: z.string().min(1, "name \xE9 obrigat\xF3rio"),
26
27
  set_default: z.boolean().optional()
27
28
  });
29
+ const SetupIntentSchema = z.object({
30
+ client_secret: z.string(),
31
+ setup_intent_id: z.string()
32
+ });
28
33
  const FindCardsParamsSchema = PaginationParamsSchema.extend(SearchParamsSchema.shape).extend(
29
34
  SortParamsSchema.shape
30
35
  );
31
36
  export {
32
37
  CardSchema,
33
38
  CreateCardRequestSchema,
34
- FindCardsParamsSchema
39
+ FindCardsParamsSchema,
40
+ SetupIntentSchema
35
41
  };
36
42
  //# sourceMappingURL=types.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/modules/cards/types.ts"],"sourcesContent":["import z from 'zod';\n\nimport {\n PaginationParamsSchema,\n SearchParamsSchema,\n SortParamsSchema,\n} from '../../infra/api/types';\n\nexport const CardSchema = z.object({\n id: z.union([z.number(), z.string()]),\n id_wl: z.number(),\n id_account: z.union([z.number(), z.string()]),\n id_gateway: z.union([z.number(), z.string()]).optional(),\n gateway_account: z.string(),\n gateway_card: z.string(),\n brand: z.string(),\n name: z.string(),\n number: z.string().nullable(),\n date: z.string().nullable(),\n deleted: z\n .number()\n .transform((val) => val === 1)\n .optional()\n .default(false),\n is_default: z.boolean().optional().default(false),\n datetime_add: z.union([z.date(), z.coerce.date()]).nullable().optional(),\n datetime_alt: z.union([z.date(), z.coerce.date()]).nullable().optional(),\n datetime_del: z.union([z.date(), z.coerce.date()]).nullable().optional(),\n});\n\nexport type Card = z.infer<typeof CardSchema>;\n\nexport const CreateCardRequestSchema = z.object({\n payment_method_id: z.string().min(1, 'payment_method_id é obrigatório'),\n set_default: z.boolean().optional(),\n});\n\nexport type CreateCardRequest = z.infer<typeof CreateCardRequestSchema>;\n\nexport const FindCardsParamsSchema = PaginationParamsSchema.extend(SearchParamsSchema.shape).extend(\n SortParamsSchema.shape\n);\n\nexport type FindCardsParams = z.infer<typeof FindCardsParamsSchema>;\n"],"mappings":"AAAA,OAAO,OAAO;AAEd;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,MAAM,aAAa,EAAE,OAAO;AAAA,EACjC,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACpC,OAAO,EAAE,OAAO;AAAA,EAChB,YAAY,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EAC5C,YAAY,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACvD,iBAAiB,EAAE,OAAO;AAAA,EAC1B,cAAc,EAAE,OAAO;AAAA,EACvB,OAAO,EAAE,OAAO;AAAA,EAChB,MAAM,EAAE,OAAO;AAAA,EACf,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,SAAS,EACN,OAAO,EACP,UAAU,CAAC,QAAQ,QAAQ,CAAC,EAC5B,SAAS,EACT,QAAQ,KAAK;AAAA,EAChB,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK;AAAA,EAChD,cAAc,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS;AAAA,EACvE,cAAc,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS;AAAA,EACvE,cAAc,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS;AACzE,CAAC;AAIM,MAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,mBAAmB,EAAE,OAAO,EAAE,IAAI,GAAG,uCAAiC;AAAA,EACtE,aAAa,EAAE,QAAQ,EAAE,SAAS;AACpC,CAAC;AAIM,MAAM,wBAAwB,uBAAuB,OAAO,mBAAmB,KAAK,EAAE;AAAA,EAC3F,iBAAiB;AACnB;","names":[]}
1
+ {"version":3,"sources":["../../../src/modules/cards/types.ts"],"sourcesContent":["import z from 'zod';\n\nimport {\n PaginationParamsSchema,\n SearchParamsSchema,\n SortParamsSchema,\n} from '../../infra/api/types';\n\nexport const CardSchema = z.object({\n id: z.union([z.number(), z.string()]),\n id_wl: z.number(),\n id_account: z.union([z.number(), z.string()]),\n id_gateway: z.union([z.number(), z.string()]).optional(),\n gateway_account: z.string(),\n gateway_card: z.string(),\n brand: z.string(),\n name: z.string(),\n number: z.string().nullable(),\n date: z.string().nullable(),\n deleted: z\n .number()\n .transform((val) => val === 1)\n .optional()\n .default(false),\n is_default: z.boolean().optional().default(false),\n datetime_add: z.union([z.date(), z.coerce.date()]).nullable().optional(),\n datetime_alt: z.union([z.date(), z.coerce.date()]).nullable().optional(),\n datetime_del: z.union([z.date(), z.coerce.date()]).nullable().optional(),\n});\n\nexport type Card = z.infer<typeof CardSchema>;\n\nexport const CreateCardRequestSchema = z.object({\n setup_intent_id: z.string().min(1, 'setup_intent_id é obrigatório'),\n name: z.string().min(1, 'name é obrigatório'),\n set_default: z.boolean().optional(),\n});\n\nexport type CreateCardRequest = z.infer<typeof CreateCardRequestSchema>;\n\nexport const SetupIntentSchema = z.object({\n client_secret: z.string(),\n setup_intent_id: z.string(),\n});\n\nexport type SetupIntent = z.infer<typeof SetupIntentSchema>;\n\nexport const FindCardsParamsSchema = PaginationParamsSchema.extend(SearchParamsSchema.shape).extend(\n SortParamsSchema.shape\n);\n\nexport type FindCardsParams = z.infer<typeof FindCardsParamsSchema>;\n"],"mappings":"AAAA,OAAO,OAAO;AAEd;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,MAAM,aAAa,EAAE,OAAO;AAAA,EACjC,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACpC,OAAO,EAAE,OAAO;AAAA,EAChB,YAAY,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EAC5C,YAAY,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACvD,iBAAiB,EAAE,OAAO;AAAA,EAC1B,cAAc,EAAE,OAAO;AAAA,EACvB,OAAO,EAAE,OAAO;AAAA,EAChB,MAAM,EAAE,OAAO;AAAA,EACf,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,SAAS,EACN,OAAO,EACP,UAAU,CAAC,QAAQ,QAAQ,CAAC,EAC5B,SAAS,EACT,QAAQ,KAAK;AAAA,EAChB,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK;AAAA,EAChD,cAAc,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS;AAAA,EACvE,cAAc,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS;AAAA,EACvE,cAAc,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS;AACzE,CAAC;AAIM,MAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,iBAAiB,EAAE,OAAO,EAAE,IAAI,GAAG,qCAA+B;AAAA,EAClE,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,0BAAoB;AAAA,EAC5C,aAAa,EAAE,QAAQ,EAAE,SAAS;AACpC,CAAC;AAIM,MAAM,oBAAoB,EAAE,OAAO;AAAA,EACxC,eAAe,EAAE,OAAO;AAAA,EACxB,iBAAiB,EAAE,OAAO;AAC5B,CAAC;AAIM,MAAM,wBAAwB,uBAAuB,OAAO,mBAAmB,KAAK,EAAE;AAAA,EAC3F,iBAAiB;AACnB;","names":[]}
package/dist/server.mjs CHANGED
@@ -25,6 +25,7 @@ import { updateSubscriptionPlanAction } from "./modules/subscriptions/actions/up
25
25
  import { updateSubscriptionPaymentAction } from "./modules/subscriptions/actions/update-subscription-payment.action";
26
26
  import { listCardsAction } from "./modules/cards/actions/list-cards.action";
27
27
  import { createCardAction } from "./modules/cards/actions/create-card.action";
28
+ import { createSetupIntentAction } from "./modules/cards/actions/create-setup-intent.action";
28
29
  import { listChargesAction } from "./modules/charges/actions/list-charges.action";
29
30
  import { findChargeByIdAction } from "./modules/charges/actions/find-charge-by-id.action";
30
31
  import { chargeActionAction } from "./modules/charges/actions/charge-action.action";
@@ -96,6 +97,7 @@ export {
96
97
  createAccountUserAction,
97
98
  createCardAction,
98
99
  createProjectAction,
100
+ createSetupIntentAction,
99
101
  deleteAccountAction,
100
102
  deleteAccountUserAction,
101
103
  deleteProjectAction,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import 'server-only';\r\n\r\n// API Client\r\nexport { ApiClient, api, apiClient } from './infra/api/client';\r\n\r\n// Services\r\nexport { authService } from './modules/auth/services/auth.service';\r\nexport { whitelabelService } from './modules/whitelabel/services/whitelabel.service';\r\nexport { revalidateWhitelabelAction } from './modules/whitelabel/actions/revalidate-whitelabel.action';\r\nexport { assertManagementPermission } from './modules/auth/utils/assert-management-permission';\r\nexport { assertManagementSubscription } from './modules/auth/utils/assert-management-subscription';\r\nexport { assertSubscriptionAddon } from './modules/auth/utils/assert-subscription-addon';\r\nexport { assertPaidSubscription } from './modules/auth/utils/assert-paid-subscription';\r\nexport { subscriptionsService } from './modules/subscriptions/services/subscriptions.service';\r\nexport { plansService } from './modules/plans/services/plans.service';\r\nexport { cardsService } from './modules/cards/services/cards.service';\r\nexport { chargesService } from './modules/charges/services/charges.service';\r\nexport { iaCreditsService } from './modules/ia-credits/services/ia-credits.service';\r\n\r\n// Actions\r\nexport { findWhitelabel } from './modules/whitelabel/actions/find-whitelabel.action';\r\nexport { validateSessionAction } from './modules/auth/actions/validate-session.action';\r\nexport { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { getAccountTokenAction } from './modules/accounts/actions/get-account-token.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport { findPlanByIdAction } from './modules/plans/actions/find-plan-by-id.action';\r\nexport { listPlansAction } from './modules/plans/actions/list-plans.action';\r\nexport { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';\r\nexport { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';\r\nexport { updateSubscriptionPaymentAction } from './modules/subscriptions/actions/update-subscription-payment.action';\r\nexport { listCardsAction } from './modules/cards/actions/list-cards.action';\r\nexport { createCardAction } from './modules/cards/actions/create-card.action';\r\nexport { listChargesAction } from './modules/charges/actions/list-charges.action';\r\nexport { findChargeByIdAction } from './modules/charges/actions/find-charge-by-id.action';\r\nexport { chargeActionAction } from './modules/charges/actions/charge-action.action';\r\nexport { resolvePlanExtrasPrices } from './modules/subscriptions/utils/resolve-plan-extras-prices';\r\nexport { hasSubscriptionExpired } from './modules/subscriptions/utils/has-subscription-expired';\r\nexport { listIaCreditsAction } from './modules/ia-credits/actions/list-ia-credits.action';\r\nexport { countPagesAction } from './modules/pages/actions/count-pages.action';\r\n\r\n// Project Services & Actions (server-only)\r\nexport { projectsService } from './modules/projects/services/projects.service';\r\nexport { listProjectsAction } from './modules/projects/actions/list-projects.action';\r\nexport { findProjectAction } from './modules/projects/actions/find-project.action';\r\nexport { createProjectAction } from './modules/projects/actions/create-project.action';\r\nexport { updateProjectAction } from './modules/projects/actions/update-project.action';\r\nexport { deleteProjectAction } from './modules/projects/actions/delete-project.action';\r\n\r\n// Project Users Services & Actions (server-only)\r\nexport { projectUsersService } from './modules/projects/services/project-users.service';\r\nexport { listProjectUsersAction } from './modules/projects/actions/list-project-users.action';\r\nexport { listAvailableUsersAction } from './modules/projects/actions/list-available-users.action';\r\nexport { addProjectUserAction } from './modules/projects/actions/add-project-user.action';\r\nexport { removeProjectUserAction } from './modules/projects/actions/remove-project-user.action';\r\n\r\n// Account Services & Actions (server-only)\r\nexport { accountService } from './modules/accounts/services/account.service';\r\nexport { twoFactorService } from './modules/accounts/services/two-factor.service';\r\nexport {\r\n listAccountUsersAction,\r\n updateUserAction,\r\n updateAccountAction,\r\n updateAccountUserByIdAction,\r\n deleteAccountUserAction,\r\n deleteAccountAction,\r\n createAccountUserAction,\r\n changePasswordAction,\r\n requestEmailChangeAction,\r\n confirmEmailChangeAction,\r\n requestPhoneChangeAction,\r\n confirmPhoneChangeAction,\r\n generateTwoFactorAction,\r\n confirmTwoFactorAction,\r\n disableTwoFactorAction,\r\n} from './modules/accounts/actions/account-management.action';\r\n\r\n// Server Utils\r\nexport { getClientInfoFromRequest } from './infra/utils/client-info';\r\nexport { getUserContext } from './modules/auth/utils/get-user-context';\r\nexport { requireValidSession } from './modules/auth/utils/require-valid-session';\r\nexport { requireTokenNotExpired } from './modules/auth/utils/require-token-not-expired';\r\nexport { buildWlOverride, buildWlOverrideFromJwt } from './modules/auth/utils/build-wl-override';\r\nexport { safeServerAction } from './utils/safeServerAction';\r\nexport { safeMutationAction } from './utils/safeMutationAction';\r\n\r\n// Image Processing (server-side)\r\nexport { processImageAction } from './modules/images/actions/process-image.action';\r\nexport { processImage } from './modules/images/services/image-processing.service';\r\nexport type {\r\n ProcessImageInput,\r\n ProcessImageOutput,\r\n ProcessImageActionInput,\r\n ProcessImageActionOutput,\r\n} from './modules/images/types/image.type';\r\n"],"mappings":"AAAA,OAAO;AAGP,SAAS,WAAW,KAAK,iBAAiB;AAG1C,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAC3C,SAAS,kCAAkC;AAC3C,SAAS,oCAAoC;AAC7C,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAGjC,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,uBAAuB;AAChC,SAAS,mCAAmC;AAC5C,SAAS,oCAAoC;AAC7C,SAAS,uCAAuC;AAChD,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AAGjC,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAGpC,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,gCAAgC;AACzC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AAGxC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,gCAAgC;AACzC,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,iBAAiB,8BAA8B;AACxD,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AAGnC,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;","names":[]}
1
+ {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import 'server-only';\r\n\r\n// API Client\r\nexport { ApiClient, api, apiClient } from './infra/api/client';\r\n\r\n// Services\r\nexport { authService } from './modules/auth/services/auth.service';\r\nexport { whitelabelService } from './modules/whitelabel/services/whitelabel.service';\r\nexport { revalidateWhitelabelAction } from './modules/whitelabel/actions/revalidate-whitelabel.action';\r\nexport { assertManagementPermission } from './modules/auth/utils/assert-management-permission';\r\nexport { assertManagementSubscription } from './modules/auth/utils/assert-management-subscription';\r\nexport { assertSubscriptionAddon } from './modules/auth/utils/assert-subscription-addon';\r\nexport { assertPaidSubscription } from './modules/auth/utils/assert-paid-subscription';\r\nexport { subscriptionsService } from './modules/subscriptions/services/subscriptions.service';\r\nexport { plansService } from './modules/plans/services/plans.service';\r\nexport { cardsService } from './modules/cards/services/cards.service';\r\nexport { chargesService } from './modules/charges/services/charges.service';\r\nexport { iaCreditsService } from './modules/ia-credits/services/ia-credits.service';\r\n\r\n// Actions\r\nexport { findWhitelabel } from './modules/whitelabel/actions/find-whitelabel.action';\r\nexport { validateSessionAction } from './modules/auth/actions/validate-session.action';\r\nexport { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { getAccountTokenAction } from './modules/accounts/actions/get-account-token.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport { findPlanByIdAction } from './modules/plans/actions/find-plan-by-id.action';\r\nexport { listPlansAction } from './modules/plans/actions/list-plans.action';\r\nexport { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';\r\nexport { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';\r\nexport { updateSubscriptionPaymentAction } from './modules/subscriptions/actions/update-subscription-payment.action';\r\nexport { listCardsAction } from './modules/cards/actions/list-cards.action';\r\nexport { createCardAction } from './modules/cards/actions/create-card.action';\r\nexport { createSetupIntentAction } from './modules/cards/actions/create-setup-intent.action';\r\nexport { listChargesAction } from './modules/charges/actions/list-charges.action';\r\nexport { findChargeByIdAction } from './modules/charges/actions/find-charge-by-id.action';\r\nexport { chargeActionAction } from './modules/charges/actions/charge-action.action';\r\nexport { resolvePlanExtrasPrices } from './modules/subscriptions/utils/resolve-plan-extras-prices';\r\nexport { hasSubscriptionExpired } from './modules/subscriptions/utils/has-subscription-expired';\r\nexport { listIaCreditsAction } from './modules/ia-credits/actions/list-ia-credits.action';\r\nexport { countPagesAction } from './modules/pages/actions/count-pages.action';\r\n\r\n// Project Services & Actions (server-only)\r\nexport { projectsService } from './modules/projects/services/projects.service';\r\nexport { listProjectsAction } from './modules/projects/actions/list-projects.action';\r\nexport { findProjectAction } from './modules/projects/actions/find-project.action';\r\nexport { createProjectAction } from './modules/projects/actions/create-project.action';\r\nexport { updateProjectAction } from './modules/projects/actions/update-project.action';\r\nexport { deleteProjectAction } from './modules/projects/actions/delete-project.action';\r\n\r\n// Project Users Services & Actions (server-only)\r\nexport { projectUsersService } from './modules/projects/services/project-users.service';\r\nexport { listProjectUsersAction } from './modules/projects/actions/list-project-users.action';\r\nexport { listAvailableUsersAction } from './modules/projects/actions/list-available-users.action';\r\nexport { addProjectUserAction } from './modules/projects/actions/add-project-user.action';\r\nexport { removeProjectUserAction } from './modules/projects/actions/remove-project-user.action';\r\n\r\n// Account Services & Actions (server-only)\r\nexport { accountService } from './modules/accounts/services/account.service';\r\nexport { twoFactorService } from './modules/accounts/services/two-factor.service';\r\nexport {\r\n listAccountUsersAction,\r\n updateUserAction,\r\n updateAccountAction,\r\n updateAccountUserByIdAction,\r\n deleteAccountUserAction,\r\n deleteAccountAction,\r\n createAccountUserAction,\r\n changePasswordAction,\r\n requestEmailChangeAction,\r\n confirmEmailChangeAction,\r\n requestPhoneChangeAction,\r\n confirmPhoneChangeAction,\r\n generateTwoFactorAction,\r\n confirmTwoFactorAction,\r\n disableTwoFactorAction,\r\n} from './modules/accounts/actions/account-management.action';\r\n\r\n// Server Utils\r\nexport { getClientInfoFromRequest } from './infra/utils/client-info';\r\nexport { getUserContext } from './modules/auth/utils/get-user-context';\r\nexport { requireValidSession } from './modules/auth/utils/require-valid-session';\r\nexport { requireTokenNotExpired } from './modules/auth/utils/require-token-not-expired';\r\nexport { buildWlOverride, buildWlOverrideFromJwt } from './modules/auth/utils/build-wl-override';\r\nexport { safeServerAction } from './utils/safeServerAction';\r\nexport { safeMutationAction } from './utils/safeMutationAction';\r\n\r\n// Image Processing (server-side)\r\nexport { processImageAction } from './modules/images/actions/process-image.action';\r\nexport { processImage } from './modules/images/services/image-processing.service';\r\nexport type {\r\n ProcessImageInput,\r\n ProcessImageOutput,\r\n ProcessImageActionInput,\r\n ProcessImageActionOutput,\r\n} from './modules/images/types/image.type';\r\n"],"mappings":"AAAA,OAAO;AAGP,SAAS,WAAW,KAAK,iBAAiB;AAG1C,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAC3C,SAAS,kCAAkC;AAC3C,SAAS,oCAAoC;AAC7C,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAGjC,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,uBAAuB;AAChC,SAAS,mCAAmC;AAC5C,SAAS,oCAAoC;AAC7C,SAAS,uCAAuC;AAChD,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AAGjC,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAGpC,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,gCAAgC;AACzC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AAGxC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,gCAAgC;AACzC,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,iBAAiB,8BAA8B;AACxD,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AAGnC,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/common",
3
- "version": "1.1.605",
3
+ "version": "1.1.607",
4
4
  "description": "Shared library for GreatApps frontend applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./src/index.ts",
@@ -6,11 +6,13 @@ import { Button } from '../../ui/buttons/Button';
6
6
  import { Toast } from '../../ui/feedback/Toast';
7
7
  import { useModalManager } from '../../../store/useModalManager';
8
8
  import { useCreateCard } from '../../../modules/cards/hooks/create-card.hook';
9
+ import { useCreateSetupIntent } from '../../../modules/cards/hooks/create-setup-intent.hook';
9
10
  import { useUpdateAccount } from '../../../modules/accounts/hooks/useAccountManagement';
10
11
  import { useExternalContracting } from '../../../providers/whitelabel.provider';
11
12
  import { CardFormFields, BillingFormFields, cardFormSchema } from './CardFormFields';
12
13
  import type { CardFormData, StripeElementsStatus } from './CardFormFields';
13
- import { IconLoader2, IconX, IconCreditCard } from '@tabler/icons-react';
14
+ import { IconLoader2, IconX, IconCreditCard, IconCheck, IconChevronRight } from '@tabler/icons-react';
15
+ import { cn } from '../../../infra/utils/clsx';
14
16
  import { useForm } from 'react-hook-form';
15
17
  import { zodResolver } from '@hookform/resolvers/zod';
16
18
  import { CardNumberElement, useElements, useStripe } from '@stripe/react-stripe-js';
@@ -22,6 +24,49 @@ const INITIAL_STRIPE_STATUS: StripeElementsStatus = {
22
24
  cardCvc: false,
23
25
  };
24
26
 
27
+ const STEPS = [
28
+ { number: 1, label: 'Cobrança' },
29
+ { number: 2, label: 'Cartão' },
30
+ ] as const;
31
+
32
+ function CardStepper({ currentStep }: { readonly currentStep: number }) {
33
+ return (
34
+ <div className="flex items-center justify-center gap-2 px-4 py-3 border-b border-zinc-200 lg:border-b-0">
35
+ {STEPS.map((step, idx) => {
36
+ const isCompleted = currentStep > step.number;
37
+ const isCurrent = currentStep === step.number;
38
+ const isPending = !isCompleted && !isCurrent;
39
+ return (
40
+ <div key={step.number} className="flex items-center gap-2">
41
+ <div
42
+ className={cn(
43
+ 'flex items-center justify-center size-6 rounded-full paragraph-xsmall-semibold',
44
+ isCompleted && 'bg-green-500 text-white',
45
+ isCurrent && 'bg-primary text-white',
46
+ isPending && 'border border-zinc-200 text-zinc-400',
47
+ )}
48
+ >
49
+ {isCompleted ? <IconCheck size={14} stroke={3} /> : step.number}
50
+ </div>
51
+ <span
52
+ className={cn(
53
+ 'paragraph-xsmall-semibold',
54
+ (isCompleted || isCurrent) && 'text-zinc-950',
55
+ isPending && 'text-zinc-400',
56
+ )}
57
+ >
58
+ {step.label}
59
+ </span>
60
+ {idx < STEPS.length - 1 && (
61
+ <IconChevronRight size={16} className="text-zinc-300 ml-1" />
62
+ )}
63
+ </div>
64
+ );
65
+ })}
66
+ </div>
67
+ );
68
+ }
69
+
25
70
  export default function AddCardModal() {
26
71
  const { activeModal, modalData, closeModal } = useModalManager();
27
72
  const isOpen = activeModal === 'addCardModal';
@@ -29,9 +74,11 @@ export default function AddCardModal() {
29
74
  const [currentStep, setCurrentStep] = useState(1);
30
75
  const [stripeStatus, setStripeStatus] = useState<StripeElementsStatus>(INITIAL_STRIPE_STATUS);
31
76
  const [stripeErrors, setStripeErrors] = useState<Record<string, string | undefined>>({});
77
+ const [isAuthenticating, setIsAuthenticating] = useState(false);
32
78
 
33
79
  const onCardAdded = modalData.onCardAdded as ((cardId: string) => void) | undefined;
34
80
 
81
+ const createSetupIntentMutation = useCreateSetupIntent();
35
82
  const createCardMutation = useCreateCard();
36
83
  const updateAccountMutation = useUpdateAccount();
37
84
  const elements = useElements();
@@ -52,6 +99,7 @@ export default function AddCardModal() {
52
99
  setCurrentStep(1);
53
100
  setStripeStatus(INITIAL_STRIPE_STATUS);
54
101
  setStripeErrors({});
102
+ setIsAuthenticating(false);
55
103
  closeModal();
56
104
  }, [form, closeModal]);
57
105
 
@@ -66,65 +114,97 @@ export default function AddCardModal() {
66
114
  );
67
115
 
68
116
  const handleContinue = useCallback(async () => {
69
- const rhfValid = await form.trigger(['name', 'country', 'personType', 'cpf', 'cnpj']);
117
+ const isValid = await form.trigger([
118
+ 'fullName',
119
+ 'cep',
120
+ 'street',
121
+ 'streetNumber',
122
+ 'neighborhood',
123
+ 'city',
124
+ 'state',
125
+ ]);
126
+ if (!isValid) return;
127
+ setCurrentStep(2);
128
+ }, [form]);
129
+
130
+ const handleBack = useCallback(() => {
131
+ setCurrentStep(1);
132
+ }, []);
70
133
 
134
+ async function handleSubmit(data: CardFormData) {
71
135
  const newStripeErrors: Record<string, string | undefined> = {};
72
136
  if (!stripeStatus.cardNumber) newStripeErrors.cardNumber = 'Número do cartão é obrigatório';
73
137
  if (!stripeStatus.cardExpiry) newStripeErrors.cardExpiry = 'Data de validade é obrigatória';
74
138
  if (!stripeStatus.cardCvc) newStripeErrors.cardCvc = 'Código de segurança é obrigatório';
75
139
  setStripeErrors(newStripeErrors);
76
140
 
77
- const stripeValid = stripeStatus.cardNumber && stripeStatus.cardExpiry && stripeStatus.cardCvc;
78
-
79
- if (rhfValid && stripeValid) {
80
- form.clearErrors(['fullName', 'cep', 'street', 'streetNumber', 'neighborhood', 'city', 'state']);
81
- setCurrentStep(2);
82
- }
83
- }, [form, stripeStatus]);
84
-
85
- const handleBack = useCallback(() => {
86
- setCurrentStep(1);
87
- }, []);
88
-
89
- async function handleSubmit(data: CardFormData) {
141
+ const stripeValid =
142
+ stripeStatus.cardNumber && stripeStatus.cardExpiry && stripeStatus.cardCvc;
143
+ if (!stripeValid) return;
90
144
  if (!stripe || !elements) return;
91
145
 
92
146
  const cardElement = elements.getElement(CardNumberElement);
93
147
  if (!cardElement) return;
94
148
 
95
- const { error, paymentMethod } = await stripe.createPaymentMethod({
96
- type: 'card',
97
- card: cardElement,
98
- billing_details: {
99
- name: data.fullName,
100
- address: {
101
- country: data.country,
102
- postal_code: data.cep,
103
- line1: `${data.street}, ${data.streetNumber}`,
104
- line2: data.complement || undefined,
105
- city: data.city,
106
- state: data.state,
149
+ setIsAuthenticating(true);
150
+ try {
151
+ const intentResult = await createSetupIntentMutation.mutateAsync();
152
+ const intent = intentResult?.data;
153
+ if (!intent?.client_secret || !intent?.setup_intent_id) {
154
+ toast.custom(
155
+ (t) => (
156
+ <Toast
157
+ variant="error"
158
+ message="Não foi possível iniciar a autenticação do cartão, tente novamente."
159
+ toastId={t}
160
+ />
161
+ ),
162
+ { duration: 5000 }
163
+ );
164
+ return;
165
+ }
166
+
167
+ const { setupIntent, error } = await stripe.confirmCardSetup(intent.client_secret, {
168
+ payment_method: {
169
+ card: cardElement,
170
+ billing_details: { name: data.name },
107
171
  },
108
- },
109
- });
172
+ });
110
173
 
111
- if (error) {
112
- toast.custom(
113
- (t) => (
114
- <Toast
115
- variant="error"
116
- message="Não foi possível adicionar o cartão na Stripe, tente novamente."
117
- toastId={t}
118
- />
119
- ),
120
- { duration: 5000 }
121
- );
122
- return;
123
- }
174
+ if (error) {
175
+ toast.custom(
176
+ (t) => (
177
+ <Toast
178
+ variant="error"
179
+ message={error.message || 'Falha na autenticação do cartão.'}
180
+ toastId={t}
181
+ />
182
+ ),
183
+ { duration: 5000 }
184
+ );
185
+ return;
186
+ }
187
+
188
+ if (setupIntent?.status !== 'succeeded') {
189
+ toast.custom(
190
+ (t) => (
191
+ <Toast
192
+ variant="error"
193
+ message={`Autenticação não concluída (status: ${setupIntent?.status ?? 'desconhecido'}).`}
194
+ toastId={t}
195
+ />
196
+ ),
197
+ { duration: 5000 }
198
+ );
199
+ return;
200
+ }
124
201
 
125
- try {
126
202
  const [cardResult] = await Promise.all([
127
- createCardMutation.mutateAsync({ payment_method_id: paymentMethod.id }),
203
+ createCardMutation.mutateAsync({
204
+ setup_intent_id: intent.setup_intent_id,
205
+ name: data.name,
206
+ set_default: true,
207
+ }),
128
208
  updateAccountMutation.mutateAsync({
129
209
  financial_document_type: data.personType === 'pf' ? 1 : 2,
130
210
  financial_document: data.personType === 'pf' ? data.cpf : data.cnpj,
@@ -159,6 +239,8 @@ export default function AddCardModal() {
159
239
  ),
160
240
  { duration: 5000 }
161
241
  );
242
+ } finally {
243
+ setIsAuthenticating(false);
162
244
  }
163
245
  }
164
246
 
@@ -169,15 +251,7 @@ export default function AddCardModal() {
169
251
 
170
252
  const watchedValues = form.watch(['name', 'country', 'personType', 'cpf', 'cnpj', 'fullName', 'cep', 'street', 'streetNumber', 'neighborhood', 'city', 'state']);
171
253
  const [name, country, personType, cpf, cnpj, fullName, cep, street, streetNumber, neighborhood, city, state] = watchedValues;
172
- const isStep1Valid =
173
- !!name &&
174
- !!country &&
175
- !!personType &&
176
- (personType === 'pf' ? !!cpf && cpf.length >= 14 : !!cnpj && cnpj.length >= 18) &&
177
- stripeStatus.cardNumber &&
178
- stripeStatus.cardExpiry &&
179
- stripeStatus.cardCvc;
180
- const isStep2Valid =
254
+ const isBillingValid =
181
255
  !!fullName &&
182
256
  !!cep && cep.length >= 9 &&
183
257
  !!street &&
@@ -185,6 +259,14 @@ export default function AddCardModal() {
185
259
  !!neighborhood &&
186
260
  !!city &&
187
261
  !!state;
262
+ const isCardValid =
263
+ !!name &&
264
+ !!country &&
265
+ !!personType &&
266
+ (personType === 'pf' ? !!cpf && cpf.length >= 14 : !!cnpj && cnpj.length >= 18) &&
267
+ stripeStatus.cardNumber &&
268
+ stripeStatus.cardExpiry &&
269
+ stripeStatus.cardCvc;
188
270
 
189
271
  if (isExternalContracting) {
190
272
  return (
@@ -228,7 +310,7 @@ export default function AddCardModal() {
228
310
  <DialogHeader className="p-0">
229
311
  <div className="flex items-center justify-center px-4 py-3 relative border-b border-zinc-200 lg:border-b-0">
230
312
  <DialogTitle className="paragraph-medium-semibold text-zinc-950 text-center">
231
- {currentStep === 1 ? 'Adicionar cartão' : 'Dados de cobrança'}
313
+ Adicionar cartão
232
314
  </DialogTitle>
233
315
  <Button
234
316
  type="button"
@@ -241,28 +323,28 @@ export default function AddCardModal() {
241
323
  </div>
242
324
  </DialogHeader>
243
325
 
244
- {/* Progress bar */}
245
- <div className="h-1 bg-zinc-100 w-full">
246
- <div
247
- className="h-full transition-all duration-300 ease-in-out bg-primary"
248
- style={{ width: currentStep === 1 ? '50%' : '100%' }}
249
- />
250
- </div>
326
+ <CardStepper currentStep={currentStep} />
251
327
 
252
328
  <form
253
329
  onSubmit={form.handleSubmit(handleSubmit)}
254
330
  className="flex flex-col flex-1 lg:flex-none"
255
331
  >
256
332
  <div className={`flex flex-col gap-6 lg:gap-8 p-4 lg:p-5 flex-1 lg:flex-none ${currentStep !== 1 ? 'hidden' : ''}`}>
333
+ <h2 className="font-[family-name:var(--font-outfit)] text-[18px] leading-tight font-semibold text-zinc-950">
334
+ Adicione suas informações de cobrança
335
+ </h2>
336
+ <BillingFormFields form={form} />
337
+ </div>
338
+ <div className={`flex flex-col gap-6 lg:gap-8 p-4 lg:p-5 flex-1 lg:flex-none ${currentStep !== 2 ? 'hidden' : ''}`}>
339
+ <h2 className="font-[family-name:var(--font-outfit)] text-[18px] leading-tight font-semibold text-zinc-950">
340
+ Adicione informações do seu cartão
341
+ </h2>
257
342
  <CardFormFields
258
343
  form={form}
259
344
  onStripeChange={handleStripeChange}
260
345
  stripeErrors={stripeErrors}
261
346
  />
262
347
  </div>
263
- <div className={`flex flex-col gap-6 lg:gap-8 p-4 lg:p-5 flex-1 lg:flex-none ${currentStep !== 2 ? 'hidden' : ''}`}>
264
- <BillingFormFields form={form} />
265
- </div>
266
348
 
267
349
  <div className="flex justify-between items-center p-4 lg:p-5 border-t border-zinc-200 gap-2 mt-auto lg:mt-0">
268
350
  {currentStep === 1 ? (
@@ -274,7 +356,7 @@ export default function AddCardModal() {
274
356
  type="button"
275
357
  className="h-10!"
276
358
  onClick={handleContinue}
277
- disabled={!isStep1Valid}
359
+ disabled={!isBillingValid}
278
360
  >
279
361
  Continuar
280
362
  </Button>
@@ -284,9 +366,18 @@ export default function AddCardModal() {
284
366
  <Button variant="secondary" type="button" onClick={handleBack} className="h-10!">
285
367
  Voltar
286
368
  </Button>
287
- <Button type="submit" className="h-10!" disabled={isSubmitting || !isStep2Valid}>
288
- {isSubmitting && <IconLoader2 className="size-4 animate-spin" />}
289
- {isSubmitting ? 'Adicionando cartão...' : 'Adicionar cartão'}
369
+ <Button
370
+ type="submit"
371
+ className="h-10!"
372
+ disabled={isSubmitting || isAuthenticating || !isCardValid}
373
+ loading={isAuthenticating || isSubmitting}
374
+ >
375
+ {isAuthenticating && <IconLoader2 className="size-4 animate-spin" />}
376
+ {isAuthenticating
377
+ ? 'Autenticando...'
378
+ : isSubmitting
379
+ ? 'Adicionando cartão...'
380
+ : 'Adicionar cartão'}
290
381
  </Button>
291
382
  </>
292
383
  )}
package/src/index.ts CHANGED
@@ -77,6 +77,7 @@ export { useUpdateSubscriptionPayment } from "./modules/subscriptions/hooks/upda
77
77
  export { useCards, CARDS_QUERY_KEY } from "./modules/cards/hooks/cards.hook";
78
78
  export { useCardById } from "./modules/cards/hooks/card-by-id.hook";
79
79
  export { useCreateCard } from "./modules/cards/hooks/create-card.hook";
80
+ export { useCreateSetupIntent } from "./modules/cards/hooks/create-setup-intent.hook";
80
81
  export { useSetDefaultCard } from "./modules/cards/hooks/set-default-card.hook";
81
82
  export { useDeleteCard } from "./modules/cards/hooks/delete-card.hook";
82
83
  export { useDeleteConfirmation } from "./modules/cards/hooks/delete-confirmation.hook";
@@ -134,11 +135,13 @@ export type {
134
135
  Card as PaymentCard,
135
136
  CreateCardRequest,
136
137
  FindCardsParams,
138
+ SetupIntent,
137
139
  } from "./modules/cards/types";
138
140
  export {
139
141
  CardSchema as PaymentCardSchema,
140
142
  CreateCardRequestSchema,
141
143
  FindCardsParamsSchema,
144
+ SetupIntentSchema,
142
145
  } from "./modules/cards/types";
143
146
  export type {
144
147
  Charge,
@@ -0,0 +1,8 @@
1
+ 'use server';
2
+
3
+ import { safeMutationAction } from '../../../utils/safeMutationAction';
4
+ import { cardsService } from '../services/cards.service';
5
+
6
+ export async function createSetupIntentAction() {
7
+ return safeMutationAction(() => cardsService.createSetupIntent());
8
+ }
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+
3
+ import { useMutation } from '@tanstack/react-query';
4
+ import { withAction } from '../../../utils/withAction';
5
+ import { createSetupIntentAction } from '../actions/create-setup-intent.action';
6
+
7
+ export function useCreateSetupIntent() {
8
+ return useMutation({
9
+ mutationFn: () => withAction(createSetupIntentAction)(),
10
+ });
11
+ }
@@ -5,9 +5,31 @@ import { ApiError, ApiActionResult, ApiPaginatedActionResult, PaginatedSuccessRe
5
5
  import { buildQueryParams } from '../../../infra/utils/params';
6
6
  import { assertManagementPermission } from '../../auth/utils/assert-management-permission';
7
7
  import { getUserContext } from '../../auth/utils/get-user-context';
8
- import { Card, CardSchema, CreateCardRequest } from '../types';
8
+ import { Card, CardSchema, CreateCardRequest, SetupIntent, SetupIntentSchema } from '../types';
9
9
 
10
10
  class CardsService {
11
+ async createSetupIntent(): Promise<SuccessResult<SetupIntent>> {
12
+ await assertManagementPermission('manage_cards');
13
+ const { id_account } = await getUserContext();
14
+
15
+ const response = await api.apps.post<ApiPaginatedActionResult<SetupIntent>>(
16
+ `/accounts/${id_account}/cards/action/setup-intent`,
17
+ {}
18
+ );
19
+
20
+ if (response.status === 0) {
21
+ throw new ApiError(
22
+ response.message || 'Erro ao criar SetupIntent',
23
+ 'CREATE_SETUP_INTENT_FAILED',
24
+ 400
25
+ );
26
+ }
27
+
28
+ const data = SetupIntentSchema.parse(response.data[0]);
29
+
30
+ return { success: true, data };
31
+ }
32
+
11
33
  async listCards(): Promise<PaginatedSuccessResult<Card>> {
12
34
  await assertManagementPermission('view_cards');
13
35
  const { id_account } = await getUserContext();
@@ -31,12 +31,20 @@ export const CardSchema = z.object({
31
31
  export type Card = z.infer<typeof CardSchema>;
32
32
 
33
33
  export const CreateCardRequestSchema = z.object({
34
- payment_method_id: z.string().min(1, 'payment_method_id é obrigatório'),
34
+ setup_intent_id: z.string().min(1, 'setup_intent_id é obrigatório'),
35
+ name: z.string().min(1, 'name é obrigatório'),
35
36
  set_default: z.boolean().optional(),
36
37
  });
37
38
 
38
39
  export type CreateCardRequest = z.infer<typeof CreateCardRequestSchema>;
39
40
 
41
+ export const SetupIntentSchema = z.object({
42
+ client_secret: z.string(),
43
+ setup_intent_id: z.string(),
44
+ });
45
+
46
+ export type SetupIntent = z.infer<typeof SetupIntentSchema>;
47
+
40
48
  export const FindCardsParamsSchema = PaginationParamsSchema.extend(SearchParamsSchema.shape).extend(
41
49
  SortParamsSchema.shape
42
50
  );
package/src/server.ts CHANGED
@@ -31,6 +31,7 @@ export { updateSubscriptionPlanAction } from './modules/subscriptions/actions/up
31
31
  export { updateSubscriptionPaymentAction } from './modules/subscriptions/actions/update-subscription-payment.action';
32
32
  export { listCardsAction } from './modules/cards/actions/list-cards.action';
33
33
  export { createCardAction } from './modules/cards/actions/create-card.action';
34
+ export { createSetupIntentAction } from './modules/cards/actions/create-setup-intent.action';
34
35
  export { listChargesAction } from './modules/charges/actions/list-charges.action';
35
36
  export { findChargeByIdAction } from './modules/charges/actions/find-charge-by-id.action';
36
37
  export { chargeActionAction } from './modules/charges/actions/charge-action.action';