yapin.js-client 0.1.0 → 0.1.4

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,5 +1,5 @@
1
1
  /** The framework version. Kept in step with package.json (a test checks it). */
2
- export const version = '0.1.0';
2
+ export const version = '0.1.4';
3
3
 
4
4
  /**
5
5
  * The plugin API version. Plugins declare the one they were written for (`apiVersion`), and the
@@ -0,0 +1,52 @@
1
+ /**
2
+ * A small built-in icon set, usable anywhere an "icon" option is accepted (page icons, About fields,
3
+ * cards, toasts, dialogs, the welcome and what's new screens…) by name: `icon: 'rocket'`. Each is a
4
+ * plain, stroke-based 24×24 SVG that inherits its colour from CSS (`currentColor`), so it follows
5
+ * whatever text colour it's placed in, in any theme.
6
+ *
7
+ * Anywhere that takes an icon also still takes raw SVG markup, an https/data image URL, or an element;
8
+ * names here are just a shortcut so client apps don't have to carry their own SVGs for common things.
9
+ */
10
+ export const ICONS = Object.freeze({
11
+ sparkles:
12
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v4M12 17v4M3 12h4M17 12h4M6.3 6.3l1.8 1.8M15.9 15.9l1.8 1.8M17.7 6.3l-1.8 1.8M8.1 15.9l-1.8 1.8"/><circle cx="12" cy="12" r="2.1"/></svg>',
13
+ rocket:
14
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 9.5c2-2 3-5 2.6-6.6-1.6-.4-4.6.6-6.6 2.6-1.8 1.8-4.3 5.2-5 7l2.9 3c1.9-.7 5.3-3.2 7-5Z"/><path d="M9 15l-3 3M13.5 6.5l4 4M8 16.5c0 1.5-1 2.5-3.5 3 .5-2.5 1.5-3.5 3-3.5Z"/></svg>',
15
+ puzzle:
16
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M9 4h3a1.5 1.5 0 0 1 0 3 1.5 1.5 0 0 0 0 3h3a1 1 0 0 1 1 1v3a1.5 1.5 0 0 1-3 0 1.5 1.5 0 0 0-3 0v3a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-3a1.5 1.5 0 0 1 0-3 1.5 1.5 0 0 0 0-3V6a1 1 0 0 1 1-1h3V4Z"/></svg>',
17
+ palette:
18
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3a9 9 0 1 0 0 18c1.1 0 2-.9 2-2 0-.5-.2-1-.5-1.3-.3-.4-.5-.8-.5-1.3 0-1.1.9-2 2-2h2a4 4 0 0 0 4-4c0-4.4-4-7.4-9-7.4Z"/><circle cx="7.5" cy="12" r="1.1" fill="currentColor" stroke="none"/><circle cx="9.5" cy="8" r="1.1" fill="currentColor" stroke="none"/><circle cx="14.5" cy="8" r="1.1" fill="currentColor" stroke="none"/><circle cx="16.5" cy="12" r="1.1" fill="currentColor" stroke="none"/></svg>',
19
+ sliders:
20
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h7M15 7h5M4 17h11M19 17h1M9 4.5v5M17 14.5v5"/></svg>',
21
+ info:
22
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5"/><circle cx="12" cy="8" r=".2" fill="currentColor"/></svg>',
23
+ check:
24
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 12.5l5 5 10-11"/></svg>',
25
+ x: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',
26
+ alertTriangle:
27
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4 3 20h18L12 4Z"/><path d="M12 10v4"/><circle cx="12" cy="17" r=".2" fill="currentColor"/></svg>',
28
+ alertCircle:
29
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5v5.5"/><circle cx="12" cy="16.5" r=".2" fill="currentColor"/></svg>',
30
+ chevronRight:
31
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 5l7 7-7 7"/></svg>',
32
+ megaphone:
33
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M3 11v2a2 2 0 0 0 2 2h1l9 4V5l-9 4H5a2 2 0 0 0-2 2Z"/><path d="M15 9.5a3.5 3.5 0 0 1 0 5"/></svg>',
34
+ bell:
35
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M6 10a6 6 0 1 1 12 0c0 3 1 4.5 2 5.5H4c1-1 2-2.5 2-5.5Z"/><path d="M10 19.5a2 2 0 0 0 4 0"/></svg>',
36
+ external:
37
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M9 5H6a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2v-3"/><path d="M13 3h8v8"/><path d="M21 3 10 14"/></svg>',
38
+ heart:
39
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20s-7.5-4.6-9.5-9.3C1.1 7.7 3 4.5 6.4 4.5c2 0 3.4 1.1 4.1 2.3.7-1.2 2.1-2.3 4.1-2.3 3.4 0 5.3 3.2 3.9 6.2C19.5 15.4 12 20 12 20Z"/></svg>',
40
+ copy:
41
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><rect x="8.5" y="8.5" width="11.5" height="11.5" rx="2"/><path d="M15.5 8.5V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7.5a2 2 0 0 0 2 2h2.5"/></svg>',
42
+ folder:
43
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 7a2 2 0 0 1 2-2h4l2 2.5h7a2 2 0 0 1 2 2V17a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2V7Z"/></svg>',
44
+ shield:
45
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l7 3v5c0 5-3.5 8-7 10-3.5-2-7-5-7-10V6l7-3Z"/><path d="M9 12l2 2 4-4.5"/></svg>',
46
+ });
47
+
48
+ /** Looks up a built-in icon by name (case-insensitive). Returns raw SVG markup, or null. */
49
+ export function builtinIcon(name) {
50
+ if (typeof name !== 'string') return null;
51
+ return ICONS[name] ?? ICONS[name.replace(/-([a-z])/g, (_, c) => c.toUpperCase())] ?? null;
52
+ }
package/types/index.d.ts CHANGED
@@ -111,11 +111,42 @@ export interface Config {
111
111
  title?: string;
112
112
  order?: number;
113
113
  icon?: string;
114
+ /** Shown in the header card: a built-in icon name, SVG markup, or an https/data image URL. Default: the name's first letter. */
115
+ logo?: string | null;
114
116
  intro?: string | null;
115
- sections?: Record<string, boolean | { title?: string | null; order?: number }>;
117
+ sections?: Record<string, boolean | { title?: string | null; order?: number; layout?: 'rows' | 'chips' | 'header' }>;
116
118
  fields?: Record<string, false | string | { label?: string; value?: string; href?: string; copy?: boolean | string; code?: boolean; order?: number; hidden?: boolean }>;
117
119
  actions?: Record<string, false>;
118
120
  };
