@hanzo/ui 8.0.12 → 8.0.13

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.
@@ -1,4 +1,6 @@
1
- export type Channel = 'x' | 'facebook' | 'instagram' | 'linkedin' | 'tiktok' | 'youtube' | 'threads';
1
+ import type { Provider } from './api';
2
+ /** The network vocabulary is the backend's ONE ordered list (./api PROVIDERS). */
3
+ export type Channel = Provider;
2
4
  /**
3
5
  * A known network, or whatever string the server sent. The badge renders unknown
4
6
  * values through the `x` fallback below, so the type says what it really accepts —
@@ -1,4 +1,4 @@
1
- import type { Post } from './PostCard';
1
+ import type { Post } from './api';
2
2
  export declare function PostAgenda({ posts, onOpen }: {
3
3
  posts: Post[];
4
4
  onOpen: (p: Post) => void;
@@ -1,13 +1,4 @@
1
- import { type ChannelLike } from './ChannelBadge';
2
- export type Post = {
3
- id: string;
4
- content: string;
5
- channel: ChannelLike;
6
- status: string;
7
- /** unix seconds; 0/undefined = not scheduled */
8
- scheduleAt?: number;
9
- media?: string[];
10
- };
1
+ import type { Post } from './api';
11
2
  export declare function PostCard({ post, onEdit, onDelete, }: {
12
3
  post: Post;
13
4
  onEdit?: (p: Post) => void;
@@ -1,4 +1,4 @@
1
- import type { ProviderCapability } from './ProviderReadinessList';
1
+ import type { ProviderCapability } from './api';
2
2
  /** Compose intents → the (status, scheduleAt) the backend stores. */
3
3
  export declare const COMPOSE_MODES: readonly ["draft", "schedule", "now"];
4
4
  export type ComposeMode = (typeof COMPOSE_MODES)[number];
@@ -1,10 +1,4 @@
1
- /** One network's readiness, as reported by the server. */
2
- export type ProviderCapability = {
3
- provider: string;
4
- credentialsConfigured: boolean;
5
- /** The env vars still missing — shown verbatim, never summarized away. */
6
- missingCredentials: string[];
7
- };
1
+ import type { ProviderCapability } from './api';
8
2
  export declare function ProviderReadinessList({ providers }: {
9
3
  providers: ProviderCapability[];
10
4
  }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { type SocialApi } from './api';
2
+ export declare function SocialResource({ api, title, subtitle, }: {
3
+ /** The bound `/v1/social` client — `createSocialApi(<host transport>)`. */
4
+ api: SocialApi;
5
+ title?: string;
6
+ subtitle?: string;
7
+ }): import("react/jsx-runtime").JSX.Element;
@@ -1,9 +1,4 @@
1
- export type SocialSummary = {
2
- posts: number;
3
- scheduled: number;
4
- published: number;
5
- accounts: number;
6
- };
1
+ import type { SocialSummary } from './api';
7
2
  export declare function SocialSummaryBar({ summary }: {
8
3
  summary: SocialSummary;
9
4
  }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,128 @@
1
+ /**
2
+ * The `/v1/social` contract — the ONE typed client for the Hanzo Social surface,
3
+ * shared by every host that renders it (the console's Publish product, the dedicated
4
+ * social.hanzo.ai app, any white-label admin).
5
+ *
6
+ * The backend is `hanzoai/cloud` `clients/social`: a native-Go per-org accounts+posts
7
+ * store on Base/SQLite (the in-process fold of the standalone social stack, twin of
8
+ * clients/crm) — NOT a proxy to the retired social pods. Routes (social.go):
9
+ *
10
+ * GET /v1/social/summary per-org roll-up
11
+ * GET /v1/social/providers publish-readiness per network
12
+ * GET/POST /v1/social/accounts list (?provider=) / connect
13
+ * GET/PUT/DELETE /v1/social/accounts/:id detail / update / disconnect
14
+ * GET/POST /v1/social/posts list (?status=) / create-or-schedule
15
+ * GET/PUT/DELETE /v1/social/posts/:id detail / update / delete
16
+ * POST /v1/social/posts/:id/publish publish now
17
+ *
18
+ * TRANSPORT IS INJECTED. This layer never picks an origin, a credential or a fetch
19
+ * wrapper — the host passes a `SocialRest` whose paths are relative to `/v1/social`
20
+ * (`'summary'`, `'posts/<id>/publish'`), so the console rides its session-cookie
21
+ * `originV1Url` and another app rides its own. Every read/write is org-scoped
22
+ * SERVER-SIDE from the validated bearer/session owner claim; no org ever travels
23
+ * from the browser.
24
+ *
25
+ * Payloads are normalized DEFENSIVELY: a field rename upstream degrades a cell
26
+ * rather than throwing, and a list is read from whichever envelope key the backend
27
+ * uses (`data`/`items`/`rows`, or a bare array).
28
+ */
29
+ /** Networks — the ONE ordered vocabulary (cloud rejects an unknown provider; '' → x). */
30
+ export declare const PROVIDERS: readonly ["x", "facebook", "instagram", "linkedin", "tiktok", "youtube", "threads"];
31
+ export type Provider = (typeof PROVIDERS)[number];
32
+ /** Account connection lifecycle (cloud rejects an unknown status; '' → connected). */
33
+ export declare const ACCOUNT_STATUSES: readonly ["connected", "disconnected", "error"];
34
+ /** Post lifecycle (cloud rejects an unknown status; '' → draft). */
35
+ export declare const POST_STATUSES: readonly ["draft", "scheduled", "published", "failed"];
36
+ export type Account = {
37
+ id: string;
38
+ provider: string;
39
+ handle: string;
40
+ status: string;
41
+ createdAt: number;
42
+ updatedAt: number;
43
+ };
44
+ export type Post = {
45
+ id: string;
46
+ content: string;
47
+ channel: string;
48
+ status: string;
49
+ /** Unix seconds; 0 = not scheduled / publish now. */
50
+ scheduleAt: number;
51
+ /**
52
+ * Attached media URLs. Cloud ALWAYS serializes an array (never null) and its PUT
53
+ * rebuilds the row from the body — so this has to round-trip: an update that
54
+ * omitted it would wipe the post's media.
55
+ */
56
+ media: string[];
57
+ /** Server-managed publish results (empty until a publish attempt lands). */
58
+ accountId?: string;
59
+ externalId?: string;
60
+ error?: string;
61
+ createdAt: number;
62
+ updatedAt: number;
63
+ };
64
+ /** The per-org roll-up (GET /v1/social/summary) — the counts SocialSummaryBar renders. */
65
+ export type SocialSummary = {
66
+ posts: number;
67
+ scheduled: number;
68
+ published: number;
69
+ accounts: number;
70
+ };
71
+ /**
72
+ * A network's publish-readiness (GET /v1/social/providers): whether this deployment
73
+ * holds the OAuth-app credentials to publish, and — if not — exactly which env vars
74
+ * are missing. The honest connect affordance; never a fabricated "connected".
75
+ */
76
+ export type ProviderCapability = {
77
+ provider: string;
78
+ credentialsConfigured: boolean;
79
+ missingCredentials: string[];
80
+ };
81
+ /** Create/update bodies — only the writable fields (server owns id/org/timestamps). */
82
+ export type NewAccount = Partial<Omit<Account, 'id' | 'createdAt' | 'updatedAt'>> & {
83
+ provider: string;
84
+ };
85
+ export type NewPost = Partial<Omit<Post, 'id' | 'createdAt' | 'updatedAt'>> & {
86
+ content: string;
87
+ };
88
+ export declare function normalizeAccount(raw: unknown): Account;
89
+ export declare function normalizePost(raw: unknown): Post;
90
+ export declare function normalizeSummary(raw: unknown): SocialSummary;
91
+ export declare function normalizeProviderCapability(raw: unknown): ProviderCapability;
92
+ export declare const normalizeAccounts: (p: unknown) => Account[];
93
+ export declare const normalizePosts: (p: unknown) => Post[];
94
+ export declare const normalizeProviders: (p: unknown) => ProviderCapability[];
95
+ /**
96
+ * The host's REST transport. `path` is relative to `/v1/social` (no leading slash);
97
+ * the host owns the origin, the credential and the error class. A rejected promise
98
+ * is passed straight to `classifyBackend`, so any client's error type works.
99
+ */
100
+ export type SocialRest = {
101
+ get: (path: string) => Promise<unknown>;
102
+ post: (path: string, body?: unknown) => Promise<unknown>;
103
+ put: (path: string, body?: unknown) => Promise<unknown>;
104
+ del: (path: string) => Promise<void>;
105
+ };
106
+ export type SocialApi = ReturnType<typeof createSocialApi>;
107
+ /** Bind the `/v1/social` contract to a host transport. One method per documented route. */
108
+ export declare function createSocialApi(rest: SocialRest): {
109
+ summary: () => Promise<SocialSummary>;
110
+ /** Publish-readiness per network (+ the exact missing OAuth-app credentials). */
111
+ providers: () => Promise<ProviderCapability[]>;
112
+ accounts: {
113
+ list: (provider?: string) => Promise<Account[]>;
114
+ get: (id: string) => Promise<Account>;
115
+ create: (body: NewAccount) => Promise<Account>;
116
+ update: (id: string, body: NewAccount) => Promise<Account>;
117
+ remove: (id: string) => Promise<void>;
118
+ };
119
+ posts: {
120
+ list: (status?: string) => Promise<Post[]>;
121
+ get: (id: string) => Promise<Post>;
122
+ create: (body: NewPost) => Promise<Post>;
123
+ update: (id: string, body: NewPost) => Promise<Post>;
124
+ remove: (id: string) => Promise<void>;
125
+ /** Publish a post NOW to its channel's connected accounts. */
126
+ publish: (id: string) => Promise<Post>;
127
+ };
128
+ };
@@ -1,3 +1,5 @@
1
+ export * from './api';
2
+ export * from './SocialResource';
1
3
  export * from './ChannelBadge';
2
4
  export * from './CampaignCard';
3
5
  export * from './PostCard';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzo/ui",
3
- "version": "8.0.12",
3
+ "version": "8.0.13",
4
4
  "type": "module",
5
5
  "description": "Hanzo UI — the one canonical, backend-flexible component library on @hanzo/gui + @hanzo/tokens. A shared design core (Hanzo dark-first tokens, Geist Sans/Mono typography) with per-backend implementations: the shadcn-compatible web surface (Radix + Tailwind, the API apps import) and the @hanzo/gui product layer (cross-platform web + native + desktop). Self-contained (theme.css), presentational, host-agnostic, clean-room.",
6
6
  "exports": {
@@ -132,8 +132,22 @@
132
132
  "files": [
133
133
  "dist"
134
134
  ],
135
+ "scripts": {
136
+ "build": "tsup && tsc -p tsconfig.build.json && mkdir -p dist/styles && cp src/styles/hanzo-motion.css dist/styles/hanzo-motion.css && node scripts/add-use-client.mjs",
137
+ "clean": "rm -rf dist types",
138
+ "gen:primitives": "node scripts/gen-primitives.mjs",
139
+ "prepack": "pnpm run build",
140
+ "tc": "tsc --noEmit",
141
+ "typecheck": "tsc --noEmit",
142
+ "typecheck:ui": "tsc -p tsconfig.check.json",
143
+ "check:svelte": "svelte-check --tsconfig ./tsconfig.svelte.json",
144
+ "test": "vitest run",
145
+ "test:watch": "vitest"
146
+ },
135
147
  "dependencies": {
136
148
  "@hanzo/logo": "^1.0.13",
149
+ "@hanzo/products": "workspace:*",
150
+ "@hanzo/tokens": "workspace:*",
137
151
  "@hanzogui/telemetry": "^0.1.0",
138
152
  "@radix-ui/react-aspect-ratio": "^1.1.8",
139
153
  "@radix-ui/react-avatar": "^1.1.11",
@@ -158,15 +172,13 @@
158
172
  "cmdk": "^1.1.1",
159
173
  "lucide-react": ">=0.456.0",
160
174
  "sonner": "^2.0.7",
161
- "tailwind-merge": "^3.5.0",
162
- "@hanzo/products": "0.2.0",
163
- "@hanzo/tokens": "1.0.0"
175
+ "tailwind-merge": "^3.5.0"
164
176
  },
165
177
  "peerDependencies": {
166
178
  "@hanzo/canvas": ">=0.1.0",
167
179
  "@hanzo/dashboard": ">=0.1.0",
168
180
  "@hanzo/data": ">=1.2.0",
169
- "@hanzo/gitops": ">=0.1.0",
181
+ "@hanzo/cd": ">=0.1.0",
170
182
  "@hanzo/gui": ">=7.2.2",
171
183
  "@hanzo/ui-shadcn": ">=5.7.0",
172
184
  "@hanzo/usage": ">=0.1.0",
@@ -187,7 +199,7 @@
187
199
  "@hanzo/dashboard": {
188
200
  "optional": true
189
201
  },
190
- "@hanzo/gitops": {
202
+ "@hanzo/cd": {
191
203
  "optional": true
192
204
  },
193
205
  "@hanzo/ui-shadcn": {
@@ -227,16 +239,5 @@
227
239
  "access": "public"
228
240
  },
229
241
  "license": "BSD-3-Clause",
230
- "author": "Hanzo AI <dev@hanzo.ai>",
231
- "scripts": {
232
- "build": "tsup && tsc -p tsconfig.build.json && mkdir -p dist/styles && cp src/styles/hanzo-motion.css dist/styles/hanzo-motion.css && node scripts/add-use-client.mjs",
233
- "clean": "rm -rf dist types",
234
- "gen:primitives": "node scripts/gen-primitives.mjs",
235
- "tc": "tsc --noEmit",
236
- "typecheck": "tsc --noEmit",
237
- "typecheck:ui": "tsc -p tsconfig.check.json",
238
- "check:svelte": "svelte-check --tsconfig ./tsconfig.svelte.json",
239
- "test": "vitest run",
240
- "test:watch": "vitest"
241
- }
242
- }
242
+ "author": "Hanzo AI <dev@hanzo.ai>"
243
+ }
package/LICENSE.md DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2023 hanzo
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.