@stacksjs/stx 0.2.354 → 0.2.356
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/chunk-0c49cy69.js +2 -0
- package/dist/chunk-0chkqvs1.js +2 -0
- package/dist/chunk-0d6qgbks.js +2 -0
- package/dist/{chunk-84bhnp6p.js → chunk-0dj2gne3.js} +2 -2
- package/dist/{chunk-57atgbyq.js → chunk-0knxnyq6.js} +1 -1
- package/dist/{chunk-m6dstr44.js → chunk-0smr2xjs.js} +2 -2
- package/dist/{chunk-e4g8wz6t.js → chunk-0t1yyn1d.js} +1 -1
- package/dist/{chunk-xvh1k1a4.js → chunk-19m7hed6.js} +1 -1
- package/dist/{chunk-vhta1be7.js → chunk-1nnza3m6.js} +1 -1
- package/dist/chunk-284kattb.js +2 -0
- package/dist/{chunk-n5657hm3.js → chunk-2gtwha4k.js} +1 -1
- package/dist/{chunk-f5veee11.js → chunk-2s3wvns6.js} +1 -1
- package/dist/chunk-2x3zy811.js +2 -0
- package/dist/chunk-38mpg3kn.js +2 -0
- package/dist/chunk-3eya6sbk.js +2 -0
- package/dist/chunk-3f782ywp.js +2 -0
- package/dist/{chunk-mmnf2pac.js → chunk-3kd0zn9c.js} +2 -2
- package/dist/{chunk-avye7h5s.js → chunk-3kyydhzt.js} +1 -1
- package/dist/{chunk-msq8xvhp.js → chunk-3ssjb8cx.js} +309 -312
- package/dist/{chunk-6r3aavbv.js → chunk-3y8vvkar.js} +2 -2
- package/dist/chunk-4ce5ma6a.js +20 -0
- package/dist/{chunk-8cc4vdkh.js → chunk-4gtsf1xw.js} +1 -1
- package/dist/chunk-4mkqzhfh.js +2 -0
- package/dist/{chunk-xj6bcwqa.js → chunk-5270fyk7.js} +1 -1
- package/dist/{chunk-a1knndrh.js → chunk-57kxjr4t.js} +10 -10
- package/dist/chunk-596cftgk.js +2 -0
- package/dist/{chunk-8bxtvsgm.js → chunk-634gaa9d.js} +1 -1
- package/dist/{chunk-pwh8pbks.js → chunk-6gsgayq3.js} +1 -1
- package/dist/{chunk-a8ghkfh6.js → chunk-6qhatdte.js} +2 -2
- package/dist/{chunk-6zrg2mmc.js → chunk-6yfccnr7.js} +2 -2
- package/dist/{chunk-z23sc9p4.js → chunk-79fj9zem.js} +2 -2
- package/dist/{chunk-2ver2s2y.js → chunk-7hb89n3z.js} +1 -1
- package/dist/{chunk-05zfez2g.js → chunk-7jcntsp4.js} +1 -1
- package/dist/{chunk-nf7k53ap.js → chunk-7kw3grq5.js} +1 -1
- package/dist/chunk-7nf8azjh.js +2 -0
- package/dist/{chunk-g5mhck0r.js → chunk-801bg5d8.js} +2 -2
- package/dist/chunk-8wgsjh65.js +2 -0
- package/dist/{chunk-34f8c48f.js → chunk-8xjasa91.js} +1 -1
- package/dist/{chunk-w5j9tbsk.js → chunk-94dz7hrj.js} +1 -1
- package/dist/{chunk-6h3r8v55.js → chunk-9qdn9y72.js} +1 -1
- package/dist/chunk-a6x0czvr.js +2 -0
- package/dist/{chunk-72x62kch.js → chunk-aa8015mk.js} +1 -1
- package/dist/{chunk-64n10kpa.js → chunk-aacfyyya.js} +1 -1
- package/dist/chunk-abtxpqna.js +2 -0
- package/dist/{chunk-c30qnb6z.js → chunk-apbr1kb1.js} +2 -2
- package/dist/{chunk-nm60wh6r.js → chunk-awyyskad.js} +1 -1
- package/dist/{chunk-ppzz953j.js → chunk-b8ywrx2w.js} +1 -1
- package/dist/{chunk-18018jkn.js → chunk-bcpjhcpn.js} +1 -1
- package/dist/{chunk-kw9cgyfc.js → chunk-c17ybabd.js} +1 -1
- package/dist/chunk-c4rpdtvw.js +2 -0
- package/dist/{chunk-zk6ghjnj.js → chunk-c79nfdyj.js} +1 -1
- package/dist/chunk-cgs5xpsn.js +2 -0
- package/dist/{chunk-avwywzsj.js → chunk-czj6nq0b.js} +2 -2
- package/dist/{chunk-9kmhwbwy.js → chunk-czypgdc1.js} +1 -1
- package/dist/{chunk-epqd3eah.js → chunk-degz74nv.js} +2 -2
- package/dist/chunk-dpyc7pht.js +2 -0
- package/dist/{chunk-hay8nwv3.js → chunk-dtdwjpvf.js} +2 -2
- package/dist/{chunk-dsztk2kp.js → chunk-e48050x3.js} +1 -1
- package/dist/{chunk-3nx7z086.js → chunk-ec8jsqgm.js} +3 -3
- package/dist/{chunk-86c461ca.js → chunk-eg8k598q.js} +1 -1
- package/dist/{chunk-bgrkxzr7.js → chunk-ej8mv2k6.js} +1 -1
- package/dist/{chunk-y2f41kaq.js → chunk-ejwfnttb.js} +1 -1
- package/dist/{chunk-ejqpq0wc.js → chunk-emjmshj8.js} +1 -1
- package/dist/{chunk-59906baj.js → chunk-ep034wt0.js} +1 -1
- package/dist/{chunk-njx93b4z.js → chunk-ez003q74.js} +1 -1
- package/dist/{chunk-ws0282jr.js → chunk-f11z7q5g.js} +1 -1
- package/dist/chunk-f3eb1f6z.js +2 -0
- package/dist/{chunk-1z1efvtw.js → chunk-fqq5k9ve.js} +1 -1
- package/dist/{chunk-c0n802j1.js → chunk-frp9fc7j.js} +1 -1
- package/dist/chunk-fzq2n865.js +2 -0
- package/dist/{chunk-g6czgcg4.js → chunk-g1vxsvqv.js} +1 -1
- package/dist/chunk-g3cmkyk2.js +2 -0
- package/dist/{chunk-7r9vgzg4.js → chunk-g7bpkpd4.js} +1 -1
- package/dist/{chunk-at622hg0.js → chunk-gn2qc03b.js} +1 -1
- package/dist/chunk-gxgrzeeh.js +2 -0
- package/dist/{chunk-a9w1ds4w.js → chunk-h99qxgbr.js} +1 -1
- package/dist/{chunk-dgv43ccd.js → chunk-hcf8399w.js} +1 -1
- package/dist/{chunk-hbkjzx1h.js → chunk-hh0aaxxy.js} +1 -1
- package/dist/{chunk-tc4pj651.js → chunk-hkrzv980.js} +2 -2
- package/dist/{chunk-7qp3zphs.js → chunk-hy79zwyy.js} +2 -2
- package/dist/chunk-j6kec9kp.js +2 -0
- package/dist/{chunk-e631svvs.js → chunk-j8wycqve.js} +1 -1
- package/dist/chunk-jmdxn2mq.js +2 -0
- package/dist/chunk-jwmact5f.js +2 -0
- package/dist/{chunk-g7msqva8.js → chunk-jy451jg5.js} +3 -3
- package/dist/{chunk-a959m68j.js → chunk-k33778kc.js} +1 -1
- package/dist/{chunk-wvc7t11n.js → chunk-kaet6r9w.js} +1 -1
- package/dist/chunk-kdmkk0rb.js +2 -0
- package/dist/{chunk-9e20mgwc.js → chunk-kjd9hbg4.js} +3 -3
- package/dist/{chunk-8m0g0h4x.js → chunk-krt45cqy.js} +2 -2
- package/dist/{chunk-2wb3pgp4.js → chunk-kyyt9xhs.js} +1 -1
- package/dist/{chunk-0k1mtwby.js → chunk-mdbj7sq8.js} +1 -1
- package/dist/{chunk-d86q27j8.js → chunk-mere396d.js} +1 -1
- package/dist/{chunk-1c9453w0.js → chunk-ms25gb16.js} +1 -1
- package/dist/{chunk-ym3r8ktq.js → chunk-n0d7nwhd.js} +1 -1
- package/dist/{chunk-7h9fajgs.js → chunk-n1y0hjk1.js} +2 -2
- package/dist/{chunk-bk1zb1xp.js → chunk-n5tpqzcb.js} +1 -1
- package/dist/{chunk-b5hank5e.js → chunk-nybn003d.js} +2 -2
- package/dist/chunk-p1426yar.js +2 -0
- package/dist/chunk-p78b80dp.js +2 -0
- package/dist/chunk-pr3hz3ec.js +2 -0
- package/dist/{chunk-gtqbvt3a.js → chunk-q4kgqqed.js} +2 -2
- package/dist/{chunk-san1eq0r.js → chunk-qbz6yn8c.js} +2 -2
- package/dist/{chunk-fvsefztj.js → chunk-qjvny3wf.js} +1 -1
- package/dist/{chunk-v0e259x2.js → chunk-qnptmtqh.js} +1 -1
- package/dist/{chunk-msywnv5n.js → chunk-qrvey4wk.js} +2 -2
- package/dist/{chunk-7we3xfde.js → chunk-ra1s4s6b.js} +1 -1
- package/dist/{chunk-62nz9v8t.js → chunk-rbfm5sjt.js} +2 -2
- package/dist/{chunk-99b5tfxc.js → chunk-rcbt11p8.js} +1 -1
- package/dist/{chunk-9nrgjtah.js → chunk-rtfwn4cm.js} +1 -1
- package/dist/chunk-rydb5n5b.js +2 -0
- package/dist/{chunk-6k5a03pw.js → chunk-s5dwatkj.js} +2 -2
- package/dist/chunk-sa6cgj9h.js +2 -0
- package/dist/chunk-skdfq4hq.js +2 -0
- package/dist/{chunk-ngjkzaj7.js → chunk-t23kccpz.js} +3 -3
- package/dist/{chunk-89mqnh67.js → chunk-tf16jtj4.js} +1 -1
- package/dist/{chunk-swvm1wgn.js → chunk-trva71am.js} +2 -2
- package/dist/{chunk-rwwfzkz4.js → chunk-tv04k7gq.js} +1 -1
- package/dist/{chunk-5wbdbcvf.js → chunk-v1qm7p7t.js} +2 -2
- package/dist/chunk-w1a8dwgx.js +2 -0
- package/dist/{chunk-y6xzr30x.js → chunk-wkyt4j9e.js} +1 -1
- package/dist/{chunk-p3p4d6g1.js → chunk-wz4fnsat.js} +2 -2
- package/dist/chunk-x131a0jq.js +2 -0
- package/dist/{chunk-f5cw54q3.js → chunk-x21hdhjw.js} +1 -1
- package/dist/chunk-x5b8az2h.js +2 -0
- package/dist/chunk-xk782v5z.js +2 -0
- package/dist/{chunk-qsbjtp60.js → chunk-y4nzmkea.js} +1 -1
- package/dist/{chunk-sqvqwd0p.js → chunk-y4zddt5r.js} +1 -1
- package/dist/{chunk-vgfd9582.js → chunk-ya5m5vbn.js} +1 -1
- package/dist/{chunk-1vb2rj09.js → chunk-yg0qm73a.js} +2 -2
- package/dist/{chunk-8y1ve8tc.js → chunk-ykevda74.js} +2 -2
- package/dist/chunk-ynj1y0qm.js +2 -0
- package/dist/{chunk-v6e35j4g.js → chunk-z50ex86m.js} +1 -1
- package/dist/chunk-z8gccz1q.js +2 -0
- package/dist/{chunk-wj21f1e0.js → chunk-zxfejz72.js} +1 -1
- package/dist/chunk-zxnf0c9x.js +2 -0
- package/dist/cli.js +14 -14
- package/dist/craft-entry.js +1 -1
- package/dist/craft.js +1 -1
- package/dist/database.js +1 -1
- package/dist/engine-bindings.d.ts +35 -0
- package/dist/engine-bindings.js +55 -0
- package/dist/pwa.js +2 -2
- package/dist/ssg.js +2 -2
- package/dist/stx-module-imports.d.ts +24 -0
- package/dist/stx-module-imports.js +57 -0
- package/dist/stx-module.d.ts +154 -0
- package/dist/stx-virtual-ts.d.ts +74 -1
- package/dist/stx-virtual-ts.js +81 -21
- package/dist/typecheck.d.ts +13 -0
- package/dist/typecheck.js +31 -25
- package/dist/variable-extractor.d.ts +2 -22
- package/dist/variable-extractor.js +3 -55
- package/dist/visual-testing.js +1 -1
- package/package.json +7 -6
- package/stx-module.d.ts +154 -0
- package/dist/chunk-04x3vny9.js +0 -19
- package/dist/chunk-1apnswz7.js +0 -2
- package/dist/chunk-1qvf8ase.js +0 -2
- package/dist/chunk-1vt1h19d.js +0 -2
- package/dist/chunk-32x78na8.js +0 -2
- package/dist/chunk-3z4d7kmp.js +0 -2
- package/dist/chunk-4b2vsawv.js +0 -2
- package/dist/chunk-616fn77w.js +0 -2
- package/dist/chunk-70zk8tj2.js +0 -2
- package/dist/chunk-86q2h34b.js +0 -2
- package/dist/chunk-88e14er7.js +0 -2
- package/dist/chunk-8yydz0hk.js +0 -2
- package/dist/chunk-a7yxvxke.js +0 -2
- package/dist/chunk-aanwshk6.js +0 -2
- package/dist/chunk-ahfj7dc7.js +0 -2
- package/dist/chunk-bed5f4bp.js +0 -2
- package/dist/chunk-dxkjvajv.js +0 -2
- package/dist/chunk-e7np0h2q.js +0 -2
- package/dist/chunk-erb294sv.js +0 -2
- package/dist/chunk-evfr2zgg.js +0 -2
- package/dist/chunk-f85f75jh.js +0 -2
- package/dist/chunk-gsc2vds7.js +0 -2
- package/dist/chunk-h5jt4mxx.js +0 -2
- package/dist/chunk-hke0k33t.js +0 -2
- package/dist/chunk-hysq9e9t.js +0 -2
- package/dist/chunk-kq30wqp6.js +0 -2
- package/dist/chunk-m2j5skez.js +0 -2
- package/dist/chunk-ntzzhw3w.js +0 -2
- package/dist/chunk-px0bs815.js +0 -2
- package/dist/chunk-qw92p9za.js +0 -2
- package/dist/chunk-rjwnw5hj.js +0 -2
- package/dist/chunk-tmr3xq5d.js +0 -2
- package/dist/chunk-tpk6wm38.js +0 -2
- package/dist/chunk-vw4b7g24.js +0 -2
- package/dist/chunk-x054qzma.js +0 -2
- package/dist/chunk-x2n1x19t.js +0 -2
- package/dist/chunk-zks9ft7n.js +0 -2
- package/dist/chunk-zkxnarrh.js +0 -2
- package/dist/chunk-zp14ksx1.js +0 -2
package/dist/stx-virtual-ts.d.ts
CHANGED
|
@@ -49,6 +49,15 @@ export interface ScriptBlock {
|
|
|
49
49
|
code: string;
|
|
50
50
|
/** 1-based line in the source file where the body's first character sits. */
|
|
51
51
|
startLine: number;
|
|
52
|
+
/**
|
|
53
|
+
* 1-based column of the body's first character. Greater than 1 when the
|
|
54
|
+
* code starts on the line the opening tag is on (`<script client>const a`),
|
|
55
|
+
* which a buffer has to pad for or every diagnostic on that line lands
|
|
56
|
+
* left of the code it is about.
|
|
57
|
+
*/
|
|
58
|
+
startColumn?: number;
|
|
59
|
+
/** Offset of the body's first character in the source. */
|
|
60
|
+
offset?: number;
|
|
52
61
|
/** The opening tag's attributes, trimmed. */
|
|
53
62
|
attrs: string;
|
|
54
63
|
}
|
|
@@ -99,6 +108,8 @@ export interface MappedLine {
|
|
|
99
108
|
export interface VirtualFile {
|
|
100
109
|
text: string;
|
|
101
110
|
componentDependencies?: Map<string, string>;
|
|
111
|
+
/** Whether the `reference` option's directive was written (line 1 was free). */
|
|
112
|
+
referenced?: boolean;
|
|
102
113
|
/**
|
|
103
114
|
* Virtual 1-based line → where it came from.
|
|
104
115
|
*
|
|
@@ -239,7 +250,17 @@ export declare function runtimeGlobalDeclarations(): string;
|
|
|
239
250
|
* checker report a genuine typo instead of suppressing every unresolved name.
|
|
240
251
|
*/
|
|
241
252
|
export declare const STX_SERVER_CONTEXT: readonly ['params', 'query', 'cookies', 'host', 'ip', 'setResponseStatus', 'setResponseHeader', 'notFound', 'request', 'url', 'definePageMeta', 'defineClientPayload', 'defineStore', 'props', '$props'];
|
|
242
|
-
export declare function serverContextDeclarations(): string;
|
|
253
|
+
export declare function serverContextDeclarations(typed?: ReadonlySet<string>): string;
|
|
254
|
+
/**
|
|
255
|
+
* Names a global declaration file declares as values: `declare function`,
|
|
256
|
+
* `declare const` / `let` / `var`, at the start of a line.
|
|
257
|
+
*
|
|
258
|
+
* Used to keep the `any` fallbacks below from colliding with a TYPED global of
|
|
259
|
+
* the same name in `stx.d.ts` — `definePageMeta` and `defineStore` are both
|
|
260
|
+
* server context and typed runtime globals, and `declare var x: any` beside
|
|
261
|
+
* `declare function x()` is a conflict that leaves the name typed by neither.
|
|
262
|
+
*/
|
|
263
|
+
export declare function declaredGlobalNames(declarations: string): Set<string>;
|
|
243
264
|
/**
|
|
244
265
|
* The names a `defineClientPayload({ … })` call publishes, or `null` when the
|
|
245
266
|
* page does not declare one.
|
|
@@ -421,6 +442,19 @@ export declare function expressionStatement(expression: TemplateExpression): {
|
|
|
421
442
|
* change a line count, so every diagnostic still lands on the author's line.
|
|
422
443
|
*/
|
|
423
444
|
export declare function absolutizeRelativeSpecifiers(code: string, originDir: string): string;
|
|
445
|
+
/**
|
|
446
|
+
* Spaces that put a block's first line at the column it occupies in the file.
|
|
447
|
+
*
|
|
448
|
+
* A body that starts on the opening tag's line (`<script client>const a = 1`)
|
|
449
|
+
* was written from column 1, so every diagnostic on that line pointed left of
|
|
450
|
+
* the code it was about by the width of the tag.
|
|
451
|
+
*/
|
|
452
|
+
export declare function firstLinePadding(block: ScriptBlock): string;
|
|
453
|
+
/**
|
|
454
|
+
* Local names a block's `import` declarations bind, type-only ones included:
|
|
455
|
+
* `import a, { b as c, type D } from 'x'` and `import * as ns from 'x'`.
|
|
456
|
+
*/
|
|
457
|
+
export declare function collectImportedNames(code: string): string[];
|
|
424
458
|
export interface BuildVirtualOptions {
|
|
425
459
|
/** Enables component call-site checks using the renderer's file lookup. */
|
|
426
460
|
filePath?: string;
|
|
@@ -438,6 +472,28 @@ export interface BuildVirtualOptions {
|
|
|
438
472
|
originDir?: string;
|
|
439
473
|
/** Append ambient declarations at all. Default true. */
|
|
440
474
|
globals?: boolean;
|
|
475
|
+
/**
|
|
476
|
+
* Where the server context, the `@stacksjs/browser` auto-imports and the
|
|
477
|
+
* template globals are declared. Default `'module'`.
|
|
478
|
+
*
|
|
479
|
+
* `'global'` wraps them in `declare global { … }`. Declared in the module
|
|
480
|
+
* they share a scope with the author's own bindings, so a block's
|
|
481
|
+
* `const { query } = defineProps()` is a redeclaration of the context's
|
|
482
|
+
* `query`; declared globally, the block's binding shadows it instead, as it
|
|
483
|
+
* does in `stx typecheck`, whose context is a global file. The editor, which
|
|
484
|
+
* has one buffer per file, needs the global form.
|
|
485
|
+
*/
|
|
486
|
+
contextScope?: 'module' | 'global';
|
|
487
|
+
/**
|
|
488
|
+
* A declaration file to pull into the program with a triple-slash
|
|
489
|
+
* reference, written on the buffer's first line.
|
|
490
|
+
*
|
|
491
|
+
* That line is always blank when the file opens with markup or with a
|
|
492
|
+
* `<script>` tag on a line of its own, which is how every real file starts,
|
|
493
|
+
* so nothing moves. When code sits on line 1 the reference is left out and
|
|
494
|
+
* {@link VirtualFile.referenced} says so, so the caller can fall back.
|
|
495
|
+
*/
|
|
496
|
+
reference?: string;
|
|
441
497
|
/**
|
|
442
498
|
* Declare the stx runtime globals as `any`. Default true.
|
|
443
499
|
*
|
|
@@ -479,6 +535,23 @@ export interface ResolvedPosition {
|
|
|
479
535
|
*/
|
|
480
536
|
inGuard?: boolean;
|
|
481
537
|
}
|
|
538
|
+
/**
|
|
539
|
+
* Whether a diagnostic on a template-expression line is an artefact of how the
|
|
540
|
+
* expression was wrapped rather than a fault in it. Both checkers drop these,
|
|
541
|
+
* so the editor and `stx typecheck` agree:
|
|
542
|
+
*
|
|
543
|
+
* - A hit inside the `if (…) {` wrapper that markup guards put around an
|
|
544
|
+
* expression is about the enclosing CONDITION, which is checked on a line
|
|
545
|
+
* of its own. This copy would report the same fault again against innocent
|
|
546
|
+
* markup (stacksjs/stx#2013).
|
|
547
|
+
* - TS2774 ("this condition will always return true since this function is
|
|
548
|
+
* always defined") is wrong about a template, and only about a template.
|
|
549
|
+
* {@link UNWRAP_HELPER} types a signal as the intersection of the signal and
|
|
550
|
+
* its value, which stays callable, and the runtime unwraps a name the
|
|
551
|
+
* expression only reads — so `x-class="ready ? '' : 'hidden'"` does not
|
|
552
|
+
* always return true. In a script block it is a true positive and is kept.
|
|
553
|
+
*/
|
|
554
|
+
export declare function isTemplateArtefact(position: ResolvedPosition, code: number): boolean;
|
|
482
555
|
/**
|
|
483
556
|
* Translate a position in a virtual buffer back to the `.stx` file.
|
|
484
557
|
*
|
package/dist/stx-virtual-ts.js
CHANGED
|
@@ -20,7 +20,7 @@ export function extractScriptBlocks(source) {
|
|
|
20
20
|
if (typeMatch && !/^(?:module|text\/(?:javascript|typescript))$/i.test(typeMatch[1]))
|
|
21
21
|
continue;
|
|
22
22
|
const kind = /\bserver\b/.test(attrs) ? "server" : /\bclient\b/.test(attrs) ? "client" : "plain", startLine = lineAt(source, bodyStart);
|
|
23
|
-
blocks.push({ kind, code: body, startLine, attrs });
|
|
23
|
+
blocks.push({ kind, code: body, startLine, startColumn: columnAt(source, bodyStart), offset: bodyStart, attrs });
|
|
24
24
|
}
|
|
25
25
|
return blocks;
|
|
26
26
|
}
|
|
@@ -340,10 +340,13 @@ export const STX_SERVER_CONTEXT = [
|
|
|
340
340
|
"props",
|
|
341
341
|
"$props"
|
|
342
342
|
];
|
|
343
|
-
export function serverContextDeclarations() {
|
|
344
|
-
return STX_SERVER_CONTEXT.map((name) => `declare var ${name}: any`).join(`
|
|
343
|
+
export function serverContextDeclarations(typed = new Set) {
|
|
344
|
+
return STX_SERVER_CONTEXT.filter((name) => !typed.has(name)).map((name) => `declare var ${name}: any`).join(`
|
|
345
345
|
`);
|
|
346
346
|
}
|
|
347
|
+
export function declaredGlobalNames(declarations) {
|
|
348
|
+
return new Set([...declarations.matchAll(/^declare (?:function|const|let|var)\s+([A-Za-z_$][\w$]*)/gm)].map((match) => match[1]));
|
|
349
|
+
}
|
|
347
350
|
export function extractClientPayloadNames(serverCode) {
|
|
348
351
|
const call = /\bdefineClientPayload\s*\(\s*\{([\s\S]*?)\}\s*\)/g;
|
|
349
352
|
let match, found = !1;
|
|
@@ -608,6 +611,27 @@ export function absolutizeRelativeSpecifiers(code, originDir) {
|
|
|
608
611
|
return `${prefix}${quote}${absolute}${quote}`;
|
|
609
612
|
});
|
|
610
613
|
}
|
|
614
|
+
export function firstLinePadding(block) {
|
|
615
|
+
return " ".repeat(Math.max(0, (block.startColumn ?? 1) - 1));
|
|
616
|
+
}
|
|
617
|
+
export function collectImportedNames(code) {
|
|
618
|
+
const names = new Set, stripped = stripCommentsAndLiterals(code);
|
|
619
|
+
for (const match of stripped.matchAll(/\bimport\s+(?:type\s+)?([\w$*{}\s,]+?)\s+from\b/g)) {
|
|
620
|
+
const clause = match[1], named = /\{([^}]*)\}/.exec(clause);
|
|
621
|
+
for (const part of named?.[1].split(",") ?? []) {
|
|
622
|
+
const local = part.trim().replace(/^type\s+/, "").split(/\s+as\s+/).pop()?.trim();
|
|
623
|
+
if (local && /^[A-Z_$][\w$]*$/i.test(local))
|
|
624
|
+
names.add(local);
|
|
625
|
+
}
|
|
626
|
+
const outside = clause.replace(/\{[^}]*\}/, ""), namespace = /\*\s*as\s+([A-Z_$][\w$]*)/i.exec(outside);
|
|
627
|
+
if (namespace)
|
|
628
|
+
names.add(namespace[1]);
|
|
629
|
+
const defaultName = /^\s*([A-Z_$][\w$]*)/i.exec(outside);
|
|
630
|
+
if (defaultName && defaultName[1] !== "type")
|
|
631
|
+
names.add(defaultName[1]);
|
|
632
|
+
}
|
|
633
|
+
return [...names].sort();
|
|
634
|
+
}
|
|
611
635
|
export function buildVirtualTypeScript(source, options = {}) {
|
|
612
636
|
const blocks = extractScriptBlocks(source), sourceLines = source.split(`
|
|
613
637
|
`), lines = Array.from({ length: sourceLines.length }, () => ""), lineMap = new Map, components = options.filePath && options.templateExpressions !== !1 ? componentContractChecks(source, maskNonTemplateRegions(source), {
|
|
@@ -617,14 +641,24 @@ export function buildVirtualTypeScript(source, options = {}) {
|
|
|
617
641
|
readComponent: options.readComponent,
|
|
618
642
|
scriptCode: (text, file) => extractScriptBlocks(text).map((block) => absolutizeRelativeSpecifiers(block.code, path.dirname(file))).join(`
|
|
619
643
|
`)
|
|
620
|
-
}) : void 0;
|
|
621
|
-
for (const block of blocks)
|
|
622
|
-
|
|
623
|
-
`)
|
|
644
|
+
}) : void 0, occupied = new Set, blockEnds = [];
|
|
645
|
+
for (const block of blocks) {
|
|
646
|
+
const code = blankScriptDirectives(substituteInterpolationsInPlace(block.code)), bodyLines = absolutizeRelativeSpecifiers(code, options.originDir ?? "").split(`
|
|
647
|
+
`);
|
|
648
|
+
bodyLines.forEach((text, i) => {
|
|
624
649
|
const index = block.startLine - 1 + i;
|
|
625
|
-
if (index < lines.length)
|
|
626
|
-
lines[index] = text;
|
|
650
|
+
if (index < lines.length) {
|
|
651
|
+
lines[index] = i === 0 ? firstLinePadding(block) + text : text;
|
|
652
|
+
occupied.add(index);
|
|
653
|
+
}
|
|
627
654
|
});
|
|
655
|
+
blockEnds.push(block.startLine - 1 + bodyLines.length - 1);
|
|
656
|
+
}
|
|
657
|
+
for (const end of blockEnds) {
|
|
658
|
+
const at = lines[end]?.trim() === "" ? end : end + 1;
|
|
659
|
+
if (at < lines.length && lines[at].trim() === "" && (at === end || !occupied.has(at)))
|
|
660
|
+
lines[at] = ";";
|
|
661
|
+
}
|
|
628
662
|
const append = (text, origin) => {
|
|
629
663
|
for (const [index, line] of text.split(`
|
|
630
664
|
`).entries()) {
|
|
@@ -635,17 +669,33 @@ export function buildVirtualTypeScript(source, options = {}) {
|
|
|
635
669
|
};
|
|
636
670
|
if (options.globals !== !1) {
|
|
637
671
|
append("");
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
`)
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
672
|
+
const bound = new Set([
|
|
673
|
+
...blocks.flatMap((block) => collectBlockDeclarations(block.code)),
|
|
674
|
+
...blocks.flatMap((block) => collectImportedNames(block.code))
|
|
675
|
+
]), declareAny = (name) => {
|
|
676
|
+
if (!bound.has(name))
|
|
677
|
+
append(`declare var ${name}: any`);
|
|
678
|
+
};
|
|
679
|
+
if (options.runtimeGlobals !== !1) {
|
|
680
|
+
if (!bound.has("window"))
|
|
681
|
+
append("declare var window: any");
|
|
682
|
+
for (const name of STX_RUNTIME_GLOBALS)
|
|
683
|
+
declareAny(name);
|
|
684
|
+
}
|
|
685
|
+
const contextNames = [...new Set([...STX_SERVER_CONTEXT, ...BROWSER_CORE_IMPORTS, ...STX_TEMPLATE_GLOBALS])].filter((name) => options.runtimeGlobals !== !1 || !STX_RUNTIME_GLOBALS.includes(name));
|
|
686
|
+
if (options.contextScope === "global") {
|
|
687
|
+
append("declare global {");
|
|
688
|
+
for (const name of contextNames)
|
|
689
|
+
append(` var ${name}: any`);
|
|
690
|
+
append("}");
|
|
691
|
+
} else {
|
|
692
|
+
for (const name of STX_SERVER_CONTEXT)
|
|
693
|
+
declareAny(name);
|
|
694
|
+
for (const name of BROWSER_CORE_IMPORTS)
|
|
695
|
+
declareAny(name);
|
|
696
|
+
for (const name of STX_TEMPLATE_GLOBALS)
|
|
697
|
+
declareAny(name);
|
|
698
|
+
}
|
|
649
699
|
append(`declare var ${INTERPOLATION_PLACEHOLDER}: any`);
|
|
650
700
|
const declared = new Set(blocks.flatMap((block) => collectBlockDeclarations(block.code)));
|
|
651
701
|
append(`type ${ELEMENT_HELPER}<T> = T extends readonly (infer E)[] ? E : T extends Iterable<infer E2> ? E2 : any`);
|
|
@@ -695,9 +745,14 @@ export function buildVirtualTypeScript(source, options = {}) {
|
|
|
695
745
|
append("});");
|
|
696
746
|
}
|
|
697
747
|
}
|
|
748
|
+
let referenced = !1;
|
|
749
|
+
if (options.reference && lines[0] !== void 0 && lines[0].trim() === "") {
|
|
750
|
+
lines[0] = `/// <reference path=${JSON.stringify(options.reference.replace(/\\/g, "/"))} />`;
|
|
751
|
+
referenced = !0;
|
|
752
|
+
}
|
|
698
753
|
append("export {}");
|
|
699
754
|
return { text: lines.join(`
|
|
700
|
-
`), lineMap, sourceLineCount: sourceLines.length, componentDependencies: components?.dependencies };
|
|
755
|
+
`), lineMap, sourceLineCount: sourceLines.length, componentDependencies: components?.dependencies, referenced };
|
|
701
756
|
}
|
|
702
757
|
export function lineStarts(text) {
|
|
703
758
|
const starts = [0];
|
|
@@ -721,6 +776,11 @@ export function positionToOffset(starts, line, column) {
|
|
|
721
776
|
const index = Math.min(Math.max(line, 1), starts.length) - 1, next = index + 1 < starts.length ? starts[index + 1] - 1 : Number.MAX_SAFE_INTEGER;
|
|
722
777
|
return Math.min(starts[index] + Math.max(column, 1) - 1, next);
|
|
723
778
|
}
|
|
779
|
+
export function isTemplateArtefact(position, code) {
|
|
780
|
+
if (!position.expression)
|
|
781
|
+
return !1;
|
|
782
|
+
return position.inGuard === !0 || code === 2774;
|
|
783
|
+
}
|
|
724
784
|
export function resolvePosition(virtual, line, column) {
|
|
725
785
|
const mapped = virtual.lineMap.get(line);
|
|
726
786
|
if (!mapped)
|
package/dist/typecheck.d.ts
CHANGED
|
@@ -34,6 +34,19 @@ export declare function sourcePathFor(virtualPath: string): string;
|
|
|
34
34
|
* than hand tsc a path to nothing.
|
|
35
35
|
*/
|
|
36
36
|
export declare function findRuntimeTypeDeclarations(): string | null;
|
|
37
|
+
/**
|
|
38
|
+
* Locate the package's own `stx-module.d.ts`, which declares the virtual `stx`
|
|
39
|
+
* module a `.stx` block imports from.
|
|
40
|
+
*
|
|
41
|
+
* It used to be generated here as `declare module 'stx' { export * from
|
|
42
|
+
* '@stacksjs/stx' }`, which typed `from 'stx'` as the whole package. That is
|
|
43
|
+
* not what the specifier binds: a client block gets only what is destructured
|
|
44
|
+
* off `window.stx`, a server block only what the engine passes in, and every
|
|
45
|
+
* other name fails at runtime (stacksjs/stx#2028). The declaration file says
|
|
46
|
+
* exactly that, and the editor plugin loads the same one, so the two checkers
|
|
47
|
+
* cannot disagree about it.
|
|
48
|
+
*/
|
|
49
|
+
export declare function findStxModuleDeclarations(): string | null;
|
|
37
50
|
export declare function typecheckStxFiles(files: string[], options?: TypecheckOptions): Promise<TypecheckResult>;
|
|
38
51
|
/** Render diagnostics the way a CLI should: file:line:col, then the message. */
|
|
39
52
|
export declare function formatTypecheckDiagnostics(diagnostics: TypecheckDiagnostic[]): string;
|
package/dist/typecheck.js
CHANGED
|
@@ -14,35 +14,24 @@ import {
|
|
|
14
14
|
scrapedBridgeNames,
|
|
15
15
|
serverContextDeclarations,
|
|
16
16
|
blankScriptDirectives,
|
|
17
|
+
declaredGlobalNames,
|
|
18
|
+
firstLinePadding,
|
|
19
|
+
isTemplateArtefact,
|
|
17
20
|
substituteInterpolationsInPlace
|
|
18
21
|
} from "./stx-virtual-ts.js";
|
|
22
|
+
import { stxImportDiagnostics } from "./stx-module-imports.js";
|
|
19
23
|
export {
|
|
20
24
|
extractScriptBlocks,
|
|
21
25
|
extractTemplateExpressions
|
|
22
26
|
} from "./stx-virtual-ts.js";
|
|
23
27
|
export function buildVirtualSource(block, serverCode = "", originDir = "") {
|
|
24
28
|
const leadingNewlines = block.startLine > 1 ? `
|
|
25
|
-
`.repeat(block.startLine - 1) : "", code = blankScriptDirectives(substituteInterpolationsInPlace(block.code)), payload = block.kind === "client" || block.kind === "plain" ? clientPayloadDeclarations(serverCode, block.code) : "";
|
|
29
|
+
`.repeat(block.startLine - 1) : "", code = firstLinePadding(block) + blankScriptDirectives(substituteInterpolationsInPlace(block.code)), payload = block.kind === "client" || block.kind === "plain" ? clientPayloadDeclarations(serverCode, block.code) : "";
|
|
26
30
|
return absolutizeRelativeSpecifiers(`${leadingNewlines + code}
|
|
27
31
|
${payload}
|
|
28
32
|
export {}
|
|
29
33
|
`, originDir);
|
|
30
34
|
}
|
|
31
|
-
function virtualStxModuleDeclaration(files) {
|
|
32
|
-
const anchor = files.length > 0 ? path.dirname(path.resolve(files[0])) : process.cwd();
|
|
33
|
-
try {
|
|
34
|
-
Bun.resolveSync("@stacksjs/stx", anchor);
|
|
35
|
-
} catch {
|
|
36
|
-
return "";
|
|
37
|
-
}
|
|
38
|
-
return [
|
|
39
|
-
"// Generated \u2014 `stx` is the virtual specifier client-script.ts strips.",
|
|
40
|
-
"declare module 'stx' {",
|
|
41
|
-
" export * from '@stacksjs/stx'",
|
|
42
|
-
"}"
|
|
43
|
-
].join(`
|
|
44
|
-
`);
|
|
45
|
-
}
|
|
46
35
|
const WINDOW_OWNED_NAMES = new Set([
|
|
47
36
|
"name",
|
|
48
37
|
"status",
|
|
@@ -94,9 +83,15 @@ export function sourcePathFor(virtualPath) {
|
|
|
94
83
|
return virtualPath.replace(/\.__stx_(?:server|client|plain|template)\d+\.ts$/, "");
|
|
95
84
|
}
|
|
96
85
|
export function findRuntimeTypeDeclarations() {
|
|
86
|
+
return findPackageDeclarations("stx.d.ts");
|
|
87
|
+
}
|
|
88
|
+
export function findStxModuleDeclarations() {
|
|
89
|
+
return findPackageDeclarations("stx-module.d.ts");
|
|
90
|
+
}
|
|
91
|
+
function findPackageDeclarations(name) {
|
|
97
92
|
for (const candidate of [
|
|
98
|
-
path.resolve(import.meta.dir, "..",
|
|
99
|
-
path.resolve(import.meta.dir, "..", "..",
|
|
93
|
+
path.resolve(import.meta.dir, "..", name),
|
|
94
|
+
path.resolve(import.meta.dir, "..", "..", name)
|
|
100
95
|
])
|
|
101
96
|
if (existsSync(candidate))
|
|
102
97
|
return candidate;
|
|
@@ -190,7 +185,7 @@ function readProjectPathAliases(startDir) {
|
|
|
190
185
|
return { paths: absolute };
|
|
191
186
|
}
|
|
192
187
|
export async function typecheckStxFiles(files, options = {}) {
|
|
193
|
-
const checkClient = options.client !== !1, checkServer = options.server !== !1, checkTemplates = options.templates !== !1, componentsDir = options.componentsDir ?? (checkTemplates ? (await loadStxConfig()).componentsDir : void 0), virtualFiles = new Map, scrapedByFile = new Map, checkedFiles = [];
|
|
188
|
+
const checkClient = options.client !== !1, checkServer = options.server !== !1, checkTemplates = options.templates !== !1, componentsDir = options.componentsDir ?? (checkTemplates ? (await loadStxConfig()).componentsDir : void 0), virtualFiles = new Map, scrapedByFile = new Map, importDiagnostics = [], checkedFiles = [];
|
|
194
189
|
let blockCount = 0, expressionCount = 0;
|
|
195
190
|
const runtimeTypes = findRuntimeTypeDeclarations();
|
|
196
191
|
for (const file of files) {
|
|
@@ -200,6 +195,16 @@ export async function typecheckStxFiles(files, options = {}) {
|
|
|
200
195
|
return checkClient;
|
|
201
196
|
}), serverCode = extractScriptBlocks(source).filter((block) => block.kind === "server").map((block) => block.code).join(`
|
|
202
197
|
`);
|
|
198
|
+
for (const d of stxImportDiagnostics(source, blocks))
|
|
199
|
+
importDiagnostics.push({
|
|
200
|
+
file,
|
|
201
|
+
line: d.line,
|
|
202
|
+
column: d.column,
|
|
203
|
+
code: 0,
|
|
204
|
+
message: d.message,
|
|
205
|
+
category: "error",
|
|
206
|
+
blockKind: d.kind
|
|
207
|
+
});
|
|
203
208
|
if (checkClient && serverCode) {
|
|
204
209
|
const clientBlocks = blocks.filter((block) => block.kind !== "server"), names = [...new Set(clientBlocks.flatMap((block) => scrapedBridgeNames(serverCode, block.code)))];
|
|
205
210
|
if (names.length > 0)
|
|
@@ -227,20 +232,22 @@ export async function typecheckStxFiles(files, options = {}) {
|
|
|
227
232
|
});
|
|
228
233
|
}
|
|
229
234
|
if (virtualFiles.size === 0)
|
|
230
|
-
return { diagnostics:
|
|
235
|
+
return { diagnostics: importDiagnostics, checkedFiles, blockCount: 0, expressionCount: 0 };
|
|
231
236
|
const ambient = (options.extraLibs ?? []).map((lib) => path.resolve(lib));
|
|
232
237
|
if (runtimeTypes)
|
|
233
238
|
ambient.push(runtimeTypes);
|
|
239
|
+
const stxModule = runtimeTypes ? findStxModuleDeclarations() : null;
|
|
240
|
+
if (stxModule)
|
|
241
|
+
ambient.push(stxModule);
|
|
234
242
|
const globalsDts = `${stateDir()}/typecheck/__stx_globals.d.ts`, globalDecls = [
|
|
235
243
|
"// Generated \u2014 the context serve.ts injects into <script server> blocks.",
|
|
236
|
-
serverContextDeclarations(),
|
|
244
|
+
serverContextDeclarations(runtimeTypes ? declaredGlobalNames(readFileSync(runtimeTypes, "utf8")) : void 0),
|
|
237
245
|
...runtimeTypes ? [] : ["declare const window: any", ...STX_RUNTIME_GLOBALS.map((name) => `declare const ${name}: any`)],
|
|
238
246
|
[
|
|
239
247
|
"// Generated \u2014 the names stx auto-imports from @stacksjs/browser.",
|
|
240
248
|
...BROWSER_CORE_IMPORTS.map((name) => `declare const ${name}: any`)
|
|
241
249
|
].join(`
|
|
242
250
|
`),
|
|
243
|
-
virtualStxModuleDeclaration(files),
|
|
244
251
|
composableGlobalDeclarations(await listComposableModules())
|
|
245
252
|
].filter(Boolean).join(`
|
|
246
253
|
`), workDir = `${stateDir()}/typecheck`;
|
|
@@ -305,9 +312,7 @@ export async function typecheckStxFiles(files, options = {}) {
|
|
|
305
312
|
const at = resolvePosition(entry.virtual, line, column);
|
|
306
313
|
if (!at?.expression)
|
|
307
314
|
continue;
|
|
308
|
-
if (at
|
|
309
|
-
continue;
|
|
310
|
-
if (Number(code) === 2774)
|
|
315
|
+
if (isTemplateArtefact(at, Number(code)))
|
|
311
316
|
continue;
|
|
312
317
|
line = at.line;
|
|
313
318
|
column = at.column;
|
|
@@ -345,6 +350,7 @@ export async function typecheckStxFiles(files, options = {}) {
|
|
|
345
350
|
blockKind: scraped.kind
|
|
346
351
|
});
|
|
347
352
|
}
|
|
353
|
+
diagnostics.push(...importDiagnostics);
|
|
348
354
|
const seen = new Set, unique = diagnostics.filter((d) => {
|
|
349
355
|
const key = `${d.file}:${d.line}:${d.column}:${d.code}:${d.message}`;
|
|
350
356
|
if (seen.has(key))
|
|
@@ -1,25 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* parameters, in the order the parameters are declared.
|
|
4
|
-
*
|
|
5
|
-
* This drives the `new Function` parameter list rather than sitting beside it,
|
|
6
|
-
* because the two must not drift: the value list below it is positional, so a
|
|
7
|
-
* name added in one place and not the other silently rebinds every argument
|
|
8
|
-
* after it.
|
|
9
|
-
*
|
|
10
|
-
* It is also the set a `from 'stx'` import must not redeclare. A server script
|
|
11
|
-
* writing the documented `import { defineProps } from 'stx'` was rewritten to
|
|
12
|
-
* `const { defineProps } = await import('stx')`, and that `const` shadows the
|
|
13
|
-
* parameter of the same name. The package's own `defineProps` reads
|
|
14
|
-
* `globalThis.__STX_CURRENT_PROPS__`, which nothing on the server path ever
|
|
15
|
-
* sets — so props came back `{}` and every component rendered empty.
|
|
16
|
-
*
|
|
17
|
-
* It went unnoticed because `stx` does not resolve inside this repo (the
|
|
18
|
-
* published package is `@stacksjs/stx`; the root `stx` is private), so the
|
|
19
|
-
* generated `await import('stx')` rejected and the shadowing binding was never
|
|
20
|
-
* created. The failure needed a real install to appear.
|
|
21
|
-
*/
|
|
22
|
-
export declare const STX_ENGINE_BINDING_NAMES: readonly ['module', 'exports', 'require', 'props', '$props', '$bool', 'defineProps', 'withDefaults', 'defineClientPayload', 'useServerData', 'useRuntimeConfig', 'useServerRuntimeConfig', 'state', 'derived', 'effect', 'batch', 'onMount', 'onDestroy', 'definePageMeta', 'useRoute', 'useRouter', 'useHead', 'useSeoMeta', 'setResponseStatus', 'setResponseHeader', 'notFound', 'ref', 'reactive', 'computed', 'watch', 'onMounted', 'onUnmounted', 'nextTick', 'defineEmits', 'defineExpose', 'defineSlots', 'provide', 'inject', 'useColorMode', 'useDark', 'useMediaQuery', 'useScrollLock', 'usePreferredDark', 'usePreferredLight', 'usePreferredReducedMotion', 'usePreferredContrast', 'window', 'document', 'console', 'confirm', 'alert', 'fetch', 'params'];
|
|
1
|
+
import { STX_ENGINE_BINDING_NAMES } from './engine-bindings';
|
|
2
|
+
export { STX_ENGINE_BINDING_NAMES };
|
|
23
3
|
/**
|
|
24
4
|
* Strip TypeScript-specific syntax to make it executable as JavaScript
|
|
25
5
|
*
|
|
@@ -4,61 +4,9 @@ import { useServerData, withServerData } from "./server-data.js";
|
|
|
4
4
|
import { prepareRuntimeConfig } from "./runtime-config-loader.js";
|
|
5
5
|
import { currentRuntimeConfig, resolveRuntimeConfig, useRuntimeConfig, useServerRuntimeConfig, withRuntimeConfig } from "./runtime-config-server.js";
|
|
6
6
|
import { getSharedTranspiler } from "./utils.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"require",
|
|
11
|
-
"props",
|
|
12
|
-
"$props",
|
|
13
|
-
"$bool",
|
|
14
|
-
"defineProps",
|
|
15
|
-
"withDefaults",
|
|
16
|
-
"defineClientPayload",
|
|
17
|
-
"useServerData",
|
|
18
|
-
"useRuntimeConfig",
|
|
19
|
-
"useServerRuntimeConfig",
|
|
20
|
-
"state",
|
|
21
|
-
"derived",
|
|
22
|
-
"effect",
|
|
23
|
-
"batch",
|
|
24
|
-
"onMount",
|
|
25
|
-
"onDestroy",
|
|
26
|
-
"definePageMeta",
|
|
27
|
-
"useRoute",
|
|
28
|
-
"useRouter",
|
|
29
|
-
"useHead",
|
|
30
|
-
"useSeoMeta",
|
|
31
|
-
"setResponseStatus",
|
|
32
|
-
"setResponseHeader",
|
|
33
|
-
"notFound",
|
|
34
|
-
"ref",
|
|
35
|
-
"reactive",
|
|
36
|
-
"computed",
|
|
37
|
-
"watch",
|
|
38
|
-
"onMounted",
|
|
39
|
-
"onUnmounted",
|
|
40
|
-
"nextTick",
|
|
41
|
-
"defineEmits",
|
|
42
|
-
"defineExpose",
|
|
43
|
-
"defineSlots",
|
|
44
|
-
"provide",
|
|
45
|
-
"inject",
|
|
46
|
-
"useColorMode",
|
|
47
|
-
"useDark",
|
|
48
|
-
"useMediaQuery",
|
|
49
|
-
"useScrollLock",
|
|
50
|
-
"usePreferredDark",
|
|
51
|
-
"usePreferredLight",
|
|
52
|
-
"usePreferredReducedMotion",
|
|
53
|
-
"usePreferredContrast",
|
|
54
|
-
"window",
|
|
55
|
-
"document",
|
|
56
|
-
"console",
|
|
57
|
-
"confirm",
|
|
58
|
-
"alert",
|
|
59
|
-
"fetch",
|
|
60
|
-
"params"
|
|
61
|
-
];
|
|
7
|
+
import { STX_ENGINE_BINDING_NAMES } from "./engine-bindings.js";
|
|
8
|
+
|
|
9
|
+
export { STX_ENGINE_BINDING_NAMES };
|
|
62
10
|
const ENGINE_BINDINGS = new Set(STX_ENGINE_BINDING_NAMES), CONTEXT_RESERVED_BINDINGS = new Set(["props", "$props", "defineProps"]), STX_RUNTIME_SPECIFIERS = new Set(["stx", "@stacksjs/stx"]);
|
|
63
11
|
import { findMatchingDelimiter } from "./parser/tokenizer.js";
|
|
64
12
|
import { mergeHeadConfigs, seoMetaToHeadConfig } from "./head.js";
|
package/dist/visual-testing.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import"./chunk-
|
|
2
|
+
import"./chunk-emjmshj8.js";import B from"fs";import $ from"path";import k from"crypto";var V=[{name:"mobile",width:375,height:667,isMobile:!0,hasTouch:!0},{name:"tablet",width:768,height:1024,isMobile:!0,hasTouch:!0},{name:"desktop",width:1280,height:800,isMobile:!1,hasTouch:!1},{name:"wide",width:1920,height:1080,isMobile:!1,hasTouch:!1}];function J(N={}){let Y={snapshotDir:N.snapshotDir||"__snapshots__",screenshotDir:N.screenshotDir||"__screenshots__",updateSnapshots:N.updateSnapshots||process.env.UPDATE_SNAPSHOTS==="true",threshold:N.threshold??0.01,viewports:N.viewports||V,generateDiff:N.generateDiff??!0,diffDir:N.diffDir||"__diffs__",compare:N.compare||b,ci:N.ci??process.env.CI==="true",retries:N.retries??(N.ci?3:1)};return{async snapshot(M,X){let q=$.join(Y.snapshotDir,`${X}.html`),G=C(M),Q=K(G);if(await Bun.file(q).exists()){let W=await Bun.file(q).text(),Z=K(C(W));if(Q===Z)return{passed:!0,snapshotPath:q,message:"Snapshot matches"};if(Y.updateSnapshots)return await B.promises.mkdir($.dirname(q),{recursive:!0}),await Bun.write(q,G),{passed:!0,snapshotPath:q,message:"Snapshot updated"};let F=$.join(Y.diffDir,`${X}.actual.html`),U=$.join(Y.diffDir,`${X}.diff.html`);return await B.promises.mkdir(Y.diffDir,{recursive:!0}),await Bun.write(F,G),await Bun.write(U,I(W,G)),{passed:!1,snapshotPath:q,actualPath:F,diffPath:U,message:"Snapshot does not match"}}return await B.promises.mkdir($.dirname(q),{recursive:!0}),await Bun.write(q,G),{passed:!0,snapshotPath:q,message:"New snapshot created"}},async snapshotJson(M,X){let q=$.join(Y.snapshotDir,`${X}.json`),G=JSON.stringify(M,null,2);if(await Bun.file(q).exists()){let Q=await Bun.file(q).text();if(G===Q)return{passed:!0,snapshotPath:q};if(Y.updateSnapshots)return await Bun.write(q,G),{passed:!0,snapshotPath:q,message:"Snapshot updated"};return{passed:!1,snapshotPath:q,message:`JSON snapshot mismatch:
|
|
3
3
|
${z(Q,G)}`}}return await B.promises.mkdir($.dirname(q),{recursive:!0}),await Bun.write(q,G),{passed:!0,snapshotPath:q,message:"New snapshot created"}},matchInlineSnapshot(M,X){let q=C(M);if(X===void 0)return{passed:!0,expected:q};let G=C(X);return{passed:q===G,expected:q}},getConfig(){return Y}}}function D(N={}){let Y=J(N),M=Y.getConfig();return{async compareScreenshots(X,q,G="desktop"){let Q=$.join(M.screenshotDir,G,`${X}.png`),W=$.join(M.diffDir,G,`${X}.actual.png`),Z=$.join(M.diffDir,G,`${X}.diff.png`);if(await Bun.file(Q).exists()){let F=await Bun.file(Q).arrayBuffer(),U=Buffer.from(F),_=await M.compare(q,U);if(_.match||_.diffPercentage<=M.threshold)return{viewport:G,passed:!0,baselinePath:Q};if(M.updateSnapshots)return await B.promises.mkdir($.dirname(Q),{recursive:!0}),await Bun.write(Q,q),{viewport:G,passed:!0,baselinePath:Q};if(await B.promises.mkdir($.dirname(W),{recursive:!0}),await Bun.write(W,q),_.diffImage&&M.generateDiff)await Bun.write(Z,_.diffImage);return{viewport:G,passed:!1,baselinePath:Q,actualPath:W,diffPath:M.generateDiff?Z:void 0,diffPercentage:_.diffPercentage}}return await B.promises.mkdir($.dirname(Q),{recursive:!0}),await Bun.write(Q,q),{viewport:G,passed:!0,baselinePath:Q}},async testViewports(X,q,G=M.viewports){let Q=[];for(let W of G){let Z=null;for(let F=0;F<M.retries;F++)try{let U=await q(W),_=await this.compareScreenshots(X,U,W.name);Q.push(_),Z=null;break}catch(U){if(Z=U,F<M.retries-1)await new Promise((_)=>setTimeout(_,100*(F+1)))}if(Z)Q.push({viewport:W.name,passed:!1,baselinePath:"",diffPercentage:100})}return Q},getSnapshotTester(){return Y}}}function L(N={}){let M=D(N).getSnapshotTester(),X=new Map;return{addStory(q){X.set(`${q.component}/${q.name}`,q)},addStories(q){for(let G of q)this.addStory(G)},getStories(){return Array.from(X.values())},getStoriesForComponent(q){return Array.from(X.values()).filter((G)=>G.component===q)},async testStory(q){let G=X.get(q);if(!G)return{name:q,passed:!1,duration:0,snapshots:[],screenshots:[],errors:[Error(`Story not found: ${q}`)]};let Q=Date.now(),W={name:q,passed:!0,duration:0,snapshots:[],screenshots:[],errors:[]};try{let Z=await G.render(),F=await M.snapshot(Z,q.replace(/\//g,"-"));if(W.snapshots.push(F),!F.passed)W.passed=!1}catch(Z){W.passed=!1,W.errors.push(Z)}return W.duration=Date.now()-Q,W},async testAllStories(){let q=[];for(let G of X.keys()){let Q=await this.testStory(G);q.push(Q)}return q},async generateStoryIndex(){let q={};for(let G of X.values()){if(!q[G.component])q[G.component]=[];q[G.component].push({name:G.name,args:G.args})}return JSON.stringify(q,null,2)}}}async function S(N,Y={}){let M={outputDir:Y.outputDir||"visual-test-report",format:Y.format||"html",title:Y.title||"Visual Test Report",includeScreenshots:Y.includeScreenshots??!0};await B.promises.mkdir(M.outputDir,{recursive:!0});let X=N.length,q=N.filter((F)=>F.passed).length,G=X-q,Q=N.reduce((F,U)=>F+U.duration,0);if(M.format==="json"){let F={title:M.title,summary:{total:X,passed:q,failed:G,duration:Q},results:N,generatedAt:new Date().toISOString()},U=$.join(M.outputDir,"report.json");return await Bun.write(U,JSON.stringify(F,null,2)),U}if(M.format==="markdown"){let F=`# ${M.title}
|
|
4
4
|
|
|
5
5
|
`;F+=`## Summary
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/stx",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.356",
|
|
5
5
|
"description": "A performant UI Framework. Powered by Bun.",
|
|
6
6
|
"author": "Chris Breuer <chris@stacksjs.org>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -84,7 +84,8 @@
|
|
|
84
84
|
"LICENSE.md",
|
|
85
85
|
"README.md",
|
|
86
86
|
"dist",
|
|
87
|
-
"stx.d.ts"
|
|
87
|
+
"stx.d.ts",
|
|
88
|
+
"stx-module.d.ts"
|
|
88
89
|
],
|
|
89
90
|
"scripts": {
|
|
90
91
|
"build": "bun run build:css && bun --bun build.ts",
|
|
@@ -117,12 +118,12 @@
|
|
|
117
118
|
"dependencies": {
|
|
118
119
|
"@stacksjs/ts-css": "^0.3.2",
|
|
119
120
|
"@stacksjs/clapp": "^0.2.16",
|
|
120
|
-
"@stacksjs/desktop": "0.2.
|
|
121
|
-
"@stacksjs/sanitizer": "0.2.
|
|
121
|
+
"@stacksjs/desktop": "0.2.356",
|
|
122
|
+
"@stacksjs/sanitizer": "0.2.356",
|
|
122
123
|
"@stacksjs/ts-i18n": "^0.1.11",
|
|
123
|
-
"bun-plugin-stx": "0.2.
|
|
124
|
+
"bun-plugin-stx": "0.2.356",
|
|
124
125
|
"bunfig": "^0.15.19",
|
|
125
|
-
"stx-router": "0.2.
|
|
126
|
+
"stx-router": "0.2.356",
|
|
126
127
|
"ts-broadcasting": "^0.0.10",
|
|
127
128
|
"ts-images": "^0.2.22",
|
|
128
129
|
"ts-syntax-highlighter": "^0.2.1"
|