121
+ /** A rounded, animated screen shown the first time the client app runs. `false` turns it off entirely. */
122
+ welcome?:
123
+ | false
124
+ | {
125
+ enabled?: boolean;
126
+ /** A built-in icon name ('sparkles', 'rocket', …), SVG markup, or an https/data image URL. */
127
+ icon?: string;
128
+ /** `{name}` and `{version}` are replaced. */
129
+ title?: string;
130
+ subtitle?: string | null;
131
+ steps?: Array<{ icon?: string; title: string; description?: string }>;
132
+ actionLabel?: string;
133
+ dismissible?: boolean;
134
+ dismissLabel?: string;
135
+ };
136
+ /** Shown once after an update, when `entries` has something for the new version. `false` turns it off entirely. */
137
+ whatsNew?:
138
+ | false
139
+ | {
140
+ enabled?: boolean;
141
+ icon?: string;
142
+ /** `{name}` and `{version}` are replaced. */
143
+ title?: string;
144
+ subtitle?: string | null;
145
+ entries?: Array<{ icon?: string; title: string; description?: string }>;
146
+ actionLabel?: string;
147
+ dismissible?: boolean;
148
+ dismissLabel?: string | null;
149
+ };
119
150
  badges?: {
120
151
  enabled?: boolean;
121
152
  sources?: Array<{ id: string; url: string; name?: string; refresh?: string | number; priority?: number }>;
@@ -153,6 +184,12 @@ export interface Config {
153
184
  company?: string | null;
154
185
  /** A signing command run on the finished .exe, with {file} replaced: 'signtool sign /fd sha256 /a {file}'. */
155
186
  sign?: string | null;
187
+ /** Build a setup wizard with NSIS when makensis is found (default true), false for the browser launcher, or makensis's path. */
188
+ nsis?: boolean | string;
189
+ /** A 164×314 .bmp for the wizard's Welcome and Finish pages; default: the accent colour with the logo. */
190
+ sidebar?: string | null;
191
+ /** A 150×57 .bmp for the top of the wizard's other pages; default: the logo on white. */
192
+ header?: string | null;
156
193
  };
157
194
  };
