svelte-origin 1.0.0-next.23 → 1.0.0-next.25
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.
Potentially problematic release.
This version of svelte-origin might be problematic. Click here for more details.
- package/LLM.md +96 -4
- package/README.md +61 -7
- package/dist/cli.js +578 -37
- package/dist/index.js +578 -37
- package/dist/plugin.js +578 -37
- package/dist/post-process.js +578 -37
- package/dist/preprocess.js +578 -37
- package/dist/transform/attrs-origin-transform.d.ts +15 -0
- package/dist/transform/origin-destructure-transform.d.ts +62 -0
- package/dist/transform/reserved-keywords.d.ts +87 -0
- package/dist/transform/schema.d.ts +11 -4
- package/dist/vite-dts.js +130 -6
- package/package.json +1 -1
|
@@ -6,12 +6,27 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type MagicString from 'magic-string';
|
|
8
8
|
import { type SchemaResolver } from './schema';
|
|
9
|
+
/**
|
|
10
|
+
* Information about a tracked origin instance (for destructuring transform)
|
|
11
|
+
*/
|
|
12
|
+
export interface TrackedOriginInstance {
|
|
13
|
+
/** Variable name holding the origin instance */
|
|
14
|
+
varName: string;
|
|
15
|
+
/** The factory name/expression used to create it */
|
|
16
|
+
factoryExpr: string;
|
|
17
|
+
/** Start position in source */
|
|
18
|
+
startPos: number;
|
|
19
|
+
/** End position in source */
|
|
20
|
+
endPos: number;
|
|
21
|
+
}
|
|
9
22
|
/**
|
|
10
23
|
* Result from transformAttrsOriginCalls including $$Props info for later injection
|
|
11
24
|
*/
|
|
12
25
|
export interface AttrsOriginTransformResult {
|
|
13
26
|
changed: boolean;
|
|
14
27
|
propsTypeDeclaration: string | null;
|
|
28
|
+
/** Tracked origin instances for destructuring transform */
|
|
29
|
+
originInstances: Map<string, TrackedOriginInstance>;
|
|
15
30
|
}
|
|
16
31
|
/**
|
|
17
32
|
* Transform $attrs.origin(X) calls in component scripts (sync fallback version).
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Origin destructuring transformation logic.
|
|
3
|
+
*
|
|
4
|
+
* Handles patterns like:
|
|
5
|
+
* - `let { increment } = counter` - destructure methods with this-binding
|
|
6
|
+
* - `let { value } = counter.props` - destructure props directly
|
|
7
|
+
* - `let { props: { value } } = counter` - nested props destructuring
|
|
8
|
+
* - `let { value = $bindable(0) } = counter.props` - override with bindable
|
|
9
|
+
*
|
|
10
|
+
* Methods are bound to preserve `this` context.
|
|
11
|
+
* Props are converted to reactive $derived values.
|
|
12
|
+
*/
|
|
13
|
+
import type MagicString from 'magic-string';
|
|
14
|
+
import type { TrackedOriginInstance } from './attrs-origin-transform';
|
|
15
|
+
/**
|
|
16
|
+
* Parsed destructuring pattern from origin
|
|
17
|
+
*/
|
|
18
|
+
export interface OriginDestructure {
|
|
19
|
+
/** Full match start position */
|
|
20
|
+
startPos: number;
|
|
21
|
+
/** Full match end position */
|
|
22
|
+
endPos: number;
|
|
23
|
+
/** The source variable being destructured from */
|
|
24
|
+
sourceVar: string;
|
|
25
|
+
/** Whether destructuring from .props (e.g., counter.props) */
|
|
26
|
+
isPropsAccess: boolean;
|
|
27
|
+
/** Destructured method names (need this binding) */
|
|
28
|
+
methods: DestructuredItem[];
|
|
29
|
+
/** Destructured props (need reactive access) */
|
|
30
|
+
props: DestructuredProp[];
|
|
31
|
+
/** Props pattern within nested `props: { ... }` */
|
|
32
|
+
nestedPropsPattern: NestedPropsPattern | null;
|
|
33
|
+
}
|
|
34
|
+
export interface DestructuredItem {
|
|
35
|
+
/** Original key in the origin */
|
|
36
|
+
key: string;
|
|
37
|
+
/** Alias if renamed (e.g., `increment: inc`) */
|
|
38
|
+
alias: string | null;
|
|
39
|
+
/** Default value if provided */
|
|
40
|
+
defaultValue: string | null;
|
|
41
|
+
}
|
|
42
|
+
export interface DestructuredProp extends DestructuredItem {
|
|
43
|
+
/** Whether $bindable() was used in the default */
|
|
44
|
+
isBindable: boolean;
|
|
45
|
+
/** The value inside $bindable() if bindable */
|
|
46
|
+
bindableDefault: string | null;
|
|
47
|
+
}
|
|
48
|
+
export interface NestedPropsPattern {
|
|
49
|
+
/** Start of the `props: { ... }` pattern */
|
|
50
|
+
startPos: number;
|
|
51
|
+
/** End of the `props: { ... }` pattern */
|
|
52
|
+
endPos: number;
|
|
53
|
+
/** Props within the nested pattern */
|
|
54
|
+
props: DestructuredProp[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Transform origin destructuring patterns in the source.
|
|
58
|
+
*
|
|
59
|
+
* Tracks origin instances created via $attrs.origin() or direct factory calls,
|
|
60
|
+
* then transforms destructuring patterns that reference them.
|
|
61
|
+
*/
|
|
62
|
+
export declare function transformOriginDestructuring(s: MagicString, source: string, originInstances: Map<string, TrackedOriginInstance>): boolean;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reserved keyword handling for generated code.
|
|
3
|
+
*
|
|
4
|
+
* JavaScript/TypeScript reserved keywords cannot be used as bare identifiers
|
|
5
|
+
* in destructuring patterns. When a prop name is a reserved keyword (like 'class'),
|
|
6
|
+
* we need to use a renamed internal variable.
|
|
7
|
+
*
|
|
8
|
+
* Example:
|
|
9
|
+
* ```ts
|
|
10
|
+
* // This is INVALID:
|
|
11
|
+
* let { class = '' } = $props()
|
|
12
|
+
*
|
|
13
|
+
* // This is VALID:
|
|
14
|
+
* let { class: ___class = '' } = $props()
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Check if a string is a reserved keyword that needs renaming
|
|
19
|
+
*/
|
|
20
|
+
export declare function isReservedKeyword(name: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Get the internal variable name for a prop.
|
|
23
|
+
*
|
|
24
|
+
* For reserved keywords and collision prevention, we prefix with `___`.
|
|
25
|
+
* This ensures the generated code is valid JavaScript.
|
|
26
|
+
*
|
|
27
|
+
* @param propName The original prop name
|
|
28
|
+
* @param forcePrefix If true, always add prefix (for collision prevention)
|
|
29
|
+
* @returns The internal variable name to use
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* getInternalVarName('class') // '___class'
|
|
33
|
+
* getInternalVarName('value') // '___value'
|
|
34
|
+
* getInternalVarName('count', true) // '___count'
|
|
35
|
+
*/
|
|
36
|
+
export declare function getInternalVarName(propName: string, forcePrefix?: boolean): string;
|
|
37
|
+
/**
|
|
38
|
+
* Generate the prop destructuring part for a single prop.
|
|
39
|
+
* Handles reserved keywords by using property renaming.
|
|
40
|
+
*
|
|
41
|
+
* @param propName The original prop name
|
|
42
|
+
* @param defaultValue The default value expression (already formatted)
|
|
43
|
+
* @returns The destructuring part for this prop
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* // Reserved keyword
|
|
47
|
+
* generatePropDestructure('class', "''")
|
|
48
|
+
* // Returns: "class: ___class = ''"
|
|
49
|
+
*
|
|
50
|
+
* // Normal prop
|
|
51
|
+
* generatePropDestructure('value', '$bindable()')
|
|
52
|
+
* // Returns: "value: ___value = $bindable()"
|
|
53
|
+
*/
|
|
54
|
+
export declare function generatePropDestructure(propName: string, defaultValue: string): string;
|
|
55
|
+
/**
|
|
56
|
+
* Generate the prop destructuring part for a prop without a default value.
|
|
57
|
+
*
|
|
58
|
+
* @param propName The original prop name
|
|
59
|
+
* @returns The destructuring part for this prop
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* generatePropDestructureNoDefault('class')
|
|
63
|
+
* // Returns: "class: ___class"
|
|
64
|
+
*/
|
|
65
|
+
export declare function generatePropDestructureNoDefault(propName: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* Generate a getter for the reactive attrs wrapper.
|
|
68
|
+
*
|
|
69
|
+
* @param propName The original prop name
|
|
70
|
+
* @returns The getter definition
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* generateGetter('class')
|
|
74
|
+
* // Returns: "get class() { return ___class }"
|
|
75
|
+
*/
|
|
76
|
+
export declare function generateGetter(propName: string): string;
|
|
77
|
+
/**
|
|
78
|
+
* Generate a setter for the reactive attrs wrapper.
|
|
79
|
+
*
|
|
80
|
+
* @param propName The original prop name
|
|
81
|
+
* @returns The setter definition
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* generateSetter('class')
|
|
85
|
+
* // Returns: "set class(v) { ___class = v }"
|
|
86
|
+
*/
|
|
87
|
+
export declare function generateSetter(propName: string): string;
|
|
@@ -64,12 +64,16 @@ export declare function parseAttrsSchemaFromSource(source: string, exportName: s
|
|
|
64
64
|
* to the factory type. This approach is required for svelte-check to properly
|
|
65
65
|
* infer component props from the origin factory definition.
|
|
66
66
|
*
|
|
67
|
+
* All props use internal variable names (prefixed with ___) to:
|
|
68
|
+
* 1. Avoid reserved keyword conflicts (e.g., 'class' -> 'class: ___class')
|
|
69
|
+
* 2. Prevent accidental naming collisions with user code
|
|
70
|
+
*
|
|
67
71
|
* @example
|
|
68
72
|
* generatePropsDestructuring([
|
|
69
|
-
* { key: '
|
|
73
|
+
* { key: 'class', defaultValue: "''", bindable: false, hasDefault: true },
|
|
70
74
|
* { key: 'count', defaultValue: '0', bindable: true, hasDefault: true }
|
|
71
75
|
* ], 'Counter')
|
|
72
|
-
* // Returns: "let {
|
|
76
|
+
* // Returns: "let { class: ___class = '', count: ___count = $bindable(0) }: $attrs.Of<typeof Counter> = $props()"
|
|
73
77
|
*/
|
|
74
78
|
export declare function generatePropsDestructuring(attrs: ParsedAttrInfo[], factoryName: string): string;
|
|
75
79
|
/**
|
|
@@ -77,12 +81,15 @@ export declare function generatePropsDestructuring(attrs: ParsedAttrInfo[], fact
|
|
|
77
81
|
* For bindable attrs, we create getters AND setters to maintain two-way binding.
|
|
78
82
|
* For non-bindable attrs, we only create getters.
|
|
79
83
|
*
|
|
84
|
+
* Getters/setters reference internal variable names (___key) that were
|
|
85
|
+
* destructured from $props().
|
|
86
|
+
*
|
|
80
87
|
* @example
|
|
81
88
|
* generateFactoryCallFromAttrs('Counter', [
|
|
82
|
-
* { key: '
|
|
89
|
+
* { key: 'class', defaultValue: "''", bindable: false, hasDefault: true },
|
|
83
90
|
* { key: 'count', defaultValue: '0', bindable: true, hasDefault: true }
|
|
84
91
|
* ])
|
|
85
|
-
* // Returns: "Counter({ get
|
|
92
|
+
* // Returns: "Counter({ get class() { return ___class }, get count() { return ___count }, set count(v) { ___count = v } })"
|
|
86
93
|
*/
|
|
87
94
|
export declare function generateFactoryCallFromAttrs(factoryName: string, attrs: ParsedAttrInfo[]): string;
|
|
88
95
|
/**
|
package/dist/vite-dts.js
CHANGED
|
@@ -200,6 +200,79 @@ function findMatchingBracket(source, openIndex, openChar = "(", closeChar = ")")
|
|
|
200
200
|
return -1;
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
+
// src/transform/reserved-keywords.ts
|
|
204
|
+
var RESERVED_KEYWORDS = new Set([
|
|
205
|
+
"break",
|
|
206
|
+
"case",
|
|
207
|
+
"catch",
|
|
208
|
+
"continue",
|
|
209
|
+
"debugger",
|
|
210
|
+
"default",
|
|
211
|
+
"delete",
|
|
212
|
+
"do",
|
|
213
|
+
"else",
|
|
214
|
+
"finally",
|
|
215
|
+
"for",
|
|
216
|
+
"function",
|
|
217
|
+
"if",
|
|
218
|
+
"in",
|
|
219
|
+
"instanceof",
|
|
220
|
+
"new",
|
|
221
|
+
"return",
|
|
222
|
+
"switch",
|
|
223
|
+
"this",
|
|
224
|
+
"throw",
|
|
225
|
+
"try",
|
|
226
|
+
"typeof",
|
|
227
|
+
"var",
|
|
228
|
+
"void",
|
|
229
|
+
"while",
|
|
230
|
+
"with",
|
|
231
|
+
"class",
|
|
232
|
+
"const",
|
|
233
|
+
"enum",
|
|
234
|
+
"export",
|
|
235
|
+
"extends",
|
|
236
|
+
"import",
|
|
237
|
+
"super",
|
|
238
|
+
"implements",
|
|
239
|
+
"interface",
|
|
240
|
+
"let",
|
|
241
|
+
"package",
|
|
242
|
+
"private",
|
|
243
|
+
"protected",
|
|
244
|
+
"public",
|
|
245
|
+
"static",
|
|
246
|
+
"yield",
|
|
247
|
+
"await",
|
|
248
|
+
"async",
|
|
249
|
+
"true",
|
|
250
|
+
"false",
|
|
251
|
+
"null",
|
|
252
|
+
"undefined",
|
|
253
|
+
"arguments",
|
|
254
|
+
"eval"
|
|
255
|
+
]);
|
|
256
|
+
function getInternalVarName(propName, forcePrefix = true) {
|
|
257
|
+
return `___${propName}`;
|
|
258
|
+
}
|
|
259
|
+
function generatePropDestructure(propName, defaultValue) {
|
|
260
|
+
const internalName = getInternalVarName(propName);
|
|
261
|
+
return `${propName}: ${internalName} = ${defaultValue}`;
|
|
262
|
+
}
|
|
263
|
+
function generatePropDestructureNoDefault(propName) {
|
|
264
|
+
const internalName = getInternalVarName(propName);
|
|
265
|
+
return `${propName}: ${internalName}`;
|
|
266
|
+
}
|
|
267
|
+
function generateGetter(propName) {
|
|
268
|
+
const internalName = getInternalVarName(propName);
|
|
269
|
+
return `get ${propName}() { return ${internalName} }`;
|
|
270
|
+
}
|
|
271
|
+
function generateSetter(propName) {
|
|
272
|
+
const internalName = getInternalVarName(propName);
|
|
273
|
+
return `set ${propName}(v) { ${internalName} = v }`;
|
|
274
|
+
}
|
|
275
|
+
|
|
203
276
|
// src/transform/schema.ts
|
|
204
277
|
function parseOriginSchemaFromSource(source, exportName) {
|
|
205
278
|
const sourceResult = parseSourceOrigin(source, exportName);
|
|
@@ -426,6 +499,7 @@ function parseAttrsContent(content) {
|
|
|
426
499
|
continue;
|
|
427
500
|
const key = trimmed.slice(0, colonIndex).trim();
|
|
428
501
|
let value = trimmed.slice(colonIndex + 1).trim();
|
|
502
|
+
value = stripTrailingComments(value);
|
|
429
503
|
const asIndex = findTopLevelAs(value);
|
|
430
504
|
if (asIndex !== -1) {
|
|
431
505
|
value = value.slice(0, asIndex).trim();
|
|
@@ -533,19 +607,69 @@ function stripComments(str) {
|
|
|
533
607
|
}
|
|
534
608
|
return result;
|
|
535
609
|
}
|
|
610
|
+
function stripTrailingComments(str) {
|
|
611
|
+
let result = str.trim();
|
|
612
|
+
let i = 0;
|
|
613
|
+
while (i < result.length) {
|
|
614
|
+
const char = result[i];
|
|
615
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
616
|
+
const quote = char;
|
|
617
|
+
i++;
|
|
618
|
+
while (i < result.length && result[i] !== quote) {
|
|
619
|
+
if (result[i] === "\\")
|
|
620
|
+
i++;
|
|
621
|
+
i++;
|
|
622
|
+
}
|
|
623
|
+
i++;
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
if (char === "{" || char === "(" || char === "[") {
|
|
627
|
+
let depth = 1;
|
|
628
|
+
i++;
|
|
629
|
+
while (i < result.length && depth > 0) {
|
|
630
|
+
const c = result[i];
|
|
631
|
+
if (c === "{" || c === "(" || c === "[")
|
|
632
|
+
depth++;
|
|
633
|
+
else if (c === "}" || c === ")" || c === "]")
|
|
634
|
+
depth--;
|
|
635
|
+
else if (c === '"' || c === "'" || c === "`") {
|
|
636
|
+
const quote = c;
|
|
637
|
+
i++;
|
|
638
|
+
while (i < result.length && result[i] !== quote) {
|
|
639
|
+
if (result[i] === "\\")
|
|
640
|
+
i++;
|
|
641
|
+
i++;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
i++;
|
|
645
|
+
}
|
|
646
|
+
continue;
|
|
647
|
+
}
|
|
648
|
+
if (char === "/" && result[i + 1] === "*") {
|
|
649
|
+
result = result.slice(0, i).trim();
|
|
650
|
+
break;
|
|
651
|
+
}
|
|
652
|
+
if (char === "/" && result[i + 1] === "/") {
|
|
653
|
+
result = result.slice(0, i).trim();
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
i++;
|
|
657
|
+
}
|
|
658
|
+
return result;
|
|
659
|
+
}
|
|
536
660
|
function generatePropsDestructuring(attrs, factoryName) {
|
|
537
661
|
const parts = [];
|
|
538
662
|
for (const attr of attrs) {
|
|
539
663
|
if (attr.bindable) {
|
|
540
664
|
if (attr.hasDefault) {
|
|
541
|
-
parts.push(
|
|
665
|
+
parts.push(generatePropDestructure(attr.key, `$bindable(${attr.defaultValue})`));
|
|
542
666
|
} else {
|
|
543
|
-
parts.push(
|
|
667
|
+
parts.push(generatePropDestructure(attr.key, "$bindable()"));
|
|
544
668
|
}
|
|
545
669
|
} else if (attr.hasDefault) {
|
|
546
|
-
parts.push(
|
|
670
|
+
parts.push(generatePropDestructure(attr.key, attr.defaultValue));
|
|
547
671
|
} else {
|
|
548
|
-
parts.push(attr.key);
|
|
672
|
+
parts.push(generatePropDestructureNoDefault(attr.key));
|
|
549
673
|
}
|
|
550
674
|
}
|
|
551
675
|
return `let { ${parts.join(", ")} }: $attrs.Of<typeof ${factoryName}> = $props()`;
|
|
@@ -553,9 +677,9 @@ function generatePropsDestructuring(attrs, factoryName) {
|
|
|
553
677
|
function generateFactoryCallFromAttrs(factoryName, attrs) {
|
|
554
678
|
const parts = [];
|
|
555
679
|
for (const attr of attrs) {
|
|
556
|
-
parts.push(
|
|
680
|
+
parts.push(generateGetter(attr.key));
|
|
557
681
|
if (attr.bindable) {
|
|
558
|
-
parts.push(
|
|
682
|
+
parts.push(generateSetter(attr.key));
|
|
559
683
|
}
|
|
560
684
|
}
|
|
561
685
|
return `${factoryName}({ ${parts.join(", ")} })`;
|