@sv-print/plugin-cloud 0.0.0-stage → 0.1.1

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.
@@ -0,0 +1,43 @@
1
+ import type { CloudClient } from "./cloud-client";
2
+ import type { TransitClient } from "./transit-client";
3
+ import type { CloudAuthAPI, PluginConfig } from "../types";
4
+ import type { CategoryItem, CloudDevice, CloudJob, CloudPrintOptions, CloudPrinter, IndustryItem, PageResult, RenderOptions, RenderTask, TemplateItem, TemplateQuery, TransitClientInfo, TransitPrintOptions, TransitTicket } from "../types";
5
+ export declare class CloudService {
6
+ private client;
7
+ private transit;
8
+ private auth;
9
+ private config;
10
+ constructor(config: PluginConfig, client: CloudClient, transit: TransitClient, auth: CloudAuthAPI);
11
+ private requireLogin;
12
+ render(opts?: RenderOptions): Promise<RenderTask>;
13
+ getRenderTask(id: string | number): Promise<RenderTask>;
14
+ waitRender(id: string | number, opts?: {
15
+ interval?: number;
16
+ timeout?: number;
17
+ }): Promise<RenderTask>;
18
+ cloudPrint(opts: CloudPrintOptions): Promise<CloudJob>;
19
+ getDevices(): Promise<CloudDevice[]>;
20
+ getDevicePrinters(deviceId: string): Promise<CloudPrinter[]>;
21
+ getJobs(params?: Record<string, any>): Promise<PageResult<CloudJob>>;
22
+ cancelJob(id: string | number): Promise<any>;
23
+ retryJob(id: string | number): Promise<any>;
24
+ getTransitTicket(): Promise<TransitTicket>;
25
+ onTransitConnectionChange(fn: (connected: boolean) => void): () => void;
26
+ private ensureTransitConnected;
27
+ getTransitClients(): Promise<TransitClientInfo[]>;
28
+ getTransitPrinters(clientId?: string): Promise<any[]>;
29
+ transitPrint(opts?: TransitPrintOptions): Promise<any>;
30
+ disconnectTransit(): void;
31
+ listTemplates(query?: TemplateQuery): Promise<PageResult<TemplateItem>>;
32
+ getTemplateData(id: string | number): Promise<any>;
33
+ applyTemplate(item: TemplateItem): Promise<{
34
+ template_data: any;
35
+ preview_data: any;
36
+ }>;
37
+ useRandomTemplate(query?: TemplateQuery): Promise<TemplateItem>;
38
+ private parseMaybeJson;
39
+ useTemplate(id: string | number): Promise<any>;
40
+ getCategories(): Promise<CategoryItem[]>;
41
+ getIndustries(): Promise<IndustryItem[]>;
42
+ private du;
43
+ }
@@ -0,0 +1,29 @@
1
+ import type { ApiEnvelope, PluginConfig } from "../types";
2
+ export interface RequestOptions {
3
+ params?: Record<string, any>;
4
+ body?: any;
5
+ headers?: Record<string, string>;
6
+ auth?: boolean;
7
+ }
8
+ export declare class CloudClient {
9
+ readonly host: string;
10
+ private tokenGetter?;
11
+ private onUnauthorizedCb?;
12
+ private adapter?;
13
+ constructor(config: PluginConfig);
14
+ setTokenGetter(fn: () => string | null): void;
15
+ setOnUnauthorized(fn: () => void): void;
16
+ private notifyUnauthorized;
17
+ apiUrl(path: string): string;
18
+ absUrl(path: string): string;
19
+ private buildUrl;
20
+ private buildHeaders;
21
+ request<T = any>(method: string, path: string, options?: RequestOptions): Promise<T>;
22
+ private parseResponse;
23
+ private unwrap;
24
+ get<T = any>(path: string, options?: RequestOptions): Promise<T>;
25
+ post<T = any>(path: string, options?: RequestOptions): Promise<T>;
26
+ patch<T = any>(path: string, options?: RequestOptions): Promise<T>;
27
+ del<T = any>(path: string, options?: RequestOptions): Promise<T>;
28
+ }
29
+ export type { ApiEnvelope };
@@ -0,0 +1,18 @@
1
+ import type { PluginConfig } from "../types";
2
+ import { CloudClient } from "./cloud-client";
3
+ import { AuthManager } from "./auth/manager";
4
+ import { TransitClient } from "./transit-client";
5
+ import { CloudService } from "./cloud-api";
6
+ export declare function setDesignerUtils(du: any): void;
7
+ export declare function getDesignerUtils(): any;
8
+ export declare function resetDesignerUtils(): void;
9
+ export interface CloudInstances {
10
+ config: PluginConfig;
11
+ client: CloudClient;
12
+ auth: AuthManager;
13
+ transit: TransitClient;
14
+ service: CloudService;
15
+ }
16
+ export declare function setCloudInstances(value: CloudInstances): void;
17
+ export declare function getCloudInstances(): CloudInstances | undefined;
18
+ export declare function ensureCloudInstances(config: PluginConfig): CloudInstances;
@@ -0,0 +1,3 @@
1
+ import type { PluginConfig } from "../types";
2
+ export declare function installTemplateCenterMenu(designerUtils: any, config: PluginConfig, onOpen: () => void): void;
3
+ export declare function removeTemplateCenterMenu(designerUtils: any): void;
@@ -0,0 +1,17 @@
1
+ export declare function createPrintOptions(): {
2
+ pageSize: string;
3
+ width: number;
4
+ height: number;
5
+ copies: number;
6
+ landscape: boolean;
7
+ duplexMode: string;
8
+ color: boolean;
9
+ silent: boolean;
10
+ printBackground: boolean;
11
+ scaleFactor: number;
12
+ pagesPerSheet: number;
13
+ marginType: string;
14
+ extra: string;
15
+ };
16
+ export type PrintOptionsForm = ReturnType<typeof createPrintOptions>;
17
+ export declare function buildPrintOptions(form: PrintOptionsForm, printer: string): Record<string, any>;
@@ -0,0 +1,2 @@
1
+ import type { CloudService } from "./cloud-api";
2
+ export declare function extendTemplate(template: any, service: CloudService): void;
@@ -0,0 +1,31 @@
1
+ import type { PluginConfig, TransitTicket } from "../types";
2
+ type Handler = (...args: any[]) => void;
3
+ export declare class TransitClient {
4
+ private host;
5
+ private socket;
6
+ private connecting;
7
+ private generation;
8
+ private printing;
9
+ private pending;
10
+ private stateListeners;
11
+ onConnectionChange(fn: (connected: boolean) => void): () => void;
12
+ private notifyState;
13
+ private failPending;
14
+ private handlers;
15
+ constructor(config: PluginConfig);
16
+ private getIo;
17
+ private resolveBase;
18
+ private ensureNetworkPermission;
19
+ private attachHandlers;
20
+ on(event: string, fn: Handler): void;
21
+ off(event: string, fn?: Handler): void;
22
+ private waitFor;
23
+ emit(event: string, payload?: any): boolean;
24
+ connect(ticket: TransitTicket): Promise<any>;
25
+ getClients(timeout?: number): Promise<any[]>;
26
+ getPrinters(clientId?: string, timeout?: number): Promise<any[]>;
27
+ print(payload: any, timeout?: number): Promise<any>;
28
+ isConnected(): boolean;
29
+ disconnect(): void;
30
+ }
31
+ export {};
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ @charset "UTF-8";.svp-cloud-oauth-overlay{position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;background:#00000073}.svp-cloud-oauth-box{width:420px;max-width:calc(100vw - 32px);height:620px;max-height:calc(100vh - 64px);display:flex;flex-direction:column;background:var(--color-base-100, #fff);color:var(--color-base-content, #1f2937);border-radius:6px;overflow:hidden;box-shadow:0 8px 30px #0000004d}.svp-cloud-oauth-head{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;font-size:14px;font-weight:600;border-bottom:1px solid color-mix(in oklch,var(--color-base-content, #1f2937) 12%,transparent)}.svp-cloud-oauth-close{border:none;background:transparent;font-size:20px;line-height:1;cursor:pointer;color:inherit}.svp-cloud-oauth-close:hover{opacity:.7}.svp-cloud-oauth-frame{flex:1;width:100%;border:none}.svp-cloud-auth-form{display:flex;flex-direction:column;gap:8px}.svp-cloud-auth-hint{margin:0;font-size:12px;opacity:.7}.svp-cloud-auth-input{width:100%;box-sizing:border-box;padding:6px 8px;font-size:12px;font-family:inherit;color:inherit;border-radius:4px;border:1px solid color-mix(in oklch,var(--color-base-content, #1f2937) 20%,transparent);background-color:var(--color-base-100, #fff)}.svp-cloud-auth-textarea{resize:vertical}.svp-cloud-auth-error{font-size:12px;color:var(--color-error, #ef4444);min-height:14px}.svp-cloud-auth-actions{display:flex;gap:8px}.svp-cloud-tc-box.svelte-1qg2qyu.svelte-1qg2qyu{width:80vw;max-width:1100px;height:78vh;display:flex;flex-direction:column;padding:14px 16px;background-color:var(--color-base-100, #fff);color:var(--color-base-content, #1f2937)}.svp-cloud-tc-head.svelte-1qg2qyu.svelte-1qg2qyu{display:flex;align-items:center;gap:10px;padding-bottom:10px;border-bottom:1px solid color-mix(in oklch,var(--color-base-content, #1f2937) 12%,transparent)}.svp-cloud-tc-title.svelte-1qg2qyu.svelte-1qg2qyu{font-size:16px;font-weight:700}.tc-search-wrap.svelte-1qg2qyu.svelte-1qg2qyu{position:relative;margin-left:auto}.svp-cloud-tc-search.svelte-1qg2qyu.svelte-1qg2qyu{width:168px;height:26px;padding:0 24px 0 8px;font-size:12px}.tc-search-clear.svelte-1qg2qyu.svelte-1qg2qyu{position:absolute;top:50%;right:4px;transform:translateY(-50%);width:18px;height:18px;line-height:16px;border:none;border-radius:50%;background:transparent;color:inherit;opacity:.55;font-size:14px;cursor:pointer}.tc-search-clear.svelte-1qg2qyu.svelte-1qg2qyu:hover{opacity:1}.svp-cloud-tc-filters.svelte-1qg2qyu.svelte-1qg2qyu{padding:8px 0;display:flex;flex-direction:column;gap:6px;max-height:108px;overflow-y:auto}.tc-filter.svelte-1qg2qyu.svelte-1qg2qyu{display:flex;flex-wrap:wrap;align-items:center;gap:4px}.tc-filter-label.svelte-1qg2qyu.svelte-1qg2qyu{font-size:12px;opacity:.7;margin-right:4px;flex:0 0 auto}.tc-chip.svelte-1qg2qyu.svelte-1qg2qyu{border:1px solid color-mix(in oklch,var(--color-base-content, #1f2937) 20%,transparent);background:transparent;color:inherit;font-size:12px;line-height:1;padding:4px 8px;border-radius:999px;cursor:pointer}.tc-chip.active.svelte-1qg2qyu.svelte-1qg2qyu{background:var(--color-primary, #409eff);color:var(--color-primary-content, #fff);border-color:transparent}.svp-cloud-tc-body.svelte-1qg2qyu.svelte-1qg2qyu{flex:1;min-height:0;overflow-y:auto;padding:4px 0}.svp-cloud-tc-grid.svelte-1qg2qyu.svelte-1qg2qyu{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px}.tc-card.svelte-1qg2qyu.svelte-1qg2qyu{display:flex;flex-direction:column;border:1px solid color-mix(in oklch,var(--color-base-content, #1f2937) 12%,transparent);border-radius:6px;overflow:hidden;background:var(--color-base-200, #f7f7f7)}.tc-thumb.svelte-1qg2qyu.svelte-1qg2qyu{position:relative;height:150px;cursor:zoom-in;display:flex;align-items:center;justify-content:center;overflow:hidden;background:var(--color-base-300, #ededed)}.tc-thumb.svelte-1qg2qyu img.svelte-1qg2qyu{max-width:100%;max-height:100%;object-fit:contain}.tc-noimg.svelte-1qg2qyu.svelte-1qg2qyu{font-size:40px;opacity:.3}.tc-zoom.svelte-1qg2qyu.svelte-1qg2qyu{position:absolute;right:6px;bottom:6px;font-size:11px;padding:2px 6px;border-radius:4px;background:#00000080;color:#fff;opacity:0;transition:opacity .15s}.tc-thumb.svelte-1qg2qyu:hover .tc-zoom.svelte-1qg2qyu{opacity:1}.tc-meta.svelte-1qg2qyu.svelte-1qg2qyu{padding:8px 8px 4px;flex:1}.tc-name.svelte-1qg2qyu.svelte-1qg2qyu{font-size:13px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tc-tags.svelte-1qg2qyu.svelte-1qg2qyu{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.tc-tag.svelte-1qg2qyu.svelte-1qg2qyu{font-size:10px;line-height:1;padding:2px 5px;border-radius:3px;background:color-mix(in oklch,var(--color-primary, #409eff) 20%,transparent);color:var(--color-primary, #409eff)}.tc-tag.rec.svelte-1qg2qyu.svelte-1qg2qyu{background:color-mix(in oklch,#f59e0b 25%,transparent);color:#b45309}.tc-tag.paid.svelte-1qg2qyu.svelte-1qg2qyu{background:color-mix(in oklch,#ef4444 20%,transparent);color:#dc2626}.tc-tag.plain.svelte-1qg2qyu.svelte-1qg2qyu{background:color-mix(in oklch,var(--color-base-content, #1f2937) 10%,transparent);color:inherit;opacity:.75}.tc-actions.svelte-1qg2qyu.svelte-1qg2qyu{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:0 8px 8px}.tc-stats.svelte-1qg2qyu.svelte-1qg2qyu{display:flex;gap:8px;font-size:11px;opacity:.65;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tc-use.svelte-1qg2qyu.svelte-1qg2qyu{flex:0 0 auto}.svp-cloud-tc-foot.svelte-1qg2qyu.svelte-1qg2qyu{display:flex;align-items:center;justify-content:center;gap:12px;padding-top:8px;border-top:1px solid color-mix(in oklch,var(--color-base-content, #1f2937) 12%,transparent)}.tc-page.svelte-1qg2qyu.svelte-1qg2qyu{font-size:12px;opacity:.75}.svp-cloud-tc-preview.svelte-1qg2qyu.svelte-1qg2qyu{position:fixed;inset:0;z-index:10000;display:flex;align-items:center;justify-content:center;background:#000c;cursor:zoom-out}.svp-cloud-tc-preview.svelte-1qg2qyu img.svelte-1qg2qyu{max-width:92vw;max-height:92vh;object-fit:contain}.svp-cloud-tc-preview-close.svelte-1qg2qyu.svelte-1qg2qyu{position:absolute;top:16px;right:16px;border:none;background:transparent;color:#fff;font-size:24px;cursor:pointer}.print-options.svelte-ye0rpk.svelte-ye0rpk{min-width:0;margin:16px 0;padding:12px;border:1px solid color-mix(in oklch,var(--color-base-content) 12%,transparent);border-radius:8px}legend.svelte-ye0rpk.svelte-ye0rpk{padding:0 6px;font-size:13px;font-weight:600}.options-grid.svelte-ye0rpk.svelte-ye0rpk{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}.options-grid.svelte-ye0rpk label.svelte-ye0rpk,.extra-label.svelte-ye0rpk.svelte-ye0rpk{display:flex;flex-direction:column;gap:6px;min-width:0;font-size:12px}.options-grid.svelte-ye0rpk input.svelte-ye0rpk,.options-grid.svelte-ye0rpk select.svelte-ye0rpk{width:100%;min-width:0;box-sizing:border-box}.options-checks.svelte-ye0rpk.svelte-ye0rpk{display:flex;flex-wrap:wrap;gap:12px;margin:14px 0;font-size:12px}.options-checks.svelte-ye0rpk label.svelte-ye0rpk{display:flex;align-items:center;gap:4px}summary.svelte-ye0rpk.svelte-ye0rpk{cursor:pointer;font-size:12px}.extra-label.svelte-ye0rpk.svelte-ye0rpk{margin-top:10px}p.svelte-ye0rpk.svelte-ye0rpk{font-size:11px;opacity:.6;line-height:1.6;margin-bottom:0}.cloud-layout.svelte-1v5czrr.svelte-1v5czrr{display:flex;gap:12px;flex:1;min-height:0;overflow:hidden}.cloud-sidebar.svelte-1v5czrr.svelte-1v5czrr{width:130px;flex-shrink:0;height:100%;overflow-y:auto;display:flex;flex-direction:column;gap:2px;padding:4px 10px 4px 0;border-right:1px solid color-mix(in oklch,var(--color-base-content) 12%,transparent)}.cloud-status-bar.svelte-1v5czrr.svelte-1v5czrr{display:flex;align-items:center;gap:6px;padding:6px 8px;margin-bottom:8px;border-radius:6px;background-color:color-mix(in oklch,var(--color-base-content) 5%,transparent);font-size:12px}.cloud-status-dot.svelte-1v5czrr.svelte-1v5czrr{width:8px;height:8px;border-radius:50%;flex-shrink:0;display:inline-block}.cloud-status-dot.dot-on.svelte-1v5czrr.svelte-1v5czrr{background-color:var(--color-success, #22c55e);box-shadow:0 0 4px var(--color-success, #22c55e)}.cloud-status-dot.dot-off.svelte-1v5czrr.svelte-1v5czrr{background-color:var(--color-error, #ef4444)}.cloud-status-text.svelte-1v5czrr.svelte-1v5czrr{color:color-mix(in oklch,var(--color-base-content) 80%,transparent)}.cloud-nav-item.svelte-1v5czrr.svelte-1v5czrr{display:flex;align-items:center;gap:6px;padding:8px 10px;border:none;background:transparent;color:color-mix(in oklch,var(--color-base-content) 65%,transparent);font-size:13px;cursor:pointer;border-radius:6px;transition:background-color .15s ease,color .15s ease;text-align:left}.cloud-nav-item.svelte-1v5czrr.svelte-1v5czrr:hover{background-color:color-mix(in oklch,var(--color-base-content) 6%,transparent);color:var(--color-base-content)}.cloud-nav-active.svelte-1v5czrr.svelte-1v5czrr{background-color:color-mix(in oklch,var(--color-primary, #409eff) 10%,transparent);color:var(--color-primary, #409eff);font-weight:600}.cloud-content.svelte-1v5czrr.svelte-1v5czrr{flex:1;min-width:0;min-height:0;overflow-y:auto;padding:4px 8px 4px 4px}.svp-spin.svelte-1v5czrr.svelte-1v5czrr{animation:svelte-1v5czrr-cloud-spin .8s linear infinite;display:inline-block}@keyframes svelte-1v5czrr-cloud-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.cloud-client-box.svelte-1v5czrr.svelte-1v5czrr{display:flex;align-items:center;gap:10px;padding:10px 12px;margin-bottom:12px;border-radius:8px;border:1px solid color-mix(in oklch,var(--color-primary) 20%,transparent);background-color:color-mix(in oklch,var(--color-primary) 4%,transparent)}.cloud-client-box.svelte-1v5czrr>.svicon.svelte-1v5czrr{font-size:18px;color:var(--color-primary, #409eff)}.cloud-client-info.svelte-1v5czrr.svelte-1v5czrr{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.cloud-client-name.svelte-1v5czrr.svelte-1v5czrr{font-size:13px;font-weight:600}.cloud-client-id.svelte-1v5czrr.svelte-1v5czrr{font-size:11px;opacity:.6}.cloud-user-box.svelte-1v5czrr.svelte-1v5czrr{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:8px;background-color:color-mix(in oklch,var(--color-base-content) 4%,transparent);border:1px solid color-mix(in oklch,var(--color-base-content) 8%,transparent)}.cloud-avatar.svelte-1v5czrr.svelte-1v5czrr,.cloud-avatar-icon.svelte-1v5czrr.svelte-1v5czrr{width:36px;height:36px;border-radius:50%;flex-shrink:0;object-fit:cover}.cloud-avatar-icon.svelte-1v5czrr.svelte-1v5czrr{display:flex;align-items:center;justify-content:center;font-size:20px;background-color:color-mix(in oklch,var(--color-primary) 15%,transparent);color:var(--color-primary, #409eff)}.cloud-user-info.svelte-1v5czrr.svelte-1v5czrr{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.cloud-user-name.svelte-1v5czrr.svelte-1v5czrr{font-size:13px;font-weight:600}.cloud-user-sub.svelte-1v5czrr.svelte-1v5czrr{font-size:11px;opacity:.6}.cloud-login-box.svelte-1v5czrr.svelte-1v5czrr{padding:4px 0}.cloud-provider-tabs.svelte-1v5czrr.svelte-1v5czrr{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}.cloud-provider-tab.svelte-1v5czrr.svelte-1v5czrr{padding:4px 10px;font-size:12px;cursor:pointer;border-radius:6px;border:1px solid color-mix(in oklch,var(--color-base-content) 15%,transparent);background:transparent;color:color-mix(in oklch,var(--color-base-content) 70%,transparent)}.cloud-provider-tab.svelte-1v5czrr.svelte-1v5czrr:hover:not(:disabled){border-color:var(--color-primary, #409eff);color:var(--color-primary, #409eff)}.cloud-provider-tab.active.svelte-1v5czrr.svelte-1v5czrr{border-color:var(--color-primary, #409eff);background-color:color-mix(in oklch,var(--color-primary, #409eff) 10%,transparent);color:var(--color-primary, #409eff);font-weight:600}.cloud-provider-tab.svelte-1v5czrr.svelte-1v5czrr:disabled{cursor:not-allowed;opacity:.6}.cloud-provider-warn.svelte-1v5czrr.svelte-1v5czrr{margin-left:2px;color:var(--color-warning, #f59e0b);font-weight:700}.cloud-search-row.svelte-1v5czrr.svelte-1v5czrr{display:flex;gap:8px;align-items:center;margin-bottom:10px}.cloud-tpl-list.svelte-1v5czrr.svelte-1v5czrr{display:flex;flex-direction:column;gap:6px}.cloud-tpl-item.svelte-1v5czrr.svelte-1v5czrr{display:flex;align-items:center;gap:10px;padding:6px 10px;border-radius:6px;border:1px solid color-mix(in oklch,var(--color-base-content) 10%,transparent);background-color:color-mix(in oklch,var(--color-base-content) 3%,transparent)}.cloud-tpl-thumb.svelte-1v5czrr.svelte-1v5czrr{width:40px;height:40px;border-radius:4px;flex-shrink:0;display:flex;align-items:center;justify-content:center;overflow:hidden;background-color:color-mix(in oklch,var(--color-base-content) 8%,transparent)}.cloud-tpl-thumb.svelte-1v5czrr img.svelte-1v5czrr{width:100%;height:100%;object-fit:cover}.cloud-tpl-info.svelte-1v5czrr.svelte-1v5czrr{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.cloud-tpl-name.svelte-1v5czrr.svelte-1v5czrr{font-size:13px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cloud-tpl-meta.svelte-1v5czrr.svelte-1v5czrr{font-size:11px;opacity:.6}.cloud-device-summary.svelte-1v5czrr.svelte-1v5czrr{margin-bottom:10px;font-size:12px;opacity:.6}.cloud-device-list.svelte-1v5czrr.svelte-1v5czrr{display:flex;flex-direction:column;gap:10px}.cloud-device-item.svelte-1v5czrr.svelte-1v5czrr{display:flex;align-items:flex-start;gap:10px;padding:14px;border-radius:8px;border:1px solid color-mix(in oklch,var(--color-base-content) 12%,transparent);font-size:13px;cursor:pointer;transition:border-color .15s,background-color .15s}.cloud-device-item.svelte-1v5czrr.svelte-1v5czrr:hover{border-color:color-mix(in oklch,var(--color-primary, #409eff) 50%,transparent)}.cloud-device-item.svelte-1v5czrr.svelte-1v5czrr:focus-within{outline:2px solid var(--color-primary, #409eff);outline-offset:2px}.cloud-device-item.active.svelte-1v5czrr.svelte-1v5czrr{border-color:var(--color-primary, #409eff);background-color:color-mix(in oklch,var(--color-primary, #409eff) 6%,transparent)}.cloud-device-item.svelte-1v5czrr input.svelte-1v5czrr{margin:5px 0 0;accent-color:var(--color-primary, #409eff)}.cloud-device-icon.svelte-1v5czrr.svelte-1v5czrr{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:32px;height:32px;border-radius:8px;background:color-mix(in oklch,var(--color-base-content) 5%,transparent);font-size:18px}.cloud-device-info.svelte-1v5czrr.svelte-1v5czrr{flex:1;min-width:0;display:flex;flex-direction:column;gap:7px}.cloud-device-heading.svelte-1v5czrr.svelte-1v5czrr{display:flex;align-items:center;gap:8px}.cloud-device-name.svelte-1v5czrr.svelte-1v5czrr{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}.cloud-device-status.svelte-1v5czrr.svelte-1v5czrr{display:inline-flex;align-items:center;flex-shrink:0;gap:5px;padding:3px 7px;border-radius:20px;font-size:11px;color:color-mix(in oklch,var(--color-base-content) 60%,transparent);background:color-mix(in oklch,var(--color-base-content) 6%,transparent)}.cloud-device-status.online.svelte-1v5czrr.svelte-1v5czrr{color:var(--color-success, #22c55e);background:color-mix(in oklch,var(--color-success, #22c55e) 10%,transparent)}.cloud-device-dot.svelte-1v5czrr.svelte-1v5czrr{width:6px;height:6px;border-radius:50%;background:currentColor}.cloud-device-meta.svelte-1v5czrr.svelte-1v5czrr{display:flex;flex-wrap:wrap;gap:4px 12px;font-size:12px;color:color-mix(in oklch,var(--color-base-content) 65%,transparent);overflow-wrap:anywhere}.cloud-device-no-printers.svelte-1v5czrr.svelte-1v5czrr{color:var(--color-warning, #d97706)}.cloud-device-detail.svelte-1v5czrr.svelte-1v5czrr{font-size:11px;opacity:.55;overflow-wrap:anywhere}.cloud-device-detail.svelte-1v5czrr>span.svelte-1v5czrr{font-family:monospace}.cloud-table.svelte-1v5czrr.svelte-1v5czrr{width:100%;border-collapse:collapse;font-size:12px}.cloud-table.svelte-1v5czrr thead th.svelte-1v5czrr{text-align:left;padding:6px 8px;border-bottom:1px solid color-mix(in oklch,var(--color-base-content) 15%,transparent);font-weight:600;opacity:.65;white-space:nowrap}.cloud-table.svelte-1v5czrr td.svelte-1v5czrr{padding:6px 8px;border-bottom:1px solid color-mix(in oklch,var(--color-base-content) 6%,transparent);white-space:nowrap}.cloud-cell-ellipsis.svelte-1v5czrr.svelte-1v5czrr{max-width:140px;overflow:hidden;text-overflow:ellipsis}.cloud-cell-actions.svelte-1v5czrr.svelte-1v5czrr{display:flex;gap:4px}.cloud-kv.svelte-1v5czrr.svelte-1v5czrr{display:grid;grid-template-columns:110px 1fr;gap:6px 10px;font-size:12px;align-items:center;margin-bottom:10px}.cloud-kv.svelte-1v5czrr span.svelte-1v5czrr{opacity:.7}.cloud-kv.svelte-1v5czrr code.svelte-1v5czrr{font-size:12px;background:color-mix(in oklch,var(--color-base-content) 8%,transparent);padding:2px 6px;border-radius:4px;word-break:break-all}.cloud-checkbox-label.svelte-1v5czrr.svelte-1v5czrr{display:flex;align-items:center;gap:4px;font-size:13px;cursor:pointer}.cloud-loading.svelte-1v5czrr.svelte-1v5czrr{padding:16px;text-align:center;font-size:13px;opacity:.6}.cloud-msg.svelte-1v5czrr.svelte-1v5czrr{display:flex;align-items:center;gap:6px;font-size:12px;padding:6px 10px;border-radius:6px;margin-top:10px}.cloud-msg.msg-success.svelte-1v5czrr.svelte-1v5czrr{color:var(--color-success, #22c55e);background-color:color-mix(in oklch,var(--color-success, #22c55e) 8%,transparent)}.cloud-msg.msg-error.svelte-1v5czrr.svelte-1v5czrr{color:var(--color-error, #ef4444);background-color:color-mix(in oklch,var(--color-error, #ef4444) 8%,transparent)}.cloud-output.svelte-1v5czrr.svelte-1v5czrr{font-size:12px;max-height:240px;overflow:auto;padding:8px;margin-top:10px;border-radius:4px;background:color-mix(in oklch,var(--color-base-content) 6%,transparent);white-space:pre-wrap;word-break:break-all}.cloud-code.svelte-1v5czrr.svelte-1v5czrr{font-family:monospace;font-size:12px;padding:1px 5px;border-radius:4px;background-color:color-mix(in oklch,var(--color-base-content) 10%,transparent)}.cloud-render-frame.svelte-1v5czrr.svelte-1v5czrr{width:100%;height:420px;margin-top:10px;border:1px solid color-mix(in oklch,var(--color-base-content) 15%,transparent);border-radius:6px;background:#fff}.cloud-render-img.svelte-1v5czrr.svelte-1v5czrr{display:block;max-width:100%;max-height:420px;margin-top:10px;border:1px solid color-mix(in oklch,var(--color-base-content) 15%,transparent);border-radius:6px}.svp-badge.badge-on.svelte-1v5czrr.svelte-1v5czrr{color:var(--color-success, #22c55e);background-color:color-mix(in oklch,var(--color-success, #22c55e) 12%,transparent)}@media (max-width: 768px){.cloud-sidebar.svelte-1v5czrr.svelte-1v5czrr{width:80px}}
@@ -0,0 +1,257 @@
1
+ import type { AuthConfig, AuthProviderType, CloudTokenStorage } from "./lib/auth/types";
2
+ export interface ApiEnvelope<T = any> {
3
+ code: number;
4
+ msg?: string;
5
+ message?: string;
6
+ data: T;
7
+ isOk?: boolean;
8
+ statusCode?: number;
9
+ }
10
+ export type CloudRequestAdapter = (config: {
11
+ url: string;
12
+ method: string;
13
+ headers: Record<string, string>;
14
+ body?: any;
15
+ }) => Promise<ApiEnvelope>;
16
+ export interface OAuthTokenResult {
17
+ accessToken: string;
18
+ refreshToken?: string;
19
+ scope?: string[];
20
+ token_type?: string;
21
+ }
22
+ export interface OAuthClientInfo {
23
+ client_id: string;
24
+ client_name: string;
25
+ client_icon?: string | null;
26
+ require_consent?: boolean;
27
+ client_type?: number;
28
+ scopes?: Array<{
29
+ scope: string;
30
+ label?: string;
31
+ }>;
32
+ }
33
+ export type OAuthAuthorizeMode = "iframe" | "popup" | "page" | "custom";
34
+ export interface OAuthConfig {
35
+ authorizeOrigin: string;
36
+ mode?: OAuthAuthorizeMode;
37
+ authorize?: (url: string, state: string) => Promise<string>;
38
+ clientId: string;
39
+ clientSecret?: string;
40
+ redirectUri?: string;
41
+ scope?: string[] | string;
42
+ exchangeToken?: (code: string, state: string) => Promise<OAuthTokenResult>;
43
+ getProfileUrl?: string;
44
+ }
45
+ export interface CloudAuthProviderInfo {
46
+ id: string;
47
+ label: string;
48
+ canLogin: boolean;
49
+ }
50
+ export interface CloudAuthAPI {
51
+ readonly type: string;
52
+ readonly label: string;
53
+ readonly providers: CloudAuthProviderInfo[];
54
+ readonly activeId: string;
55
+ switchProvider(id: string): Promise<void>;
56
+ canLogin(): boolean;
57
+ isLoggedIn(): boolean;
58
+ getToken(): string | null;
59
+ login(): Promise<OAuthTokenResult>;
60
+ logout(): Promise<void>;
61
+ getUser(): Promise<any>;
62
+ getClientInfo(): Promise<OAuthClientInfo | null>;
63
+ onChange(fn: (token: OAuthTokenResult | null) => void): () => void;
64
+ }
65
+ export interface RenderOptions {
66
+ template?: any;
67
+ template_id?: number | string;
68
+ print_data?: any;
69
+ options?: Record<string, any>;
70
+ renderer_id?: number | string;
71
+ type?: "pdf" | "img" | "html";
72
+ sync?: boolean;
73
+ }
74
+ export interface RenderTask {
75
+ task_id: string | number;
76
+ status?: number | string;
77
+ file_url?: string;
78
+ file_path?: string;
79
+ ext?: string;
80
+ file_size?: number;
81
+ render_ms?: number;
82
+ total_ms?: number;
83
+ [key: string]: any;
84
+ }
85
+ export interface CloudDevice {
86
+ id?: number | string;
87
+ device_id?: string;
88
+ device_name?: string;
89
+ remark?: string;
90
+ status?: number;
91
+ [key: string]: any;
92
+ client_version?: string;
93
+ platform?: string;
94
+ arch?: string;
95
+ last_ip?: string;
96
+ online?: boolean;
97
+ socket_online?: boolean;
98
+ last_heartbeat_time?: string;
99
+ printer_count?: number;
100
+ member_id?: number | string;
101
+ }
102
+ export interface CloudPrinter {
103
+ name: string;
104
+ displayName?: string | null;
105
+ status?: number;
106
+ isDefault?: boolean;
107
+ isOk?: boolean;
108
+ disabled?: boolean;
109
+ }
110
+ export interface CloudJob {
111
+ id?: number | string;
112
+ job_id?: string;
113
+ status?: number;
114
+ device_id?: string;
115
+ [key: string]: any;
116
+ }
117
+ export interface CloudPrintOptions {
118
+ device_id: string;
119
+ template_id?: number | string;
120
+ template_data?: any;
121
+ preview_data?: any;
122
+ print_type?: string;
123
+ print_options?: string | Record<string, any>;
124
+ remark?: string;
125
+ }
126
+ export interface TransitTicket {
127
+ ticket: string;
128
+ expires_in?: number;
129
+ namespace?: string;
130
+ }
131
+ export interface TransitClientInfo {
132
+ clientId: string;
133
+ clientType?: string;
134
+ ip?: string;
135
+ connectedAt?: string;
136
+ hostname?: string;
137
+ platform?: string;
138
+ printerList?: any[];
139
+ printerCount?: number;
140
+ [key: string]: any;
141
+ }
142
+ export interface TransitPrintOptions {
143
+ clientId?: string;
144
+ printer?: string;
145
+ template?: any;
146
+ preview_data?: any;
147
+ print_type?: string;
148
+ print_options?: string | Record<string, any>;
149
+ }
150
+ export interface PageResult<T = any> {
151
+ list: T[];
152
+ total: number;
153
+ page?: number;
154
+ pageSize?: number;
155
+ }
156
+ export interface TemplateItem {
157
+ template_id: number;
158
+ template_name: string;
159
+ preview_img?: string | null;
160
+ category_id?: number | null;
161
+ industry_id?: number | null;
162
+ category_name?: string | null;
163
+ industry_name?: string | null;
164
+ template_type?: number;
165
+ member_id?: number | null;
166
+ is_free?: boolean;
167
+ price?: number;
168
+ status?: number;
169
+ view_cnt?: number;
170
+ use_cnt?: number;
171
+ share_cnt?: number;
172
+ fav_cnt?: number;
173
+ is_recommend?: boolean;
174
+ created_time?: string;
175
+ category?: CategoryItem | null;
176
+ industry?: IndustryItem | null;
177
+ [key: string]: any;
178
+ }
179
+ export interface CategoryItem {
180
+ category_id: number;
181
+ parent_id?: number | null;
182
+ category_name: string;
183
+ category_img?: string | null;
184
+ category_sort?: number;
185
+ industry_id?: number | null;
186
+ industry_name?: string | null;
187
+ status?: number;
188
+ children?: CategoryItem[];
189
+ [key: string]: any;
190
+ }
191
+ export interface IndustryItem {
192
+ industry_id: number;
193
+ industry_name: string;
194
+ industry_code?: string;
195
+ industry_img?: string | null;
196
+ industry_sort?: number;
197
+ status?: number;
198
+ [key: string]: any;
199
+ }
200
+ export interface TemplateQuery {
201
+ keyword?: string;
202
+ category_id?: number | string;
203
+ industry_id?: number | string;
204
+ template_type?: string;
205
+ is_free?: boolean | number;
206
+ is_recommend?: boolean | number;
207
+ page?: number;
208
+ pageSize?: number;
209
+ }
210
+ export interface TemplateCenterMenuConfig {
211
+ enable?: boolean;
212
+ menuOrder?: number;
213
+ menuTitle?: string;
214
+ icon?: string;
215
+ }
216
+ export interface PluginConfig {
217
+ host?: string;
218
+ auth?: AuthConfig | AuthConfig[];
219
+ defaultAuth?: AuthProviderType;
220
+ autoLogin?: boolean;
221
+ storage?: CloudTokenStorage;
222
+ storageKey?: string;
223
+ enableSettingsTab?: boolean;
224
+ settingsTabSort?: number;
225
+ settingsTabShowConfig?: boolean;
226
+ templateCenter?: TemplateCenterMenuConfig;
227
+ templateCenterPageSize?: number;
228
+ requestAdapter?: CloudRequestAdapter;
229
+ }
230
+ export interface TemplateCenterAPI {
231
+ show: () => void;
232
+ hide: () => void;
233
+ toggle: () => void;
234
+ isOpen: () => boolean;
235
+ list: (query?: TemplateQuery) => Promise<PageResult<TemplateItem>>;
236
+ }
237
+ export interface CloudAPI {
238
+ render: (opts?: RenderOptions) => Promise<RenderTask>;
239
+ getRenderTask: (id: string | number) => Promise<RenderTask>;
240
+ cloudPrint: (opts: CloudPrintOptions) => Promise<CloudJob>;
241
+ getDevices: () => Promise<CloudDevice[]>;
242
+ getDevicePrinters: (deviceId: string) => Promise<CloudPrinter[]>;
243
+ getJobs: (params?: Record<string, any>) => Promise<PageResult<CloudJob>>;
244
+ cancelJob: (id: string | number) => Promise<any>;
245
+ retryJob: (id: string | number) => Promise<any>;
246
+ transitPrint: (opts?: TransitPrintOptions) => Promise<any>;
247
+ getTransitClients: () => Promise<TransitClientInfo[]>;
248
+ getTransitPrinters: (clientId?: string) => Promise<any[]>;
249
+ applyTemplate: (item: TemplateItem) => Promise<{
250
+ template_data: any;
251
+ preview_data: any;
252
+ }>;
253
+ useRandomTemplate: (query?: TemplateQuery) => Promise<TemplateItem>;
254
+ templateCenter: TemplateCenterAPI;
255
+ auth: CloudAuthAPI;
256
+ config: PluginConfig;
257
+ }
package/package.json CHANGED
@@ -1,6 +1,56 @@
1
1
  {
2
2
  "name": "@sv-print/plugin-cloud",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.1",
4
+ "description": "sv-print plugin: cloud (pluggable auth / server render / cloud print / transit / template center)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "svelte": "./dist/index.mjs",
8
+ "module": "./dist/index.mjs",
9
+ "types": "./dist/index.d.ts",
10
+ "jsdelivr": "./dist/index.umd.js",
11
+ "unpkg": "./dist/index.umd.js",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.mjs",
16
+ "require": "./dist/index.umd.js"
17
+ },
18
+ "./dist/style.css": {
19
+ "import": "./dist/style.css",
20
+ "require": "./dist/style.css"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "scripts": {
27
+ "build": "vite build && node scripts/emit-dts.js",
28
+ "build-browserify": "vite build --mode=browserify && node scripts/emit-dts.js",
29
+ "pub": "pnpm build && npm --registry https://registry.npmjs.org/ publish --access public",
30
+ "pub-beta": "pnpm build && pnpm --registry https://registry.npmjs.org/ publish --access public --tag beta"
31
+ },
32
+ "keywords": [
33
+ "sv-print",
34
+ "hiprint",
35
+ "cloud",
36
+ "oauth",
37
+ "template-center"
38
+ ],
39
+ "author": "CcSimple",
40
+ "license": "MIT",
41
+ "devDependencies": {
42
+ "sv-print": "^0.2.26",
43
+ "typescript": "^5.9.3",
44
+ "vite": "^5.4.11",
45
+ "@sveltejs/vite-plugin-svelte": "2.0.2",
46
+ "@tsconfig/svelte": "^3.0.0",
47
+ "interactjs": "^1.10.0",
48
+ "sass": "^1.53.0",
49
+ "svelte": "^3.55.0",
50
+ "svelte-preprocess": "^5.1.4",
51
+ "svelte2tsx": "^0.5.12"
52
+ },
53
+ "peerDependencies": {
54
+ "sv-print": ">=0.2.26 <0.3.0-0"
55
+ }
56
+ }