158
195
  }
@@ -167,20 +167,40 @@ export interface AboutField {
167
167
  hidden?: boolean;
168
168
  }
169
169
 
170
+ export type AboutLayout = 'rows' | 'chips' | 'header';
171
+
170
172
  export interface AboutPage {
171
173
  /** id is '<section>.<name>', like 'git.commit' or 'support.discord'. */
172
174
  set(id: string, field: AboutField): this;
173
175
  get(id: string): (AboutField & { id: string; section: string }) | null;
174
176
  remove(id: string): boolean;
175
177
  fields(): Array<AboutField & { id: string; section: string }>;
176
- section(id: string, options: { title?: string | null; order?: number }): this;
178
+ /** 'rows' (default), 'chips' (compact pills, for links) or 'header' (the card at the top). */
179
+ section(id: string, options: { title?: string | null; order?: number; layout?: AboutLayout }): this;
180
+ sections(): Array<{ id: string; title: string | null; order: number; layout: AboutLayout }>;
177
181
  removeSection(id: string): this;
178
- action(id: string, options: { label: string; run: (client: Client) => unknown; variant?: 'primary' | 'ghost' | 'danger'; order?: number }): this;
182
+ action(id: string, options: { label: string; icon?: string; run: (client: Client) => unknown; variant?: 'primary' | 'ghost' | 'danger'; order?: number }): this;
179
183
  removeAction(id: string): this;
180
184
  /** Everything on the page as text, plus enabled plugins, themes and recent errors. */
181
185
  debugInfo(): string;
182
186
  }
183
187
 
188
+ // ---------- welcome / what's new ----------
189
+
190
+ export interface OnboardingScreen {
191
+ readonly enabled: boolean;
192
+ /** Shows it right now, regardless of whether it's been seen. */
193
+ show(): () => void;
194
+ /** Marks it seen without showing it. */
195
+ markSeen(): void;
196
+ /** Clears the seen flag so it's shown again next start (or call show() now). */
197
+ reset(): void;
198
+ shouldShow(): boolean;
199
+ }
200
+
201
+ export interface Welcome extends OnboardingScreen {}
202
+ export interface WhatsNew extends OnboardingScreen {}
203
+
184
204
  // ---------- themes ----------
185
205
 
186
206
  export interface ThemeVariable {
@@ -647,6 +667,10 @@ export declare class Client {
647
667
  readonly userContent: UserContent;
648
668
  /** null when the client app turned the About page off. */
649
669
  readonly about: AboutPage | null;
670
+ /** null when the client app turned the welcome screen off. */
671
+ readonly welcome: Welcome | null;
672
+ /** null when the client app turned the what's new screen off. */
673
+ readonly whatsNew: WhatsNew | null;
650
674
  reportError(error: unknown, tags?: Record<string, unknown>): void;
651
675
  openExternal(url: string): boolean;
652
676
  stop(): void;