@danhachuel/thunderbolt 0.5.4 → 0.5.6

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.
package/app/main.py CHANGED
@@ -7105,14 +7105,17 @@ def _render_media_provider_card(settings: dict[str, Any], cards: list[dict[str,
7105
7105
  if card.get("provider") == "canva":
7106
7106
  callback_code = str(st.query_params.get("code") or "").strip()
7107
7107
  callback_state = str(st.query_params.get("state") or "").strip()
7108
- pending_state = str(st.session_state.get(f"canva_state_{card_id}") or "")
7108
+ oauth_pending = card.get("oauth_pending") if isinstance(card.get("oauth_pending"), dict) else {}
7109
+ pending_state = str(st.session_state.get(f"canva_state_{card_id}") or oauth_pending.get("state") or "")
7110
+ pending_verifier = str(st.session_state.get(f"canva_verifier_{card_id}") or oauth_pending.get("code_verifier") or "")
7109
7111
  if callback_code:
7110
- if callback_state != pending_state:
7112
+ if not pending_state or callback_state != pending_state:
7111
7113
  st.error("Canva OAuth rejeitado: state inválido. Inicie a autorização novamente.")
7112
7114
  else:
7113
7115
  try:
7114
- token = exchange_code(str(card.get("client_id") or ""), str(card.get("client_secret") or ""), callback_code, str(card.get("redirect_uri") or ""), str(st.session_state.get(f"canva_verifier_{card_id}") or ""))
7116
+ token = exchange_code(str(card.get("client_id") or ""), str(card.get("client_secret") or ""), callback_code, str(card.get("redirect_uri") or ""), pending_verifier)
7115
7117
  card["oauth_token"] = token
7118
+ card.pop("oauth_pending", None)
7116
7119
  cards[index] = card
7117
7120
  _persist_media_cards(settings, cards, str(settings.get(MEDIA_IMAGE_ACTIVE_CARD_KEY) or ""), str(settings.get(MEDIA_VIDEO_ACTIVE_CARD_KEY) or ""))
7118
7121
  st.session_state.pop(f"canva_state_{card_id}", None)
@@ -7135,6 +7138,7 @@ def _render_media_provider_card(settings: dict[str, Any], cards: list[dict[str,
7135
7138
  with card_form:
7136
7139
  key_col, model_col = st.columns(2)
7137
7140
  refresh_clicked = False
7141
+ authorize_clicked = False
7138
7142
  with key_col:
7139
7143
  api_key = str(card.get("api_key") or "")
7140
7144
  if definition.requires_api_key:
@@ -7200,6 +7204,7 @@ def _render_media_provider_card(settings: dict[str, Any], cards: list[dict[str,
7200
7204
  st.session_state[f"canva_verifier_{card_id}"] = verifier
7201
7205
  st.session_state[f"canva_state_{card_id}"] = state
7202
7206
  st.session_state[f"canva_authorization_url_{card_id}"] = authorization_url(client_id, redirect_uri, state=state, code_challenge=challenge)
7207
+ extra_values["oauth_pending"] = {"state": state, "code_verifier": verifier}
7203
7208
  authorization_link = str(st.session_state.get(f"canva_authorization_url_{card_id}") or "")
7204
7209
  if authorization_link:
7205
7210
  st.markdown(f"[Abrir autorização Canva]({authorization_link})")
@@ -7231,7 +7236,12 @@ def _render_media_provider_card(settings: dict[str, Any], cards: list[dict[str,
7231
7236
  edited = dict(card)
7232
7237
  edited.update({"api_key": str(api_key or "").strip(), "model": str(model or "").strip(), "base_url": str(base_url or "").strip(), "enabled": bool(enabled), "supports_image": bool(supports_image), "supports_video": bool(supports_video), "priority": int(priority), **extra_values})
7233
7238
  cards[index] = edited
7234
- if refresh_clicked:
7239
+ if authorize_clicked:
7240
+ # Guardar as credenciais antes de o browser sair para a Canva. No
7241
+ # callback, o código OAuth é trocado usando este card persistido.
7242
+ _persist_media_cards(settings, cards, str(settings.get(MEDIA_IMAGE_ACTIVE_CARD_KEY) or ""), str(settings.get(MEDIA_VIDEO_ACTIVE_CARD_KEY) or ""))
7243
+ st.success("Credenciais Canva guardadas. Abra o link para autorizar.")
7244
+ elif refresh_clicked:
7235
7245
  try:
7236
7246
  discovered = _fetch_media_models(edited)
7237
7247
  st.session_state[f"media_model_catalog_{card_id}"] = discovered
@@ -232,6 +232,12 @@ def normalize_media_card(card: Any, index: int = 0) -> dict[str, Any]:
232
232
  result["thumbnail_width"] = raw_width if raw_width in {"1280", "1792"} else "1280"
233
233
  result["thumbnail_height"] = raw_height if raw_height in {"720", "1024"} else ("1024" if result["thumbnail_width"] == "1792" else "720")
234
234
  result["oauth_token"] = dict(source.get("oauth_token") or {}) if isinstance(source.get("oauth_token"), Mapping) else {}
235
+ pending = source.get("oauth_pending")
236
+ if isinstance(pending, Mapping) and pending.get("state") and pending.get("code_verifier"):
237
+ result["oauth_pending"] = {
238
+ "state": str(pending.get("state")),
239
+ "code_verifier": str(pending.get("code_verifier")),
240
+ }
235
241
  if provider == "nano_banana":
236
242
  result["aspect_ratio"] = str(source.get("aspect_ratio") or INTERNAL_IMAGE_ASPECT_RATIO).strip()
237
243
  result["image_size"] = str(source.get("image_size") or INTERNAL_IMAGE_SIZE).strip()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
4
4
  "description": "Thunderbolt — interface local para operação de canais faceless e motor MoneyPrinterTurbo",
5
5
  "license": "MIT",
6
6
  "main": "scripts/cli.mjs",