@stacksjs/stx 0.2.151 → 0.2.152
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/browser-composables.d.ts +16 -9
- package/dist/cli.js +503 -503
- package/dist/component-processing.d.ts +16 -0
- package/dist/component-processing.js +4 -1
- package/dist/component-renderer.js +2 -2
- package/dist/composables/use-device-orientation.d.ts +8 -1
- package/dist/composables/use-event-source.d.ts +14 -1
- package/dist/composables/use-eye-dropper.d.ts +10 -1
- package/dist/composables/use-idle.d.ts +21 -3
- package/dist/composables/use-storage.d.ts +8 -2
- package/dist/composables/use-text-selection.d.ts +27 -3
- package/dist/composables/use-wake-lock.d.ts +2 -2
- package/dist/craft.js +265 -265
- package/dist/edge-runtime.d.ts +1 -1
- package/dist/includes.js +2 -0
- package/dist/pwa.js +255 -255
- package/dist/render.d.ts +1 -1
- package/dist/render.js +2 -2
- package/dist/ssg.js +273 -273
- package/dist/ssr.d.ts +17 -1
- package/dist/utils.js +1 -8
- package/dist/variable-extractor.d.ts +8 -0
- package/dist/variable-extractor.js +24 -9
- package/dist/visual-testing.d.ts +26 -3
- package/package.json +5 -5
|
@@ -38,6 +38,22 @@ export declare function findComponentTags(html: string, tagPattern: RegExp, skip
|
|
|
38
38
|
* A legacy HTML-entity-escaped JSON format is still accepted as a fallback so
|
|
39
39
|
* that any externally-produced markup keeps working.
|
|
40
40
|
*/
|
|
41
|
+
/**
|
|
42
|
+
* Decode the entities in a static attribute value.
|
|
43
|
+
*
|
|
44
|
+
* An attribute in a template is HTML source, so `title="Tom & Jerry"` names
|
|
45
|
+
* the string `Tom & Jerry`, and a component that receives it as a prop should
|
|
46
|
+
* see that string rather than the encoding of it.
|
|
47
|
+
*
|
|
48
|
+
* The narrowness is the point. This runs on attribute values, at parse time, and
|
|
49
|
+
* on nothing else: a value that reached a component any other way - from the
|
|
50
|
+
* component's own script, from the parent's context, from a `:bound="expression"`
|
|
51
|
+
* - was never encoded, so decoding it can only destroy escaping somebody meant.
|
|
52
|
+
* That is exactly what a blanket "this looks like HTML, unescape it" pass over
|
|
53
|
+
* the component context used to do, and it turned escaped user text back into
|
|
54
|
+
* live markup.
|
|
55
|
+
*/
|
|
56
|
+
export declare function decodeAttributeEntities(value: string): string;
|
|
41
57
|
export declare function decodeStxProp(attrValue: string, options?: { debug?: boolean }): unknown;
|
|
42
58
|
/**
|
|
43
59
|
* Parse multiline attributes from a component tag
|
|
@@ -113,6 +113,9 @@ export function findComponentTags(html, tagPattern, skipTags) {
|
|
|
113
113
|
}
|
|
114
114
|
return matches;
|
|
115
115
|
}
|
|
116
|
+
export function decodeAttributeEntities(value) {
|
|
117
|
+
return value.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/�?39;/g, "'").replace(/'/gi, "'").replace(/&/g, "&");
|
|
118
|
+
}
|
|
116
119
|
export function decodeStxProp(attrValue, options) {
|
|
117
120
|
try {
|
|
118
121
|
const json = Buffer.from(attrValue, "base64").toString("utf8");
|
|
@@ -606,7 +609,7 @@ export async function processCustomElements(template, context, filePath, compone
|
|
|
606
609
|
props[attrName] = result;
|
|
607
610
|
}
|
|
608
611
|
} else
|
|
609
|
-
props[attrName] = attrValue;
|
|
612
|
+
props[attrName] = decodeAttributeEntities(attrValue);
|
|
610
613
|
}
|
|
611
614
|
const processedContent = await renderComponentWithSlot(componentPath, props, tag.content, componentsDir, context, filePath, options, processedComponents, dependencies);
|
|
612
615
|
result = result.substring(0, tag.startIndex) + processedContent + result.substring(tag.endIndex);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { registry } from "./component-registry.js";
|
|
2
2
|
import { registerBuiltins } from "./builtins/index.js";
|
|
3
|
-
import { decodeStxProp, findComponentTags, parseMultilineAttributes, pascalToKebab, restoreStashedScripts, stashScriptElements } from "./component-processing.js";
|
|
3
|
+
import { decodeAttributeEntities, decodeStxProp, findComponentTags, parseMultilineAttributes, pascalToKebab, restoreStashedScripts, stashScriptElements } from "./component-processing.js";
|
|
4
4
|
import { maskAtElementPosition, matchHtmlComment } from "./html-masking.js";
|
|
5
5
|
import { renderComponentWithSlot, userComponentFileExists } from "./utils.js";
|
|
6
6
|
import { createSafeFunction, isExpressionSafe, safeEvaluateObject } from "./safe-evaluator.js";
|
|
@@ -287,7 +287,7 @@ function parseComponentProps(rawProps, context, options) {
|
|
|
287
287
|
}
|
|
288
288
|
continue;
|
|
289
289
|
}
|
|
290
|
-
setStatic(attrName, attrValue === BOOLEAN_ATTRIBUTE_SENTINEL ? "true" : attrValue);
|
|
290
|
+
setStatic(attrName, attrValue === BOOLEAN_ATTRIBUTE_SENTINEL ? "true" : decodeAttributeEntities(attrValue));
|
|
291
291
|
}
|
|
292
292
|
return resolved;
|
|
293
293
|
}
|
|
@@ -63,7 +63,7 @@ export declare function useDeviceMotion(): DeviceMotionRef;
|
|
|
63
63
|
* })
|
|
64
64
|
* ```
|
|
65
65
|
*/
|
|
66
|
-
export declare function useParallax():
|
|
66
|
+
export declare function useParallax(): ParallaxRef;
|
|
67
67
|
/**
|
|
68
68
|
* Device Orientation & Motion Composables
|
|
69
69
|
*
|
|
@@ -101,6 +101,13 @@ export declare interface DeviceOrientationRef {
|
|
|
101
101
|
isSupported: () => boolean
|
|
102
102
|
requestPermission: () => Promise<boolean>
|
|
103
103
|
}
|
|
104
|
+
/** Handle returned by {@link useParallax}. */
|
|
105
|
+
export declare interface ParallaxRef {
|
|
106
|
+
get: () => { x: number, y: number }
|
|
107
|
+
subscribe: (fn: (state: { x: number, y: number }) => void) => () => void
|
|
108
|
+
isSupported: () => boolean
|
|
109
|
+
requestPermission: () => Promise<boolean>
|
|
110
|
+
}
|
|
104
111
|
export declare interface DeviceMotionRef {
|
|
105
112
|
get: () => DeviceMotionState
|
|
106
113
|
subscribe: (fn: (state: DeviceMotionState) => void) => () => void
|
|
@@ -40,7 +40,7 @@ export declare function useEventSource<T = unknown>(url: string | URL, options?:
|
|
|
40
40
|
* })
|
|
41
41
|
* ```
|
|
42
42
|
*/
|
|
43
|
-
export declare function useSSE<T = unknown>(url: string):
|
|
43
|
+
export declare function useSSE<T = unknown>(url: string): SSERef<T>;
|
|
44
44
|
export declare interface EventSourceState<T = unknown> {
|
|
45
45
|
status: EventSourceStatus
|
|
46
46
|
data: T | null
|
|
@@ -61,6 +61,19 @@ export declare interface EventSourceOptions {
|
|
|
61
61
|
onMessage?: (event: MessageEvent) => void
|
|
62
62
|
onError?: (event: Event) => void
|
|
63
63
|
}
|
|
64
|
+
/** Handle returned by {@link useSSE}. */
|
|
65
|
+
export declare interface SSERef<T = unknown> {
|
|
66
|
+
data: {
|
|
67
|
+
get: () => T | null
|
|
68
|
+
subscribe: (fn: (data: T | null) => void) => () => void
|
|
69
|
+
}
|
|
70
|
+
status: {
|
|
71
|
+
get: () => EventSourceStatus
|
|
72
|
+
subscribe: (fn: (status: EventSourceStatus) => void) => () => void
|
|
73
|
+
}
|
|
74
|
+
close: () => void
|
|
75
|
+
open: () => void
|
|
76
|
+
}
|
|
64
77
|
export declare interface EventSourceRef<T = unknown> {
|
|
65
78
|
get: () => EventSourceState<T>
|
|
66
79
|
subscribe: (fn: (state: EventSourceState<T>) => void) => () => void
|
|
@@ -69,7 +69,7 @@ export declare function hexToHsl(hex: string): { h: number, s: number, l: number
|
|
|
69
69
|
export declare function useColorHistory(options?: {
|
|
70
70
|
maxHistory?: number
|
|
71
71
|
onPick?: (color: string) => void
|
|
72
|
-
}):
|
|
72
|
+
}): ColorHistoryRef;
|
|
73
73
|
/**
|
|
74
74
|
* EyeDropper Composables
|
|
75
75
|
*
|
|
@@ -89,6 +89,15 @@ export declare interface EyeDropperOptions {
|
|
|
89
89
|
onAbort?: () => void
|
|
90
90
|
onError?: (error: Error) => void
|
|
91
91
|
}
|
|
92
|
+
/** Handle returned by {@link useColorHistory}. */
|
|
93
|
+
export declare interface ColorHistoryRef {
|
|
94
|
+
get: () => { current: string | null, history: string[] }
|
|
95
|
+
subscribe: (fn: (state: { current: string | null, history: string[] }) => void) => () => void
|
|
96
|
+
pick: () => Promise<string | null>
|
|
97
|
+
clearHistory: () => void
|
|
98
|
+
removeFromHistory: (color: string) => void
|
|
99
|
+
isSupported: () => boolean
|
|
100
|
+
}
|
|
92
101
|
export declare interface EyeDropperRef {
|
|
93
102
|
get: () => EyeDropperState
|
|
94
103
|
subscribe: (fn: (state: EyeDropperState) => void) => () => void
|
|
@@ -32,7 +32,7 @@ export declare function useIdle(options?: IdleOptions): IdleRef;
|
|
|
32
32
|
* })
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
|
-
export declare function useIdleState(timeout?: number):
|
|
35
|
+
export declare function useIdleState(timeout?: number): IdleStateRef;
|
|
36
36
|
/**
|
|
37
37
|
* Track user's last active timestamp
|
|
38
38
|
*
|
|
@@ -45,7 +45,7 @@ export declare function useIdleState(timeout?: number): void;
|
|
|
45
45
|
* })
|
|
46
46
|
* ```
|
|
47
47
|
*/
|
|
48
|
-
export declare function useLastActive():
|
|
48
|
+
export declare function useLastActive(): LastActiveRef;
|
|
49
49
|
/**
|
|
50
50
|
* Auto-logout after idle timeout
|
|
51
51
|
*
|
|
@@ -57,7 +57,7 @@ export declare function useLastActive(): void;
|
|
|
57
57
|
* })
|
|
58
58
|
* ```
|
|
59
59
|
*/
|
|
60
|
-
export declare function useAutoLogout(timeout: number, onLogout: () => void, options?: { warningTime?: number, onWarning?: (remainingTime: number) => void }):
|
|
60
|
+
export declare function useAutoLogout(timeout: number, onLogout: () => void, options?: { warningTime?: number, onWarning?: (remainingTime: number) => void }): AutoLogoutRef;
|
|
61
61
|
/**
|
|
62
62
|
* Idle Detection Composables
|
|
63
63
|
*
|
|
@@ -82,3 +82,21 @@ export declare interface IdleRef {
|
|
|
82
82
|
reset: () => void
|
|
83
83
|
isIdle: () => boolean
|
|
84
84
|
}
|
|
85
|
+
/** Narrowed view of {@link IdleRef} exposing only the idle flag. */
|
|
86
|
+
export declare interface IdleStateRef {
|
|
87
|
+
get: () => boolean
|
|
88
|
+
subscribe: (fn: (isIdle: boolean) => void) => () => void
|
|
89
|
+
reset: () => void
|
|
90
|
+
}
|
|
91
|
+
/** Narrowed view of {@link IdleRef} exposing only the last-active timestamp. */
|
|
92
|
+
export declare interface LastActiveRef {
|
|
93
|
+
get: () => number
|
|
94
|
+
subscribe: (fn: (timestamp: number) => void) => () => void
|
|
95
|
+
reset: () => void
|
|
96
|
+
}
|
|
97
|
+
/** Handle returned by {@link useAutoLogout}. */
|
|
98
|
+
export declare interface AutoLogoutRef {
|
|
99
|
+
get: () => IdleState
|
|
100
|
+
subscribe: (fn: (state: IdleState) => void) => () => void
|
|
101
|
+
reset: () => void
|
|
102
|
+
}
|
|
@@ -20,12 +20,18 @@
|
|
|
20
20
|
export declare function useStorage<T>(key: string, defaultValue: T, options?: UseStorageOptions<T>): StorageRef<T>;
|
|
21
21
|
/**
|
|
22
22
|
* Shorthand for useStorage with localStorage
|
|
23
|
+
*
|
|
24
|
+
* The return type is annotated rather than inferred on purpose: the shipped
|
|
25
|
+
* declarations are emitted by bun-plugin-dtsx, which resolves an unannotated
|
|
26
|
+
* export to `void`. Consumers importing from `@stacksjs/stx/composables` then
|
|
27
|
+
* got `Property 'value' does not exist on type 'void'` for a function that
|
|
28
|
+
* plainly returns a StorageRef. See stacksjs/stx#1796.
|
|
23
29
|
*/
|
|
24
|
-
export declare function useLocalStorage<T>(key: string, defaultValue: T, options?: Omit<UseStorageOptions<T>, 'storage'>):
|
|
30
|
+
export declare function useLocalStorage<T>(key: string, defaultValue: T, options?: Omit<UseStorageOptions<T>, 'storage'>): StorageRef<T>;
|
|
25
31
|
/**
|
|
26
32
|
* Shorthand for useStorage with sessionStorage
|
|
27
33
|
*/
|
|
28
|
-
export declare function useSessionStorage<T>(key: string, defaultValue: T, options?: Omit<UseStorageOptions<T>, 'storage'>):
|
|
34
|
+
export declare function useSessionStorage<T>(key: string, defaultValue: T, options?: Omit<UseStorageOptions<T>, 'storage'>): StorageRef<T>;
|
|
29
35
|
/**
|
|
30
36
|
* Clear all items from storage
|
|
31
37
|
*/
|
|
@@ -36,7 +36,7 @@ export declare function useTextSelection(options?: TextSelectionOptions): TextSe
|
|
|
36
36
|
* })
|
|
37
37
|
* ```
|
|
38
38
|
*/
|
|
39
|
-
export declare function useElementTextSelection(element: Element | null):
|
|
39
|
+
export declare function useElementTextSelection(element: Element | null): ElementTextSelectionRef;
|
|
40
40
|
/**
|
|
41
41
|
* Create a selection popup that appears when text is selected
|
|
42
42
|
*
|
|
@@ -56,7 +56,7 @@ export declare function useSelectionPopup(options: {
|
|
|
56
56
|
onShow?: (text: string, position: { x: number, y: number }) => void
|
|
57
57
|
onHide?: () => void
|
|
58
58
|
minLength?: number
|
|
59
|
-
}):
|
|
59
|
+
}): SelectionPopupRef;
|
|
60
60
|
/**
|
|
61
61
|
* Copy selected text to clipboard with custom formatting
|
|
62
62
|
*
|
|
@@ -71,7 +71,7 @@ export declare function useSelectionPopup(options: {
|
|
|
71
71
|
* copy.copyWithPrefix('> ')
|
|
72
72
|
* ```
|
|
73
73
|
*/
|
|
74
|
-
export declare function useCopySelection():
|
|
74
|
+
export declare function useCopySelection(): CopySelectionRef;
|
|
75
75
|
/**
|
|
76
76
|
* Text Selection Composables
|
|
77
77
|
*
|
|
@@ -87,6 +87,30 @@ export declare interface TextSelectionOptions {
|
|
|
87
87
|
onSelect?: (state: TextSelectionState) => void
|
|
88
88
|
onClear?: () => void
|
|
89
89
|
}
|
|
90
|
+
/** Handle returned by {@link useElementTextSelection}. */
|
|
91
|
+
export declare interface ElementTextSelectionRef {
|
|
92
|
+
get: () => string
|
|
93
|
+
subscribe: (fn: (text: string) => void) => () => void
|
|
94
|
+
clear: () => void
|
|
95
|
+
selectAll: () => void
|
|
96
|
+
}
|
|
97
|
+
/** Handle returned by {@link useSelectionPopup}. */
|
|
98
|
+
export declare interface SelectionPopupRef {
|
|
99
|
+
get: () => TextSelectionState
|
|
100
|
+
subscribe: (fn: (state: TextSelectionState) => void) => () => void
|
|
101
|
+
isShowing: () => boolean
|
|
102
|
+
}
|
|
103
|
+
/** Handle returned by {@link useCopySelection}. */
|
|
104
|
+
export declare interface CopySelectionRef {
|
|
105
|
+
get: () => TextSelectionState
|
|
106
|
+
subscribe: (fn: (state: TextSelectionState) => void) => () => void
|
|
107
|
+
copy: () => Promise<boolean>
|
|
108
|
+
copyAsMarkdown: () => Promise<boolean>
|
|
109
|
+
copyWithPrefix: (prefix: string) => Promise<boolean>
|
|
110
|
+
copyWithWrapper: (start: string, end: string) => Promise<boolean>
|
|
111
|
+
getText: () => string
|
|
112
|
+
clear: () => void
|
|
113
|
+
}
|
|
90
114
|
export declare interface TextSelectionRef {
|
|
91
115
|
get: () => TextSelectionState
|
|
92
116
|
subscribe: (fn: (state: TextSelectionState) => void) => () => void
|
|
@@ -43,7 +43,7 @@ export declare function useWakeLock(): WakeLockRef;
|
|
|
43
43
|
* })
|
|
44
44
|
* ```
|
|
45
45
|
*/
|
|
46
|
-
export declare function useAutoWakeLock():
|
|
46
|
+
export declare function useAutoWakeLock(): WakeLockRef;
|
|
47
47
|
/**
|
|
48
48
|
* Wake lock that only activates while a condition is true
|
|
49
49
|
*
|
|
@@ -62,7 +62,7 @@ export declare function useAutoWakeLock(): void;
|
|
|
62
62
|
* wakeLock.check() // Releases wake lock
|
|
63
63
|
* ```
|
|
64
64
|
*/
|
|
65
|
-
export declare function useConditionalWakeLock(condition: () => boolean): void;
|
|
65
|
+
export declare function useConditionalWakeLock(condition: () => boolean): WakeLockRef & { check: () => Promise<void> };
|
|
66
66
|
/**
|
|
67
67
|
* Wake Lock Composables
|
|
68
68
|
*
|