fakelab 0.0.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.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # FAKELAB
package/bin/run.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import "../lib/cli.js";
package/lib/cli.js ADDED
@@ -0,0 +1 @@
1
+ import {Command}from'commander';import w from'express';import q from'cors';import F from'path';import {fileURLToPath}from'url';import {bundleRequire}from'bundle-require';import O from'joycon';import'fast-glob';import I from'fs-extra';import'fs/promises';import u from'picocolors';import $ from'express-ejs-layouts';import B from'http';import'ejs';import U from'qs';import h from'zod';import {Project}from'ts-morph';import {v4}from'uuid';import J from'figlet';var c=class t{static prefix(e){let r=new Date().toLocaleTimeString();return {info:u.blue,warn:u.yellow,error:u.red,success:u.green,debug:u.magenta}[e](`[${r}] FAKELAB_${e.toUpperCase()}`)}static log(e,r,...s){let o=u.white,n=t.prefix(e);(e==="error"?console.error:e==="warn"?console.warn:console.log)(n,o(r),...s);}static info(e,...r){this.log("info",e,...r);}static warn(e,...r){this.log("warn",e,...r);}static error(e,...r){this.log("error",e,...r);}static success(e,...r){this.log("success",e,...r);}};async function k(){try{let e=await new O().resolve({files:["fakelab.config.ts"]});return e||(c.error("No fakelab config file is detected."),process.exit(1)),(await bundleRequire({filepath:e})).mod.default}catch{c.error("Could not load the config file."),process.exit(1);}}var g=class{constructor(e){this.faker=e;}JSDOC_FAKER_FIELD="faker";FAKER_TAG_REGEX=/^([a-zA-Z0-9._]+)(?:\((.*)\))?$/;boolMapping={true:true,false:false};string(e){return this.execute(e,this.faker.word.noun)}int(e){return this.execute(e,this.faker.number.int)}bool(e){return this.execute(e,this.faker.datatype.boolean)}bigInt(e){return this.execute(e,this.faker.number.bigInt)}litbool(e){return this.boolMapping[e]}async object(e,r){let s={};return await Promise.all(e.map(async o=>{let n=o.getTypeAtLocation(o.getValueDeclarationOrThrow());s[o.getName()]=await r(n,this,this.readJSDocTags(o));})),s}async union(e){let r=await Promise.all(e);return r[Math.floor(Math.random()*r.length)]}async intersection(e){let r=await Promise.all(e);return r[Math.floor(Math.random()*r.length)]}evalArgs(e){if(!(!e||!e.trim()))return Function(`"use strict"; return (${e});`)()}readJSDocTags(e){let r=e.getJsDocTags().filter(s=>s.getName()===this.JSDOC_FAKER_FIELD);return r.length===0?[]:r.map(s=>{let[o]=s.getText();if(!o)return;let n=o.text.trim().match(this.FAKER_TAG_REGEX);if(!n)return;let[,i,a]=n,f=this.evalArgs(a);return {path:i,args:f}})}execute(e,r){if(!e)return r();let s=e.path.split("."),o=this.faker;for(let n of s)o=o[n],o||(c.error("Invalid faker module path:",e.path),process.exit(1));typeof o!="function"&&(c.error("Unresolvable faker function.",e.path),process.exit(1));try{return e.args?o(e.args):o()}catch{return c.error("Passed invalid arguments to faker function."),o()}}};var d=class{constructor(e){this.files=e;let s=new Project({tsConfigFilePath:"tsconfig.json"}).addSourceFilesAtPaths(e);this.__targets=s.flatMap(o=>o.getInterfaces());}__targets;async run(e){return await e()}entities(){return new Map(this.__targets.map(e=>[e.getName().toLowerCase(),e.getType()]))}async loadFaker(e){let{faker:r}=await import(`@faker-js/faker/locale/${e.locale}`);return r}};async function p(t,e,r=[],s=0){if(t.isString())return e.string(r[s]);if(t.isNumber())return e.int(r[s]);if(t.isBoolean())return e.bool(r[s]);if(t.isBigInt())return e.bigInt(r[s]);if(t.isBooleanLiteral())return e.litbool(t.getText());if(t.isLiteral())return t.getLiteralValue();if(!t.isUndefined()){if(t.isUnion()){let o=t.getUnionTypes();return await e.union(o.map((n,i)=>p(n,e,r,i)))}if(t.isIntersection()){let o=t.getIntersectionTypes();return await e.intersection(o.map((n,i)=>p(n,e,r,i)))}if(t.isArray()){let o=t.getArrayElementTypeOrThrow();return [await p(o,e,r,s)]}if(t.isObject()){let o=t.getProperties();return await e.object(o,(n,i,a)=>p(n,i,a,s))}return null}}function _({each:t}){return {resolve:async r=>await Promise.all(Array.from({length:r},(s,o)=>t(o)))}}function R(t,e){return t==="uuid"?v4():e+1}function j(t,e,r){return async s=>{let o=await p(t,e);return r.uid&&typeof o=="object"?{[r.uid]:R(r.s,s),...o}:o}}async function x(t){let e=new d(t.files),r=await e.loadFaker(t.fakerOptions),s=new g(r),o=e.entities();async function n(i,a){let f=_({each:j(i,s,a)}),l=await(a.count?f.resolve(parseInt(a.count)):p(i,s)),m=JSON.stringify(l,null,2);return {data:l,json:m}}return {entities:o,forge:n}}var N=fileURLToPath(import.meta.url),G=F.dirname(N),T=I.readJSONSync(F.join(G,"../package.json")),y=class{constructor(e,r){this.router=e;this.config=r;this.prefix=this.config.serverOptions.pathPrefix;}prefix;get querySchema(){return h.object({count:h.string().optional(),uid:h.string().optional(),s:h.string().optional()})}async handleQueries(e){let{success:r,data:s,error:o}=await this.querySchema.safeParseAsync(e.query);return r?s:(c.warn(o.message),{})}async register(){let{entities:e,forge:r}=await x(this.config);this.router.get("/",(s,o)=>{let n=s.path;o.render("index",{currentPath:n,entities:e,version:T.version});}),this.router.get("/:name",async(s,o)=>{let n=`${s.protocol}://${s.host}/`,i=s.path,a=s.params.name,f=await this.handleQueries(s),l=U.stringify(f,{addQueryPrefix:true}),m=e.get(a.toLowerCase());if(m){let{json:P}=await r(m,f);o.render("preview",{name:a,currentPath:i,address:n,search:l,json:P,entities:e,version:T.version,prefix:this.prefix});}else o.redirect("/");}),this.router.get(`/${this.prefix}/:name`,async(s,o)=>{try{let n=s.params.name,i=await this.handleQueries(s),a=e.get(n.toLowerCase());if(a){let{data:f}=await r(a,i);o.status(200).json(f);}else o.status(400).json({message:"The requested interface is not found"});}catch(n){o.status(500).send(n);}});}};var K=fileURLToPath(import.meta.url),E=F.dirname(K);function X(t,e){let r=e.serverOptions.port;t.listen(r,"localhost",async()=>{c.info(`Server: http://localhost:${r}`),console.log(await J.text("FAKELAB"));});}function z(t,e,r){e.setHeader("x-powered-by","fakelab"),r();}function Q(t){t.disable("x-powered-by"),t.use(w.json()),t.use(q({methods:"GET"})),t.use(w.static(E+"/public")),t.use(z);}function V(t){t.set("views",F.join(E,"views")),t.set("view engine","ejs"),t.use($),t.set("layout","layouts/main");}async function L(t){let e=w(),r=w.Router(),s=B.createServer(e);Q(e),V(e),await new y(r,t).register(),e.use(r),X(s,t);}var v=new Command;v.name("falekab").description("CLI to generate mock data").version("0.0.0");v.command("serve").description("start server").action(async()=>{let t=await k();L(t);});v.parse();
package/lib/main.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ type FakerLocale = "af" | "ar" | "az" | "bn" | "cs" | "cy" | "da" | "de" | "dv" | "el" | "en" | "eo" | "es" | "fa" | "fi" | "fr" | "he" | "hr" | "hu" | "hy" | "id" | "it" | "ja" | "ka" | "ko" | "ku" | "lv" | "mk" | "nb" | "ne" | "nl" | "pl" | "pt" | "ro";
2
+
3
+ type ServerOptions = {
4
+ /**
5
+ * @default 5200
6
+ */
7
+ port?: number;
8
+ /**
9
+ * @default `api`
10
+ */
11
+ pathPrefix?: string;
12
+ };
13
+ type FakerEngineOptions = {
14
+ locale?: FakerLocale;
15
+ };
16
+ type ConfigOptions = {
17
+ sourcePath: string;
18
+ server?: ServerOptions;
19
+ faker?: FakerEngineOptions;
20
+ };
21
+ declare function defineConfig(options: ConfigOptions): Promise<{
22
+ files: string[];
23
+ serverOptions: Required<ServerOptions>;
24
+ fakerOptions: Required<FakerEngineOptions>;
25
+ }>;
26
+
27
+ export { defineConfig };
package/lib/main.js ADDED
@@ -0,0 +1 @@
1
+ import'bundle-require';import'joycon';import u from'fast-glob';import g from'fs-extra';import p from'path';import {stat,access,constants}from'fs/promises';import i from'picocolors';var s=class{static PREFIX="api";static PORT=5200;static DEFAULT_LOCALE="en";static locale(){let e=Intl.DateTimeFormat().resolvedOptions().locale;if(!e)return this.DEFAULT_LOCALE;let[t]=e.split("-");return t.toLowerCase()}};var o=class r{static prefix(e){let t=new Date().toLocaleTimeString();return {info:i.blue,warn:i.yellow,error:i.red,success:i.green,debug:i.magenta}[e](`[${t}] FAKELAB_${e.toUpperCase()}`)}static log(e,t,...n){let a=i.white,l=r.prefix(e);(e==="error"?console.error:e==="warn"?console.warn:console.log)(l,a(t),...n);}static info(e,...t){this.log("info",e,...t);}static warn(e,...t){this.log("warn",e,...t);}static error(e,...t){this.log("error",e,...t);}static success(e,...t){this.log("success",e,...t);}};var f=".ts";async function w(r){if(r.endsWith(f))return r;let e=r+f;return await g.exists(e)?e:null}async function h(r){return await u("**/*.ts",{cwd:r,absolute:true,ignore:["**/*.d.ts"]})}async function y(r){let e=await w(r);try{if(e&&(await stat(e)).isFile()){if(await v(e))return o.info("Source:",e),[e];o.info("Could not access to the provided file path %s",p),process.exit(1);}}catch{o.error("The provided source path does not exists."),process.exit(1);}try{if((await stat(r)).isDirectory())return o.info("Source:",r),await h(r)}catch{o.error("The provided source path does not exists."),process.exit(1);}o.error("The provided source path does not exists."),process.exit(1);}async function x(r){let e=p.resolve(r.sourcePath),t=await y(e);t.length===0&&(o.error("No Typescript files found in %s",e),process.exit(1));let n={pathPrefix:r.server?.pathPrefix||s.PREFIX,port:r.server?.port||s.PORT},a={locale:r.faker?.locale||s.locale()};return {files:t,serverOptions:n,fakerOptions:a}}async function v(r){try{return await access(r,constants.R_OK),!0}catch{return false}}export{x as defineConfig};
@@ -0,0 +1,571 @@
1
+ @font-face {
2
+ font-family: inter;
3
+ src: url(/fonts/Inter-Regular.ttf) format(woff);
4
+ width: 400;
5
+ font-style: normal;
6
+ font-display: swap;
7
+ }
8
+
9
+ body {
10
+ font-family: inter;
11
+ box-sizing: border-box;
12
+ margin: 0;
13
+ overflow: hidden;
14
+ height: 100vh;
15
+ }
16
+
17
+ .hljs {
18
+ background: none !important;
19
+ }
20
+
21
+ pre {
22
+ margin: 0;
23
+ }
24
+
25
+ .root {
26
+ display: flex;
27
+ width: 100%;
28
+ height: 100%;
29
+ background: oklch(27.8% 0.033 256.848);
30
+ }
31
+
32
+ .sidebar {
33
+ display: flex;
34
+ flex-direction: column;
35
+ overflow: hidden;
36
+ height: 100%;
37
+ width: 350px;
38
+ min-width: 350px;
39
+ box-shadow: 1px 0px 3px oklch(20.992% 0.03416 263.451 / 0.356);
40
+ }
41
+
42
+ .sidebar .logo {
43
+ height: 65px;
44
+ padding-inline: 16px;
45
+ display: flex;
46
+ align-items: center;
47
+ color: oklch(98.5% 0.002 247.839);
48
+ text-decoration: none;
49
+ }
50
+
51
+ .sidebar .sidebar_docs {
52
+ margin-top: auto;
53
+ padding: 16px;
54
+ display: flex;
55
+ justify-content: space-between;
56
+ align-items: center;
57
+ cursor: pointer;
58
+ text-decoration: none;
59
+ background-color: oklch(37.306% 0.03436 260.191 / 0.26);
60
+ > span {
61
+ color: oklch(98.5% 0.002 247.839);
62
+ font-size: 14px;
63
+ }
64
+ }
65
+
66
+ .sidebar .sidebar_footer {
67
+ margin-top: auto;
68
+ padding: 16px;
69
+ display: flex;
70
+ flex-direction: column;
71
+ gap: 8px;
72
+ }
73
+
74
+ .sidebar_footer span {
75
+ color: oklch(98.463% 0.00181 249.248 / 0.76);
76
+ font-size: 12px;
77
+ }
78
+
79
+ .sidebar .sidebar_content {
80
+ display: flex;
81
+ flex-direction: column;
82
+ flex: 1;
83
+ overflow: hidden;
84
+ padding-block: 16px;
85
+ }
86
+
87
+ .sidebar_content .sidebar_content_leading {
88
+ display: flex;
89
+ gap: 8px;
90
+ align-items: center;
91
+ width: 100%;
92
+ padding: 16px;
93
+ }
94
+
95
+ .sidebar_content .sidebar_content_list {
96
+ padding-inline: 16px;
97
+ display: flex;
98
+ flex-direction: column;
99
+ gap: 2px;
100
+ overflow: auto;
101
+ }
102
+
103
+ .sidebar_content_list::-webkit-scrollbar {
104
+ width: 10px;
105
+ }
106
+ .sidebar_content_list::-webkit-scrollbar-track {
107
+ background: oklch(27.8% 0.033 256.848);
108
+ }
109
+ .sidebar_content_list::-webkit-scrollbar-thumb {
110
+ background: hsl(216, 31%, 24%);
111
+ border-radius: 99px;
112
+ }
113
+
114
+ .sidebar_content_list .sidebar_content_list_item {
115
+ padding: 12px 8px;
116
+ border-radius: 4px;
117
+ cursor: pointer;
118
+ transition: all 250ms ease-in-out;
119
+ color: oklch(98.463% 0.00181 249.248 / 0.726);
120
+ text-decoration: none;
121
+ font-size: 14px;
122
+ &:hover {
123
+ color: oklch(98.5% 0.002 247.839);
124
+ }
125
+
126
+ > span {
127
+ user-select: none;
128
+ }
129
+ }
130
+
131
+ .sidebar_content_list_item.active {
132
+ color: oklch(98.5% 0.002 247.839);
133
+ background-color: oklch(37.306% 0.03436 260.191 / 0.26);
134
+ }
135
+
136
+ .sidebar_content_leading .sidebar_content_title {
137
+ color: oklch(98.5% 0.002 247.839);
138
+ font-size: 14px;
139
+ }
140
+
141
+ .sidebar_content_leading .sidebar_content_indicator_icon {
142
+ width: 8px;
143
+ height: 8px;
144
+ border-radius: 99px;
145
+ background: oklch(68.5% 0.169 237.323);
146
+ position: relative;
147
+ &::before {
148
+ content: "";
149
+ position: absolute;
150
+ left: 0;
151
+ top: 0;
152
+ width: 100%;
153
+ height: 100%;
154
+ border-radius: 99px;
155
+ background: oklch(68.5% 0.169 237.323);
156
+ animation: blink 2s infinite ease-in-out;
157
+ transform-origin: center;
158
+ z-index: 1;
159
+ }
160
+ }
161
+
162
+ .main {
163
+ display: flex;
164
+ flex: 1;
165
+ flex-direction: column;
166
+ height: 100%;
167
+ overflow: hidden;
168
+ min-width: 441px;
169
+ }
170
+
171
+ .header {
172
+ flex-basis: 65px;
173
+ border-bottom: 1px solid oklch(21% 0.034 264.665);
174
+ padding-inline: 16px;
175
+ display: flex;
176
+ overflow: hidden;
177
+ align-items: center;
178
+ justify-content: space-between;
179
+ }
180
+
181
+ .header .interface_name {
182
+ font-size: 16px;
183
+ color: oklch(98.463% 0.00181 249.248 / 0.61);
184
+ }
185
+
186
+ .preview {
187
+ background: oklch(21% 0.034 264.665);
188
+ flex: 1;
189
+ display: flex;
190
+ flex-direction: column;
191
+ overflow-y: auto;
192
+ }
193
+
194
+ .preview::-webkit-scrollbar {
195
+ width: 10px;
196
+ }
197
+ .preview::-webkit-scrollbar-track {
198
+ background: oklch(21% 0.034 264.665);
199
+ }
200
+ .preview::-webkit-scrollbar-thumb {
201
+ background: oklch(27.8% 0.033 256.848);
202
+ border-radius: 99px;
203
+ }
204
+
205
+ .preview .preview_toolbar {
206
+ max-height: fit-content;
207
+ flex: 1;
208
+ padding: 16px;
209
+ display: flex;
210
+ align-items: center;
211
+ justify-content: space-between;
212
+ gap: 16px;
213
+ position: sticky;
214
+ top: 0px;
215
+ background-color: oklch(21% 0.034 264.665);
216
+ }
217
+
218
+ .preview_toolbar .data_fetch_address {
219
+ background: oklch(27.8% 0.033 256.848);
220
+ padding-inline: 12px;
221
+ height: 32px;
222
+ display: flex;
223
+ align-items: center;
224
+ gap: 8px;
225
+ border-radius: 4px;
226
+ box-shadow: 0px 0px 2px hsl(220, 43%, 10%);
227
+ min-width: 300px;
228
+ }
229
+
230
+ .preview_toolbar .toolbar_actions {
231
+ background: oklch(27.8% 0.033 256.848);
232
+ height: 32px;
233
+ display: flex;
234
+ align-items: center;
235
+ border-radius: 4px;
236
+ box-shadow: 0px 0px 2px hsl(220, 43%, 10%);
237
+ }
238
+
239
+ .toolbar_actions .toolbar_action_item {
240
+ transition: opacity 250ms ease-in-out;
241
+ height: 100%;
242
+ width: 32px;
243
+ display: flex;
244
+ align-items: center;
245
+ justify-content: center;
246
+ cursor: pointer;
247
+ &:hover > .icon {
248
+ opacity: 1;
249
+ }
250
+ }
251
+
252
+ .preview_toolbar .divider {
253
+ width: 1px;
254
+ height: 12px;
255
+ background-color: hsla(210, 20%, 80%, 0.2);
256
+ }
257
+
258
+ .preview_toolbar .toolbar_setting {
259
+ display: flex;
260
+ align-items: center;
261
+ gap: 8px;
262
+ position: relative;
263
+
264
+ /* > .toolbar_setting_count_input {
265
+ border: 1px solid oklch(98.463% 0.00181 249.248 / 0.171);
266
+ outline: none;
267
+ border-radius: 4px;
268
+ padding-inline: 8px;
269
+ height: 32px;
270
+ color: oklch(98.463% 0.00181 249.248 / 0.801);
271
+ background: transparent;
272
+ font-family: inter;
273
+ } */
274
+ }
275
+ .toolbar_setting .toolbar_setting_option {
276
+ display: flex;
277
+ align-items: center;
278
+ justify-content: center;
279
+ border-radius: 4px;
280
+ background: oklch(27.8% 0.033 256.848);
281
+ box-shadow: 0px 0px 2px hsl(220, 43%, 10%);
282
+ height: 32px;
283
+ width: 32px;
284
+ cursor: pointer;
285
+ transition: opacity 250ms ease-in-out;
286
+ &:hover > .icon {
287
+ opacity: 1;
288
+ }
289
+ }
290
+
291
+ .toolbar_setting .toolbar_setting_overlay {
292
+ display: none;
293
+ position: absolute;
294
+ left: calc(100% + 8px);
295
+ top: 0px;
296
+ width: 300px;
297
+ height: fit-content;
298
+ background: oklch(27.8% 0.033 256.848);
299
+ box-shadow: 0px 0px 2px hsl(220, 43%, 10%);
300
+ border-radius: 4px;
301
+ flex-direction: column;
302
+ gap: 4px;
303
+ z-index: 99;
304
+ padding: 16px;
305
+
306
+ &[data-visible="true"] {
307
+ display: flex;
308
+ }
309
+ }
310
+
311
+ .toolbar_setting_overlay .setting_title {
312
+ color: #fff;
313
+ font-size: 14px;
314
+ display: flex;
315
+ align-items: center;
316
+ }
317
+
318
+ .toolbar_setting_overlay .setting_form {
319
+ display: flex;
320
+ flex-direction: column;
321
+ gap: 20px;
322
+ margin-top: 16px;
323
+ }
324
+ .setting_form .form_input {
325
+ display: flex;
326
+ flex-direction: column;
327
+ gap: 2px;
328
+ &[data-visible="false"] {
329
+ display: none;
330
+ }
331
+ }
332
+
333
+ .setting_form .form_input.inline {
334
+ flex-direction: row;
335
+ justify-content: space-between;
336
+ align-items: center;
337
+ }
338
+
339
+ .setting_form .form_buttons {
340
+ display: flex;
341
+ align-items: center;
342
+ width: 100%;
343
+ gap: 8px;
344
+ margin-top: 8px;
345
+ }
346
+
347
+ .form_buttons .form_apply_btn {
348
+ display: flex;
349
+ flex: 1;
350
+ align-items: center;
351
+ justify-content: center;
352
+ outline: none;
353
+ border: none;
354
+ height: 38px;
355
+ color: #fff;
356
+ background-color: oklch(68.5% 0.169 237.323);
357
+ margin-top: auto;
358
+ border-radius: 4px;
359
+ cursor: pointer;
360
+ font-family: inter;
361
+ transition: background-color 250ms ease-in-out;
362
+ &:hover {
363
+ background-color: oklch(58.8% 0.158 241.966);
364
+ }
365
+ }
366
+
367
+ .form_buttons .form_reset_btn {
368
+ display: flex;
369
+ flex: 1;
370
+ outline: none;
371
+ align-items: center;
372
+ justify-content: center;
373
+ border: none;
374
+ height: 38px;
375
+ color: #fff;
376
+ background-color: hsl(216, 31%, 23%);
377
+ margin-top: auto;
378
+ border-radius: 4px;
379
+ cursor: pointer;
380
+ font-family: inter;
381
+ transition: background-color 250ms ease-in-out;
382
+ &:hover {
383
+ background-color: hsl(216, 31%, 20%);
384
+ }
385
+ }
386
+
387
+ .form_input input {
388
+ border: 1px solid oklch(98.463% 0.00181 249.248 / 0.171);
389
+ outline: none;
390
+ border-radius: 4px;
391
+ padding-inline: 8px;
392
+ height: 32px;
393
+ color: oklch(98.463% 0.00181 249.248 / 0.801);
394
+ background: transparent;
395
+ font-family: inter;
396
+ font-size: 12px;
397
+ }
398
+
399
+ .form_input label {
400
+ font-size: 12px;
401
+ color: #fff;
402
+ }
403
+
404
+ .form_input span {
405
+ font-size: 10px;
406
+ color: oklch(98.463% 0.00181 249.248 / 0.801);
407
+ }
408
+ .data_fetch_address .address {
409
+ font-size: 12px;
410
+ display: flex;
411
+ flex: 1;
412
+ width: 100%;
413
+ align-items: center;
414
+ gap: 8px;
415
+
416
+ > .address_method {
417
+ color: oklch(75% 0.183 55.934);
418
+ font-weight: 500;
419
+ }
420
+ > .address_url {
421
+ color: oklch(98.463% 0.00181 249.248 / 0.801);
422
+ }
423
+ }
424
+
425
+ .preview_toolbar.loading {
426
+ display: none;
427
+ }
428
+
429
+ .preview .nodata {
430
+ display: flex;
431
+ flex: 1;
432
+ justify-content: center;
433
+ align-items: center;
434
+ color: oklch(98.463% 0.00181 249.248 / 0.61);
435
+ font-size: 14px;
436
+ }
437
+
438
+ .preview-loading {
439
+ display: none;
440
+ flex: 1;
441
+ justify-content: center;
442
+ align-items: center;
443
+ flex-direction: column;
444
+ gap: 8px;
445
+ }
446
+ .preview-loading.loading {
447
+ display: flex;
448
+ }
449
+
450
+ .code.loading {
451
+ display: none;
452
+ }
453
+
454
+ .error {
455
+ display: none;
456
+ font-size: 14px;
457
+ color: oklch(50.5% 0.213 27.518);
458
+ }
459
+
460
+ .error.visible {
461
+ display: block;
462
+ }
463
+
464
+ .loader {
465
+ width: 30px;
466
+ height: 30px;
467
+ border: 4px solid oklch(98.463% 0.00181 249.248 / 0.24);
468
+ border-top: 4px solid #f9fafb7c;
469
+ border-radius: 50%;
470
+ display: none;
471
+ box-sizing: border-box;
472
+ animation: rotation 1s linear infinite;
473
+ }
474
+
475
+ .loader.visible {
476
+ display: inline-block;
477
+ }
478
+
479
+ .icon {
480
+ pointer-events: none;
481
+ cursor: pointer;
482
+ opacity: 0.7;
483
+ transition: opacity 250ms ease-in-out;
484
+ &:hover {
485
+ opacity: 1;
486
+ }
487
+ }
488
+
489
+ .icon.pointer_auto {
490
+ pointer-events: auto;
491
+ }
492
+ .switch {
493
+ position: relative;
494
+ display: inline-block;
495
+ width: 28px;
496
+ height: 6px;
497
+ }
498
+
499
+ .switch input {
500
+ opacity: 0;
501
+ width: 0;
502
+ height: 0;
503
+ }
504
+
505
+ .slider {
506
+ position: absolute;
507
+ cursor: pointer;
508
+ top: 0;
509
+ left: 0;
510
+ right: 0;
511
+ bottom: 0;
512
+ background-color: hsl(216, 31%, 25%);
513
+ -webkit-transition: 0.4s;
514
+ transition: 0.4s;
515
+ border-radius: 24px;
516
+ height: 6px;
517
+ }
518
+
519
+ .slider:before {
520
+ position: absolute;
521
+ content: "";
522
+ height: 16px;
523
+ width: 16px;
524
+ left: -1px;
525
+ bottom: -5px;
526
+ background-color: hsl(216, 31%, 32%);
527
+ -webkit-transition: 0.4s;
528
+ transition: 0.4s;
529
+ border-radius: 50%;
530
+ }
531
+
532
+ input:checked + .slider:before {
533
+ -webkit-transform: translateX(13px);
534
+ -ms-transform: translateX(13px);
535
+ transform: translateX(13px);
536
+ background-color: oklch(68.5% 0.169 237.323);
537
+ }
538
+
539
+ .unique_id_hint {
540
+ font-size: 10px;
541
+ color: oklch(98.463% 0.00181 249.248 / 0.801);
542
+ }
543
+
544
+ .unique_strategy {
545
+ margin-top: 8px;
546
+ display: none;
547
+ flex-direction: column;
548
+ gap: 16px;
549
+ &[data-visible="true"] {
550
+ display: flex;
551
+ }
552
+ }
553
+
554
+ @keyframes rotation {
555
+ 0% {
556
+ transform: rotate(0deg);
557
+ }
558
+ 100% {
559
+ transform: rotate(360deg);
560
+ }
561
+ }
562
+ @keyframes blink {
563
+ 0% {
564
+ opacity: 0.8;
565
+ transform: scale(1);
566
+ }
567
+ 100% {
568
+ opacity: 0;
569
+ transform: scale(2.5);
570
+ }
571
+ }
@@ -0,0 +1,93 @@
1
+ pre code.hljs {
2
+ display: block;
3
+ overflow-x: auto;
4
+ padding: 1em;
5
+ }
6
+ code.hljs {
7
+ padding: 3px 5px;
8
+ }
9
+ .hljs {
10
+ background: #1e1e1e;
11
+ color: #dcdcdc;
12
+ }
13
+ .hljs-keyword,
14
+ .hljs-literal,
15
+ .hljs-name,
16
+ .hljs-symbol {
17
+ color: #569cd6;
18
+ }
19
+ .hljs-link {
20
+ color: #569cd6;
21
+ text-decoration: underline;
22
+ }
23
+ .hljs-built_in,
24
+ .hljs-type {
25
+ color: #4ec9b0;
26
+ }
27
+ .hljs-class,
28
+ .hljs-number {
29
+ color: #b8d7a3;
30
+ }
31
+ .hljs-meta .hljs-string,
32
+ .hljs-string {
33
+ color: #d69d85;
34
+ }
35
+ .hljs-regexp,
36
+ .hljs-template-tag {
37
+ color: #9a5334;
38
+ }
39
+ .hljs-formula,
40
+ .hljs-function,
41
+ .hljs-params,
42
+ .hljs-subst,
43
+ .hljs-title {
44
+ color: #dcdcdc;
45
+ }
46
+ .hljs-comment,
47
+ .hljs-quote {
48
+ color: #57a64a;
49
+ font-style: italic;
50
+ }
51
+ .hljs-doctag {
52
+ color: #608b4e;
53
+ }
54
+ .hljs-meta,
55
+ .hljs-meta .hljs-keyword,
56
+ .hljs-tag {
57
+ color: #9b9b9b;
58
+ }
59
+ .hljs-template-variable,
60
+ .hljs-variable {
61
+ color: #bd63c5;
62
+ }
63
+ .hljs-attr,
64
+ .hljs-attribute {
65
+ color: #9cdcfe;
66
+ }
67
+ .hljs-section {
68
+ color: gold;
69
+ }
70
+ .hljs-emphasis {
71
+ font-style: italic;
72
+ }
73
+ .hljs-strong {
74
+ font-weight: 700;
75
+ }
76
+ .hljs-bullet,
77
+ .hljs-selector-attr,
78
+ .hljs-selector-class,
79
+ .hljs-selector-id,
80
+ .hljs-selector-pseudo,
81
+ .hljs-selector-tag {
82
+ color: #d7ba7d;
83
+ }
84
+ .hljs-addition {
85
+ background-color: #144212;
86
+ display: inline-block;
87
+ width: 100%;
88
+ }
89
+ .hljs-deletion {
90
+ background-color: #600;
91
+ display: inline-block;
92
+ width: 100%;
93
+ }