@oktis-works/admin 0.4.6 → 0.4.7
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/dist/client/_astro/{AtGlanceWidget.Cq8OOJPG.js → AtGlanceWidget.Csh6O1qC.js} +1 -1
- package/dist/client/_astro/{Footer.BU0nQfsj.js → Footer.B45KEgQC.js} +1 -1
- package/dist/client/_astro/{QuickDraftWidget.BklxPtXw.js → QuickDraftWidget.DsmDxcjM.js} +1 -1
- package/dist/client/_astro/{version.BBlB8V1z.js → version.DLKCNYBX.js} +1 -1
- package/dist/server/chunks/{ContentEditor_BIKFMKGc.mjs → ContentEditor_DYVCMTXI.mjs} +2 -1
- package/dist/server/chunks/{DashboardLayout_DvpIbi-L.mjs → DashboardLayout_BSI1WOi6.mjs} +3 -519
- package/dist/server/chunks/{MediaLibrary_ayG_it4q.mjs → MediaLibrary_DZjpMXgK.mjs} +2 -1
- package/dist/server/chunks/{_slug__DGHktOQk.mjs → _slug__CT9lqK13.mjs} +1 -1
- package/dist/server/chunks/{edit_zoYziljx.mjs → edit_BUOEvmvl.mjs} +2 -2
- package/dist/server/chunks/{general_CBOFvXp5.mjs → general_pGxOJQzX.mjs} +2 -1
- package/dist/server/chunks/i18n_DnHqy5K-.mjs +527 -0
- package/dist/server/chunks/{index_D6HRv5gR.mjs → index_BSxjpQXZ.mjs} +2 -1
- package/dist/server/chunks/{index_BGAjNTWX.mjs → index_CHL9vq3T.mjs} +2 -1
- package/dist/server/chunks/{index_DXH9TpQZ.mjs → index_DgL2eLJu.mjs} +2 -1
- package/dist/server/chunks/{index_B0Kv_zY5.mjs → index_IW6nshbT.mjs} +2 -2
- package/dist/server/chunks/{index_B9j_Mdp1.mjs → index_YwwAn3Lb.mjs} +1 -1
- package/dist/server/chunks/{new_BGsvWic-.mjs → new_BfiBbnro.mjs} +2 -2
- package/dist/server/chunks/{new_1yZE_PrZ.mjs → new_D1aZllsr.mjs} +2 -1
- package/dist/server/chunks/{node_BafXIcNi.mjs → node_kWZa8y--.mjs} +3 -3
- package/dist/server/chunks/{post-types_9hCXqS5l.mjs → post-types_76cyJz6s.mjs} +2 -1
- package/dist/server/chunks/remote_ByPF9VwL.mjs +49 -0
- package/dist/server/chunks/sequence_CQpaaIXP.mjs +1420 -0
- package/dist/server/chunks/{sharp_C91d8fsK.mjs → sharp_37gnUicY.mjs} +1 -1
- package/dist/server/chunks/{taxonomies_CzecicEb.mjs → taxonomies_DFQu9XsS.mjs} +2 -1
- package/dist/server/chunks/{upload_BaboNcp0.mjs → upload_39j7H3EB.mjs} +2 -2
- package/dist/server/entry.mjs +23 -1151
- package/dist/server/virtual_astro_middleware.mjs +56 -2
- package/package.json +1 -1
- package/dist/server/chunks/console_B_CnzVJ2.mjs +0 -170
- package/dist/server/chunks/remote_DUw5DMmE.mjs +0 -169
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{C as e,E as t,S as n,_ as r,b as i,f as a,o,p as s,r as c,t as l,u}from"./web.D1H9RxZL.js";import{t as d}from"./i18n.DJXYgZ8Z.js";import{t as f}from"./api.DTNuyqvx.js";import{t as p}from"./version.
|
|
1
|
+
import{C as e,E as t,S as n,_ as r,b as i,f as a,o,p as s,r as c,t as l,u}from"./web.D1H9RxZL.js";import{t as d}from"./i18n.DJXYgZ8Z.js";import{t as f}from"./api.DTNuyqvx.js";import{t as p}from"./version.DLKCNYBX.js";var m=s(`<div><div class=dashboard-widget-header><h3 class=dashboard-widget-title></h3></div><div class=dashboard-widget-content></div><style>
|
|
2
2
|
.dashboard-widget {
|
|
3
3
|
background: var(--color-surface);
|
|
4
4
|
border: 1px solid var(--color-border);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{S as e,i as t,o as n,p as r,r as i,u as a}from"./web.D1H9RxZL.js";import{t as o}from"./i18n.DJXYgZ8Z.js";import{t as s}from"./version.
|
|
1
|
+
import{S as e,i as t,o as n,p as r,r as i,u as a}from"./web.D1H9RxZL.js";import{t as o}from"./i18n.DJXYgZ8Z.js";import{t as s}from"./version.DLKCNYBX.js";var c=r(`<footer class=admin-footer role=contentinfo><div class=footer-content><div class=footer-left><p class=footer-version><span class=product-name>OkCMS</span><span class=version-badge>v<!$><!/></span></p><p class=footer-copyright></p></div><nav class=footer-links><a href=https://oktisworks.com target=_blank rel="noopener noreferrer"></a><a href=https://github.com/oktis-works/cms target=_blank rel="noopener noreferrer"></a><a href=https://docs.oktisworks.com target=_blank rel="noopener noreferrer"></a><a href=https://oktisworks.com/community target=_blank rel="noopener noreferrer"></a></nav><div class=footer-right><p class=footer-powered></p></div></div><style>
|
|
2
2
|
.admin-footer {
|
|
3
3
|
position: fixed;
|
|
4
4
|
bottom: 0;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{C as e,E as t,S as n,b as r,d as i,g as a,i as o,l as s,n as c,o as l,p as u,r as d,s as f,u as p}from"./web.D1H9RxZL.js";import{t as m}from"./i18n.DJXYgZ8Z.js";import{t as h}from"./api.DTNuyqvx.js";import{DashboardWidget as g}from"./AtGlanceWidget.
|
|
1
|
+
import{C as e,E as t,S as n,b as r,d as i,g as a,i as o,l as s,n as c,o as l,p as u,r as d,s as f,u as p}from"./web.D1H9RxZL.js";import{t as m}from"./i18n.DJXYgZ8Z.js";import{t as h}from"./api.DTNuyqvx.js";import{DashboardWidget as g}from"./AtGlanceWidget.Csh6O1qC.js";var _=u(`<div class=quick-draft-wrapper><div class=quick-draft-content-wrapper>`),v=u(`<style>
|
|
2
2
|
.quick-draft-form { display: flex; flex-direction: column; gap: 1rem; }
|
|
3
3
|
.form-group textarea { min-height: 100px; resize: vertical; font-family: inherit; }
|
|
4
4
|
.drafts-list h4 { margin-bottom: 1rem; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e={name:`okcms`,version:`0.4.
|
|
1
|
+
var e={name:`okcms`,version:`0.4.7`,private:!0,description:`Hybrid, modular, API-first CMS`,engines:{node:`>=20.0.0`,bun:`>=1.3.0`},workspaces:[`apps/*`,`packages/*`,`plugins/*`,`themes/*`],overrides:{ioredis:`5.3.0`},scripts:{dev:`bun run --filter '@oktis-works/*' dev`,build:`bun run --filter '@oktis-works/*' build`,test:`vitest`,"test:run":`vitest run`,lint:`eslint .`,typecheck:`tsc --noEmit`,clean:`rm -rf node_modules apps/*/node_modules packages/*/node_modules`,changeset:`changeset`,"version-packages":`changeset version`,"publish:all":`node scripts/prepare-publish.mjs && for pkg in packages/* apps/api apps/admin apps/web apps/worker; do [ -f "$pkg/package.json" ] || continue; echo "→ publishing $pkg"; (cd "$pkg" && npm publish --access public) || exit 1; done`},devDependencies:{"@changesets/changelog-github":`^1.0.1`,"@changesets/cli":`^3.0.3`,"@types/node":`22.0.0`,"@types/semver":`7.7.0`,"@typescript-eslint/eslint-plugin":`^8.71.0`,"@typescript-eslint/parser":`8.0.0`,autoprefixer:`^10.6.1`,eslint:`9.0.0`,playwright:`1.59.1`,"playwright-core":`1.59.1`,postcss:`^8.5.28`,sass:`^1.105.1`,tailwindcss:`^4.3.3`,typescript:`5.7.3`,"typescript-eslint":`8.31.0`,vitest:`3.0.0`},packageManager:`bun@1.3.14`}.version;export{e as t};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as useTranslation, r as apiClient } from "./i18n_DnHqy5K-.mjs";
|
|
2
|
+
import { a as For2, d as createMemo$1, f as createSignal$1, l as Show2 } from "./DashboardLayout_BSI1WOi6.mjs";
|
|
2
3
|
import { createComponent, escape, memo, ssr, ssrAttribute, ssrHydrationKey } from "solid-js/web";
|
|
3
4
|
import { For, Show, createMemo, createSignal, onMount } from "solid-js";
|
|
4
5
|
//#region ../../packages/validation/dist/client-validate.js
|
|
@@ -2,6 +2,7 @@ import "./rolldown-runtime_BMI-E3GI.mjs";
|
|
|
2
2
|
import { S as createAstro, d as maybeRenderHead, i as renderComponent, p as addAttribute, s as renderSlot, u as renderTemplate } from "./server_B5N27szj.mjs";
|
|
3
3
|
import { t as createComponent$1 } from "./compiler_O7J1rlsi.mjs";
|
|
4
4
|
import { n as renderScript, t as $$BaseLayout } from "./BaseLayout_GUKuUGNt.mjs";
|
|
5
|
+
import { a as LOCALE_LABELS, i as LOCALE_FLAGS, n as useTranslation, o as SUPPORTED_LOCALES, r as apiClient } from "./i18n_DnHqy5K-.mjs";
|
|
5
6
|
import { t as require_semver } from "./semver_WbqCUY_o.mjs";
|
|
6
7
|
import { createComponent, escape, ssr, ssrAttribute, ssrHydrationKey, ssrStyle } from "solid-js/web";
|
|
7
8
|
import { For, For as For2, Show, Show as Show2, createMemo as createMemo$1, createSignal, createSignal as createSignal$1, onCleanup, onMount, onMount as onMount$1 } from "solid-js";
|
|
@@ -394,523 +395,6 @@ function PluginExtensionsSlot() {
|
|
|
394
395
|
});
|
|
395
396
|
}
|
|
396
397
|
//#endregion
|
|
397
|
-
//#region src/i18n/config.ts
|
|
398
|
-
var SUPPORTED_LOCALES = [
|
|
399
|
-
"pt-BR",
|
|
400
|
-
"en",
|
|
401
|
-
"es-ES",
|
|
402
|
-
"ru",
|
|
403
|
-
"uk",
|
|
404
|
-
"tr",
|
|
405
|
-
"he",
|
|
406
|
-
"it",
|
|
407
|
-
"pl",
|
|
408
|
-
"zh-CN",
|
|
409
|
-
"ja",
|
|
410
|
-
"ar",
|
|
411
|
-
"sw",
|
|
412
|
-
"yo",
|
|
413
|
-
"zu",
|
|
414
|
-
"am",
|
|
415
|
-
"ha",
|
|
416
|
-
"ig"
|
|
417
|
-
];
|
|
418
|
-
var LOCALE_LABELS = {
|
|
419
|
-
"pt-BR": "Português (Brasil)",
|
|
420
|
-
"en": "English",
|
|
421
|
-
"es-ES": "Español",
|
|
422
|
-
"ru": "Русский",
|
|
423
|
-
"uk": "Українська",
|
|
424
|
-
"tr": "Türkçe",
|
|
425
|
-
"he": "עברית",
|
|
426
|
-
"it": "Italiano",
|
|
427
|
-
"pl": "Polski",
|
|
428
|
-
"zh-CN": "中文 (简体)",
|
|
429
|
-
"ja": "日本語",
|
|
430
|
-
"ar": "العربية",
|
|
431
|
-
"sw": "Kiswahili",
|
|
432
|
-
"yo": "Yorùbá",
|
|
433
|
-
"zu": "isiZulu",
|
|
434
|
-
"am": "አማርኛ",
|
|
435
|
-
"ha": "Hausa",
|
|
436
|
-
"ig": "Igbo"
|
|
437
|
-
};
|
|
438
|
-
var LOCALE_FLAGS = {
|
|
439
|
-
"pt-BR": "🇧🇷",
|
|
440
|
-
"en": "🇺🇸",
|
|
441
|
-
"es-ES": "🇪🇸",
|
|
442
|
-
"ru": "🇷🇺",
|
|
443
|
-
"uk": "🇺🇦",
|
|
444
|
-
"tr": "🇹🇷",
|
|
445
|
-
"he": "🇮🇱",
|
|
446
|
-
"it": "🇮🇹",
|
|
447
|
-
"pl": "🇵🇱",
|
|
448
|
-
"zh-CN": "🇨🇳",
|
|
449
|
-
"ja": "🇯🇵",
|
|
450
|
-
"ar": "🇸🇦",
|
|
451
|
-
"sw": "🇹🇿",
|
|
452
|
-
"yo": "🇳🇬",
|
|
453
|
-
"zu": "🇿🇦",
|
|
454
|
-
"am": "🇪🇹",
|
|
455
|
-
"ha": "🇳🇬",
|
|
456
|
-
"ig": "🇳🇬"
|
|
457
|
-
};
|
|
458
|
-
//#endregion
|
|
459
|
-
//#region \0rolldown_dynamic_import_helper.js
|
|
460
|
-
var _rolldown_dynamic_import_helper_default = (glob, path, segments) => {
|
|
461
|
-
const query = path.lastIndexOf("?");
|
|
462
|
-
const v = glob[query === -1 || query < path.lastIndexOf("/") ? path : path.slice(0, query)];
|
|
463
|
-
if (v) return typeof v === "function" ? v() : Promise.resolve(v);
|
|
464
|
-
return new Promise((_, reject) => {
|
|
465
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(reject.bind(null, /* @__PURE__ */ new Error("Unknown variable dynamic import: " + path + (path.split("/").length !== segments ? ". Note that variables only represent file names one level deep." : ""))));
|
|
466
|
-
});
|
|
467
|
-
};
|
|
468
|
-
//#endregion
|
|
469
|
-
//#region src/i18n/loaders.ts
|
|
470
|
-
var localeCache = /* @__PURE__ */ new Map();
|
|
471
|
-
/** Carrega arquivo JSON de locale */
|
|
472
|
-
async function loadLocale(locale) {
|
|
473
|
-
if (localeCache.has(locale)) return localeCache.get(locale);
|
|
474
|
-
try {
|
|
475
|
-
const module = await _rolldown_dynamic_import_helper_default(/* #__PURE__ */ Object.assign({
|
|
476
|
-
"./locales/ar.json": () => import("./ar_DBjdWIJ0.mjs"),
|
|
477
|
-
"./locales/en.json": () => import("./en_C750mYKk.mjs"),
|
|
478
|
-
"./locales/es-ES.json": () => import("./es-ES_TJ4oK1yi.mjs"),
|
|
479
|
-
"./locales/he.json": () => import("./he_TWsuTphz.mjs"),
|
|
480
|
-
"./locales/it.json": () => import("./it_CEVFVWh1.mjs"),
|
|
481
|
-
"./locales/ja.json": () => import("./ja_CqDirMqf.mjs"),
|
|
482
|
-
"./locales/pl.json": () => import("./pl_ChIKxfZG.mjs"),
|
|
483
|
-
"./locales/pt-BR.json": () => import("./pt-BR_4d4jZWL0.mjs"),
|
|
484
|
-
"./locales/ru.json": () => import("./ru_CIc6O5Q7.mjs"),
|
|
485
|
-
"./locales/sw.json": () => import("./sw_Bs3iYVDM.mjs"),
|
|
486
|
-
"./locales/tr.json": () => import("./tr_C7JbXuoQ.mjs"),
|
|
487
|
-
"./locales/uk.json": () => import("./uk_Dibs8Wkc.mjs"),
|
|
488
|
-
"./locales/yo.json": () => import("./yo_B6MPvz_U.mjs"),
|
|
489
|
-
"./locales/zh-CN.json": () => import("./zh-CN_G1Dc2b28.mjs")
|
|
490
|
-
}), `./locales/${locale}.json`, 3);
|
|
491
|
-
const translations = module.default ?? module;
|
|
492
|
-
localeCache.set(locale, translations);
|
|
493
|
-
return translations;
|
|
494
|
-
} catch {
|
|
495
|
-
if (locale !== "en") return loadLocale("en");
|
|
496
|
-
return {};
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
//#endregion
|
|
500
|
-
//#region src/lib/api.ts
|
|
501
|
-
var API_BASE = "http://localhost:3000";
|
|
502
|
-
var ApiClient = class {
|
|
503
|
-
baseUrl;
|
|
504
|
-
csrfToken = null;
|
|
505
|
-
isRefreshing = false;
|
|
506
|
-
constructor(baseUrl = API_BASE) {
|
|
507
|
-
this.baseUrl = baseUrl;
|
|
508
|
-
}
|
|
509
|
-
/** Inicializa lendo CSRF do cookie (chamado no boot da app) */
|
|
510
|
-
async init() {
|
|
511
|
-
try {
|
|
512
|
-
await fetch(`${this.baseUrl}/api/v1/auth/me`, { credentials: "include" });
|
|
513
|
-
} catch {}
|
|
514
|
-
}
|
|
515
|
-
/** Sessão válida — verifica via /me (usa cookies HttpOnly automaticamente) */
|
|
516
|
-
async isLoggedIn() {
|
|
517
|
-
try {
|
|
518
|
-
return (await fetch(`${this.baseUrl}/api/v1/auth/me`, { credentials: "include" })).ok;
|
|
519
|
-
} catch {
|
|
520
|
-
return false;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
/** Obtém tenantId do backend via /me */
|
|
524
|
-
async getTenantId() {
|
|
525
|
-
try {
|
|
526
|
-
const res = await fetch(`${this.baseUrl}/api/v1/auth/me`, { credentials: "include" });
|
|
527
|
-
if (!res.ok) return null;
|
|
528
|
-
return (await res.json()).tenantId ?? null;
|
|
529
|
-
} catch {
|
|
530
|
-
return null;
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
/** Obtém locale do usuário logado via /me/locale */
|
|
534
|
-
async getUserLocale() {
|
|
535
|
-
try {
|
|
536
|
-
const res = await fetch(`${this.baseUrl}/api/v1/users/me/locale`, { credentials: "include" });
|
|
537
|
-
if (!res.ok) return "pt-BR";
|
|
538
|
-
return (await res.json()).locale ?? "pt-BR";
|
|
539
|
-
} catch {
|
|
540
|
-
return "pt-BR";
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
/** Salva locale do usuário via /me/locale */
|
|
544
|
-
async setUserLocale(locale) {
|
|
545
|
-
await this.request("PUT", "/api/v1/users/me/locale", { locale });
|
|
546
|
-
}
|
|
547
|
-
/** Sessão atual (/auth/me) — usuário + tenant + papéis (alimenta o admin bar) */
|
|
548
|
-
async getMe() {
|
|
549
|
-
return this.request("GET", "/api/v1/auth/me");
|
|
550
|
-
}
|
|
551
|
-
/** Auditoria recente — notificações reais do sino no admin bar */
|
|
552
|
-
async getAuditLogs(limit = 8) {
|
|
553
|
-
return this.request("GET", `/api/v1/audit-logs?limit=${limit}`);
|
|
554
|
-
}
|
|
555
|
-
/** Login — o backend seta cookies HttpOnly e CSRF; retorna user + tenantId */
|
|
556
|
-
async login(input) {
|
|
557
|
-
return await this.request("POST", "/api/v1/auth/login", input);
|
|
558
|
-
}
|
|
559
|
-
/** Logout — limpa cookies no backend */
|
|
560
|
-
async logout() {
|
|
561
|
-
await this.request("POST", "/api/v1/auth/logout", {});
|
|
562
|
-
this.csrfToken = null;
|
|
563
|
-
}
|
|
564
|
-
/** Refresh de access token via cookie refresh_token */
|
|
565
|
-
async refreshTokens() {
|
|
566
|
-
if (this.isRefreshing) return;
|
|
567
|
-
this.isRefreshing = true;
|
|
568
|
-
try {
|
|
569
|
-
await this.request("POST", "/api/v1/auth/refresh", {});
|
|
570
|
-
} finally {
|
|
571
|
-
this.isRefreshing = false;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
/** Requisição genérica com:
|
|
575
|
-
* - credentials: 'include' (envia cookies HttpOnly)
|
|
576
|
-
* - auto-refresh em 401
|
|
577
|
-
* - CSRF header para mutações
|
|
578
|
-
*/
|
|
579
|
-
async request(method, path, body, headers) {
|
|
580
|
-
const url = `${this.baseUrl}${path}`;
|
|
581
|
-
const requestHeaders = {
|
|
582
|
-
"Content-Type": "application/json",
|
|
583
|
-
...headers
|
|
584
|
-
};
|
|
585
|
-
if (![
|
|
586
|
-
"GET",
|
|
587
|
-
"HEAD",
|
|
588
|
-
"OPTIONS"
|
|
589
|
-
].includes(method.toUpperCase())) {
|
|
590
|
-
const csrf = this.getCsrfToken();
|
|
591
|
-
if (csrf) requestHeaders["x-csrf-token"] = csrf;
|
|
592
|
-
}
|
|
593
|
-
let response = await fetch(url, {
|
|
594
|
-
method,
|
|
595
|
-
headers: requestHeaders,
|
|
596
|
-
credentials: "include",
|
|
597
|
-
body: body ? JSON.stringify(body) : void 0
|
|
598
|
-
});
|
|
599
|
-
if (response.status === 401 && !path.includes("/auth/refresh") && !path.includes("/auth/logout")) {
|
|
600
|
-
await this.refreshTokens();
|
|
601
|
-
response = await fetch(url, {
|
|
602
|
-
method,
|
|
603
|
-
headers: requestHeaders,
|
|
604
|
-
credentials: "include",
|
|
605
|
-
body: body ? JSON.stringify(body) : void 0
|
|
606
|
-
});
|
|
607
|
-
}
|
|
608
|
-
if (!response.ok) {
|
|
609
|
-
const error = await response.json().catch(() => ({ error: "Request failed" }));
|
|
610
|
-
throw new Error(error.error ?? `Request failed: ${response.status}`);
|
|
611
|
-
}
|
|
612
|
-
const setCookie = response.headers.get("set-cookie");
|
|
613
|
-
if (setCookie) {
|
|
614
|
-
const csrfMatch = setCookie.match(/csrf_token=([^;]+)/);
|
|
615
|
-
if (csrfMatch?.[1]) this.csrfToken = csrfMatch[1];
|
|
616
|
-
}
|
|
617
|
-
return response.json();
|
|
618
|
-
}
|
|
619
|
-
/** Lê CSRF token do cookie (document.cookie) */
|
|
620
|
-
getCsrfToken() {
|
|
621
|
-
if (this.csrfToken) return this.csrfToken;
|
|
622
|
-
if (typeof document !== "undefined") {
|
|
623
|
-
const match = document.cookie.match(/(?:^|;\s*)csrf_token=([^;]+)/);
|
|
624
|
-
if (match?.[1]) return match[1];
|
|
625
|
-
}
|
|
626
|
-
return null;
|
|
627
|
-
}
|
|
628
|
-
async getContent(options) {
|
|
629
|
-
const params = new URLSearchParams();
|
|
630
|
-
if (options?.page) params.set("page", String(options.page));
|
|
631
|
-
if (options?.limit) params.set("limit", String(options.limit));
|
|
632
|
-
if (options?.type) params.set("type", options.type);
|
|
633
|
-
if (options?.status) params.set("status", options.status);
|
|
634
|
-
if (options?.search) params.set("search", options.search);
|
|
635
|
-
return this.request("GET", `/api/v1/content?${params.toString()}`);
|
|
636
|
-
}
|
|
637
|
-
async getContentById(id) {
|
|
638
|
-
return this.request("GET", `/api/v1/content/${id}`);
|
|
639
|
-
}
|
|
640
|
-
async createContent(data) {
|
|
641
|
-
return this.request("POST", `/api/v1/content`, data);
|
|
642
|
-
}
|
|
643
|
-
async updateContent(id, data) {
|
|
644
|
-
return this.request("PUT", `/api/v1/content/${id}`, data);
|
|
645
|
-
}
|
|
646
|
-
async deleteContent(id) {
|
|
647
|
-
await this.request("DELETE", `/api/v1/content/${id}`);
|
|
648
|
-
}
|
|
649
|
-
/** A2: publica via rota real do publisher (eventBus + cache + revisions). */
|
|
650
|
-
async publishContent(id) {
|
|
651
|
-
return this.request("POST", `/api/v1/content/${id}/publish`);
|
|
652
|
-
}
|
|
653
|
-
/** A2: despublica via rota real do publisher. */
|
|
654
|
-
async unpublishContent(id) {
|
|
655
|
-
return this.request("POST", `/api/v1/content/${id}/unpublish`);
|
|
656
|
-
}
|
|
657
|
-
/** Atalho usado pela ContentList: publish/unpublish conforme status atual. */
|
|
658
|
-
async publishToggle(id, isPublished) {
|
|
659
|
-
return isPublished ? this.unpublishContent(id) : this.publishContent(id);
|
|
660
|
-
}
|
|
661
|
-
async getContentTypes() {
|
|
662
|
-
return this.request("GET", "/api/v1/content-types");
|
|
663
|
-
}
|
|
664
|
-
async createContentType(data) {
|
|
665
|
-
return this.request("POST", "/api/v1/content-types", data);
|
|
666
|
-
}
|
|
667
|
-
async updateContentType(slug, data) {
|
|
668
|
-
return this.request("PUT", `/api/v1/content-types/${slug}`, data);
|
|
669
|
-
}
|
|
670
|
-
async deleteContentType(slug) {
|
|
671
|
-
await this.request("DELETE", `/api/v1/content-types/${slug}`);
|
|
672
|
-
}
|
|
673
|
-
async getTaxonomies() {
|
|
674
|
-
return this.request("GET", "/api/v1/taxonomies");
|
|
675
|
-
}
|
|
676
|
-
async createTaxonomy(data) {
|
|
677
|
-
return this.request("POST", "/api/v1/taxonomies", data);
|
|
678
|
-
}
|
|
679
|
-
async attachTaxonomy(slug, contentType) {
|
|
680
|
-
await this.request("POST", `/api/v1/taxonomies/${slug}/attach`, { contentType });
|
|
681
|
-
}
|
|
682
|
-
async detachTaxonomy(slug, contentType) {
|
|
683
|
-
await this.request("POST", `/api/v1/taxonomies/${slug}/detach`, { contentType });
|
|
684
|
-
}
|
|
685
|
-
async deleteTaxonomy(slug) {
|
|
686
|
-
await this.request("DELETE", `/api/v1/taxonomies/${slug}`);
|
|
687
|
-
}
|
|
688
|
-
async getFieldGroups(context) {
|
|
689
|
-
if (context?.type) {
|
|
690
|
-
const qs = new URLSearchParams({ type: context.type });
|
|
691
|
-
for (const [key, value] of Object.entries(context)) if (key !== "type" && value) qs.set(key, value);
|
|
692
|
-
return this.request("GET", `/api/v1/field-groups?${qs.toString()}`);
|
|
693
|
-
}
|
|
694
|
-
return this.request("GET", "/api/v1/field-groups");
|
|
695
|
-
}
|
|
696
|
-
async getFieldGroup(id) {
|
|
697
|
-
return this.request("GET", `/api/v1/field-groups/${id}`);
|
|
698
|
-
}
|
|
699
|
-
async createFieldGroup(data) {
|
|
700
|
-
return this.request("POST", "/api/v1/field-groups", data);
|
|
701
|
-
}
|
|
702
|
-
async getFieldTypes(category) {
|
|
703
|
-
const query = category ? `?category=${encodeURIComponent(category)}` : "";
|
|
704
|
-
return this.request("GET", `/api/v1/field-types${query}`);
|
|
705
|
-
}
|
|
706
|
-
async listMedia(options) {
|
|
707
|
-
const params = new URLSearchParams();
|
|
708
|
-
if (options?.page) params.set("page", String(options.page));
|
|
709
|
-
if (options?.limit) params.set("limit", String(options.limit));
|
|
710
|
-
if (options?.mimeType) params.set("mimeType", options.mimeType);
|
|
711
|
-
if (options?.search) params.set("search", options.search);
|
|
712
|
-
return this.request("GET", `/api/v1/media?${params.toString()}`);
|
|
713
|
-
}
|
|
714
|
-
async getMedia(id) {
|
|
715
|
-
return this.request("GET", `/api/v1/media/${id}`);
|
|
716
|
-
}
|
|
717
|
-
/** Upload multipart — NÃO seta Content-Type (o fetch precisa do boundary). */
|
|
718
|
-
async uploadMedia(file, options) {
|
|
719
|
-
const formData = new FormData();
|
|
720
|
-
formData.append("file", file);
|
|
721
|
-
if (options?.alt) formData.append("alt", options.alt);
|
|
722
|
-
if (options?.caption) formData.append("caption", options.caption);
|
|
723
|
-
const url = `${this.baseUrl}/api/v1/media/upload`;
|
|
724
|
-
const requestHeaders = {};
|
|
725
|
-
const csrf = this.getCsrfToken();
|
|
726
|
-
if (csrf) requestHeaders["x-csrf-token"] = csrf;
|
|
727
|
-
const response = await fetch(url, {
|
|
728
|
-
method: "POST",
|
|
729
|
-
headers: requestHeaders,
|
|
730
|
-
credentials: "include",
|
|
731
|
-
body: formData
|
|
732
|
-
});
|
|
733
|
-
if (!response.ok) {
|
|
734
|
-
const error = await response.json().catch(() => ({ error: `Upload failed: ${response.status}` }));
|
|
735
|
-
throw new Error(error.error ?? `Upload failed: ${response.status}`);
|
|
736
|
-
}
|
|
737
|
-
return response.json();
|
|
738
|
-
}
|
|
739
|
-
async updateMedia(id, data) {
|
|
740
|
-
return this.request("PUT", `/api/v1/media/${id}`, data);
|
|
741
|
-
}
|
|
742
|
-
async deleteMedia(id) {
|
|
743
|
-
await this.request("DELETE", `/api/v1/media/${id}`);
|
|
744
|
-
}
|
|
745
|
-
async listUsers(options) {
|
|
746
|
-
const params = new URLSearchParams();
|
|
747
|
-
if (options?.page) params.set("page", String(options.page));
|
|
748
|
-
if (options?.limit) params.set("limit", String(options.limit));
|
|
749
|
-
if (options?.search) params.set("search", options.search);
|
|
750
|
-
if (options?.status) params.set("status", options.status);
|
|
751
|
-
return this.request("GET", `/api/v1/users?${params.toString()}`);
|
|
752
|
-
}
|
|
753
|
-
async getUser(id) {
|
|
754
|
-
return this.request("GET", `/api/v1/users/${id}`);
|
|
755
|
-
}
|
|
756
|
-
async createUser(data) {
|
|
757
|
-
return this.request("POST", "/api/v1/users", data);
|
|
758
|
-
}
|
|
759
|
-
async updateUser(id, data) {
|
|
760
|
-
return this.request("PUT", `/api/v1/users/${id}`, data);
|
|
761
|
-
}
|
|
762
|
-
async deleteUser(id) {
|
|
763
|
-
await this.request("DELETE", `/api/v1/users/${id}`);
|
|
764
|
-
}
|
|
765
|
-
async setUserPassword(id, password) {
|
|
766
|
-
await this.request("PUT", `/api/v1/users/${id}/password`, { password });
|
|
767
|
-
}
|
|
768
|
-
async assignRole(userId, roleId) {
|
|
769
|
-
return this.request("POST", `/api/v1/users/${userId}/roles`, { roleId });
|
|
770
|
-
}
|
|
771
|
-
async removeRole(userId, roleId) {
|
|
772
|
-
return this.request("DELETE", `/api/v1/users/${userId}/roles/${roleId}`);
|
|
773
|
-
}
|
|
774
|
-
async listRoles() {
|
|
775
|
-
return this.request("GET", "/api/v1/roles");
|
|
776
|
-
}
|
|
777
|
-
async getSettings(group) {
|
|
778
|
-
const query = group ? `?group=${encodeURIComponent(group)}` : "";
|
|
779
|
-
return this.request("GET", `/api/v1/settings${query}`);
|
|
780
|
-
}
|
|
781
|
-
async updateSettings(items) {
|
|
782
|
-
await this.request("PUT", "/api/v1/settings", items);
|
|
783
|
-
}
|
|
784
|
-
async healthCheck() {
|
|
785
|
-
return this.request("GET", "/health");
|
|
786
|
-
}
|
|
787
|
-
async getThemes() {
|
|
788
|
-
return (await this.request("GET", "/api/v1/themes")).map((theme) => ({
|
|
789
|
-
id: String(theme["id"] ?? ""),
|
|
790
|
-
name: String(theme["name"] ?? ""),
|
|
791
|
-
version: theme["version"] ? String(theme["version"]) : void 0,
|
|
792
|
-
status: String(theme["status"] ?? "INSTALLED"),
|
|
793
|
-
manifest: theme["manifest"] ?? null
|
|
794
|
-
}));
|
|
795
|
-
}
|
|
796
|
-
};
|
|
797
|
-
var apiClient = new ApiClient();
|
|
798
|
-
//#endregion
|
|
799
|
-
//#region src/i18n/locale.ts
|
|
800
|
-
var LOCALE_COOKIE = "admin_locale";
|
|
801
|
-
/** Obtém locale do cookie */
|
|
802
|
-
function getCookieLocale() {
|
|
803
|
-
if (typeof document === "undefined") return null;
|
|
804
|
-
const match = document.cookie.match(new RegExp(`(?:^|; )${LOCALE_COOKIE}=([^;]+)`));
|
|
805
|
-
if (match?.[1] && SUPPORTED_LOCALES.includes(match[1])) return match[1];
|
|
806
|
-
return null;
|
|
807
|
-
}
|
|
808
|
-
/** Define locale no cookie (1 ano) */
|
|
809
|
-
function setCookieLocale(locale) {
|
|
810
|
-
if (typeof document === "undefined") return;
|
|
811
|
-
document.cookie = `${LOCALE_COOKIE}=${locale}; path=/; max-age=31536000; SameSite=Lax`;
|
|
812
|
-
}
|
|
813
|
-
/** Obtém locale do Accept-Language header */
|
|
814
|
-
function getBrowserLocale() {
|
|
815
|
-
if (typeof navigator === "undefined") return "en";
|
|
816
|
-
const lang = navigator.language?.split("-")[0]?.toLowerCase();
|
|
817
|
-
const fullLang = navigator.language?.toLowerCase();
|
|
818
|
-
for (const locale of SUPPORTED_LOCALES) if (locale.toLowerCase() === fullLang || locale.split("-")[0] === lang) return locale;
|
|
819
|
-
return "en";
|
|
820
|
-
}
|
|
821
|
-
/** Obtém locale do usuário logado via API */
|
|
822
|
-
async function getUserLocaleFromAPI() {
|
|
823
|
-
try {
|
|
824
|
-
const locale = await apiClient.getUserLocale();
|
|
825
|
-
if (locale && SUPPORTED_LOCALES.includes(locale)) return locale;
|
|
826
|
-
} catch {}
|
|
827
|
-
return null;
|
|
828
|
-
}
|
|
829
|
-
/** Salva locale do usuário via API */
|
|
830
|
-
async function setUserLocaleInAPI(locale) {
|
|
831
|
-
await apiClient.setUserLocale(locale);
|
|
832
|
-
}
|
|
833
|
-
/** Resolve locale final com prioridade: cookie → user API → browser → default */
|
|
834
|
-
async function resolveLocale() {
|
|
835
|
-
const cookie = getCookieLocale();
|
|
836
|
-
if (cookie) return cookie;
|
|
837
|
-
const user = await getUserLocaleFromAPI();
|
|
838
|
-
if (user) return user;
|
|
839
|
-
const browser = getBrowserLocale();
|
|
840
|
-
if (browser) return browser;
|
|
841
|
-
return "en";
|
|
842
|
-
}
|
|
843
|
-
/** Muda locale (salva no cookie + API se logado) */
|
|
844
|
-
async function changeLocale(locale) {
|
|
845
|
-
setCookieLocale(locale);
|
|
846
|
-
try {
|
|
847
|
-
await setUserLocaleInAPI(locale);
|
|
848
|
-
} catch {}
|
|
849
|
-
}
|
|
850
|
-
//#endregion
|
|
851
|
-
//#region src/i18n/index.ts
|
|
852
|
-
var tFunctionCache = /* @__PURE__ */ new Map();
|
|
853
|
-
/** Cria função de tradução para um locale */
|
|
854
|
-
function createTFunction(translations, fallback) {
|
|
855
|
-
return function t(key, params) {
|
|
856
|
-
const keys = key.split(".");
|
|
857
|
-
let value = translations;
|
|
858
|
-
for (const k of keys) if (value && typeof value === "object" && k in value) value = value[k];
|
|
859
|
-
else {
|
|
860
|
-
value = fallback;
|
|
861
|
-
for (const k of keys) if (value && typeof value === "object" && k in value) value = value[k];
|
|
862
|
-
else return key;
|
|
863
|
-
break;
|
|
864
|
-
}
|
|
865
|
-
if (typeof value !== "string") return key;
|
|
866
|
-
if (params) return value.replace(/\{(\w+)\}/g, (_, param) => String(params[param] ?? ""));
|
|
867
|
-
return value;
|
|
868
|
-
};
|
|
869
|
-
}
|
|
870
|
-
/** Obtém ou cria função de tradução para locale */
|
|
871
|
-
async function getTFunction(locale) {
|
|
872
|
-
if (tFunctionCache.has(locale)) return tFunctionCache.get(locale);
|
|
873
|
-
const [translations, fallback] = await Promise.all([loadLocale(locale), loadLocale("en")]);
|
|
874
|
-
const fn = createTFunction(translations, fallback);
|
|
875
|
-
tFunctionCache.set(locale, fn);
|
|
876
|
-
return fn;
|
|
877
|
-
}
|
|
878
|
-
var currentTFunction = (key) => key;
|
|
879
|
-
var currentLocale = "en";
|
|
880
|
-
var isLoading = true;
|
|
881
|
-
/** Hook Solid para usar traduções em componentes */
|
|
882
|
-
function useTranslation(initialLocale) {
|
|
883
|
-
const [, forceUpdate] = createSignal(0);
|
|
884
|
-
onMount(async () => {
|
|
885
|
-
if (isLoading) {
|
|
886
|
-
const resolvedLocale = initialLocale ?? await resolveLocale();
|
|
887
|
-
currentLocale = resolvedLocale;
|
|
888
|
-
currentTFunction = await getTFunction(resolvedLocale);
|
|
889
|
-
isLoading = false;
|
|
890
|
-
forceUpdate((n) => n + 1);
|
|
891
|
-
}
|
|
892
|
-
});
|
|
893
|
-
const changeLocaleFn = async (newLocale) => {
|
|
894
|
-
isLoading = true;
|
|
895
|
-
await changeLocale(newLocale);
|
|
896
|
-
currentLocale = newLocale;
|
|
897
|
-
currentTFunction = await getTFunction(newLocale);
|
|
898
|
-
isLoading = false;
|
|
899
|
-
forceUpdate((n) => n + 1);
|
|
900
|
-
};
|
|
901
|
-
const translate = (key, params) => currentTFunction(key, params);
|
|
902
|
-
return {
|
|
903
|
-
t: translate,
|
|
904
|
-
get locale() {
|
|
905
|
-
return currentLocale;
|
|
906
|
-
},
|
|
907
|
-
changeLocale: changeLocaleFn,
|
|
908
|
-
get loading() {
|
|
909
|
-
return isLoading;
|
|
910
|
-
}
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
|
-
//#endregion
|
|
914
398
|
//#region src/components/LanguageSelector.tsx
|
|
915
399
|
var _tmpl$$7 = [
|
|
916
400
|
"<ul",
|
|
@@ -1569,7 +1053,7 @@ function HelpTabs(props) {
|
|
|
1569
1053
|
/** Versão do release atual (ex.: "0.4.0"). */
|
|
1570
1054
|
var APP_VERSION = {
|
|
1571
1055
|
name: "okcms",
|
|
1572
|
-
version: "0.4.
|
|
1056
|
+
version: "0.4.7",
|
|
1573
1057
|
"private": true,
|
|
1574
1058
|
description: "Hybrid, modular, API-first CMS",
|
|
1575
1059
|
engines: {
|
|
@@ -2080,4 +1564,4 @@ var $$DashboardLayout = createComponent$1(($$result, $$props, $$slots) => {
|
|
|
2080
1564
|
})}</div></main></div>` })}${renderScript($$result, "/home/runner/work/cms/cms/apps/admin/src/layouts/DashboardLayout.astro?astro&type=script&index=0&lang.ts")}`;
|
|
2081
1565
|
}, "/home/runner/work/cms/cms/apps/admin/src/layouts/DashboardLayout.astro", void 0);
|
|
2082
1566
|
//#endregion
|
|
2083
|
-
export {
|
|
1567
|
+
export { For2 as a, Select as c, createMemo$1 as d, createSignal$1 as f, Card as i, Show2 as l, Badge as n, Input as o, onMount$1 as p, Button as r, Pagination as s, $$DashboardLayout as t, Table as u };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as useTranslation, r as apiClient } from "./i18n_DnHqy5K-.mjs";
|
|
2
|
+
import { a as For2, c as Select, f as createSignal, l as Show2, o as Input, p as onMount, r as Button, s as Pagination } from "./DashboardLayout_BSI1WOi6.mjs";
|
|
2
3
|
import { createComponent, escape, ssr, ssrAttribute, ssrHydrationKey, ssrStyleProperty } from "solid-js/web";
|
|
3
4
|
//#region src/components/media/MediaLibrary.tsx
|
|
4
5
|
var _tmpl$ = [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { r as __exportAll } from "./rolldown-runtime_BMI-E3GI.mjs";
|
|
2
2
|
import { S as createAstro, d as maybeRenderHead, i as renderComponent, p as addAttribute, u as renderTemplate } from "./server_B5N27szj.mjs";
|
|
3
3
|
import { t as createComponent } from "./compiler_O7J1rlsi.mjs";
|
|
4
|
-
import { t as $$DashboardLayout } from "./
|
|
4
|
+
import { t as $$DashboardLayout } from "./DashboardLayout_BSI1WOi6.mjs";
|
|
5
5
|
//#region src/pages/plugins/[slug].astro
|
|
6
6
|
var _slug__exports = /* @__PURE__ */ __exportAll({
|
|
7
7
|
default: () => $$Slug,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { r as __exportAll } from "./rolldown-runtime_BMI-E3GI.mjs";
|
|
2
2
|
import { S as createAstro, d as maybeRenderHead, i as renderComponent, u as renderTemplate } from "./server_B5N27szj.mjs";
|
|
3
3
|
import { t as createComponent } from "./compiler_O7J1rlsi.mjs";
|
|
4
|
-
import { t as $$DashboardLayout } from "./
|
|
5
|
-
import { t as ContentEditor } from "./
|
|
4
|
+
import { t as $$DashboardLayout } from "./DashboardLayout_BSI1WOi6.mjs";
|
|
5
|
+
import { t as ContentEditor } from "./ContentEditor_DYVCMTXI.mjs";
|
|
6
6
|
//#region src/pages/content/edit.astro
|
|
7
7
|
var edit_exports = /* @__PURE__ */ __exportAll({
|
|
8
8
|
default: () => $$Edit,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { r as __exportAll } from "./rolldown-runtime_BMI-E3GI.mjs";
|
|
2
2
|
import { S as createAstro, d as maybeRenderHead, i as renderComponent, u as renderTemplate } from "./server_B5N27szj.mjs";
|
|
3
3
|
import { t as createComponent$1 } from "./compiler_O7J1rlsi.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { n as useTranslation, r as apiClient } from "./i18n_DnHqy5K-.mjs";
|
|
5
|
+
import { c as Select, f as createSignal, i as Card, l as Show2, o as Input, p as onMount, r as Button, t as $$DashboardLayout } from "./DashboardLayout_BSI1WOi6.mjs";
|
|
5
6
|
import { createComponent, escape, memo, ssr, ssrHydrationKey } from "solid-js/web";
|
|
6
7
|
//#region src/components/apps/settings/GeneralSettings.tsx
|
|
7
8
|
var _tmpl$ = [
|