@aerobuilt/core 0.2.1 → 0.2.3
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-5GK7XRII.js → chunk-4DAK56WB.js} +1 -1
- package/dist/{chunk-3OZCI7DL.js → chunk-5ZNUGZOW.js} +1 -1
- package/dist/{chunk-7A3WBPH4.js → chunk-JAMYN2VX.js} +55 -19
- package/dist/chunk-VTEG2UU3.js +184 -0
- package/dist/entry-dev.js +3 -3
- package/dist/entry-editor.d.ts +72 -0
- package/dist/entry-editor.js +14 -0
- package/dist/entry-prod.js +2 -2
- package/dist/runtime/index.js +2 -2
- package/dist/runtime/instance.js +3 -3
- package/dist/vite/index.js +179 -261
- package/package.json +14 -3
|
@@ -11,6 +11,57 @@ function toPosixRelative(value, root) {
|
|
|
11
11
|
return valuePosix;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
// src/utils/route-pattern.ts
|
|
15
|
+
var PARAM_SEGMENT_REGEX = /^\[([^.\]\[]+)\]$/;
|
|
16
|
+
function parseRoutePattern(pattern) {
|
|
17
|
+
const rawSegments = pattern.split("/").filter(Boolean);
|
|
18
|
+
const segments = rawSegments.map((seg) => {
|
|
19
|
+
const paramMatch = seg.match(PARAM_SEGMENT_REGEX);
|
|
20
|
+
if (paramMatch) {
|
|
21
|
+
return { type: "param", name: paramMatch[1] };
|
|
22
|
+
}
|
|
23
|
+
return { type: "static", value: seg };
|
|
24
|
+
});
|
|
25
|
+
return { segments };
|
|
26
|
+
}
|
|
27
|
+
function isDynamicRoutePattern(pattern) {
|
|
28
|
+
const { segments } = parseRoutePattern(pattern);
|
|
29
|
+
return segments.some((s) => s.type === "param");
|
|
30
|
+
}
|
|
31
|
+
function matchRoutePattern(pattern, pageName) {
|
|
32
|
+
const { segments } = parseRoutePattern(pattern);
|
|
33
|
+
const requestedSegments = pageName.split("/").filter(Boolean);
|
|
34
|
+
if (segments.length !== requestedSegments.length) return null;
|
|
35
|
+
const params = {};
|
|
36
|
+
for (let i = 0; i < segments.length; i++) {
|
|
37
|
+
const seg = segments[i];
|
|
38
|
+
const requestSeg = requestedSegments[i];
|
|
39
|
+
if (seg.type === "param") {
|
|
40
|
+
params[seg.name] = decodeURIComponent(requestSeg);
|
|
41
|
+
} else if (seg.value !== requestSeg) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return params;
|
|
46
|
+
}
|
|
47
|
+
function expandRoutePattern(pattern, params) {
|
|
48
|
+
const { segments } = parseRoutePattern(pattern);
|
|
49
|
+
const parts = [];
|
|
50
|
+
for (const seg of segments) {
|
|
51
|
+
if (seg.type === "param") {
|
|
52
|
+
if (!(seg.name in params)) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`[aero] getStaticPaths: missing param "${seg.name}" for pattern "${pattern}". Provided params: ${JSON.stringify(params)}`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
parts.push(params[seg.name]);
|
|
58
|
+
} else {
|
|
59
|
+
parts.push(seg.value);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return parts.join("/");
|
|
63
|
+
}
|
|
64
|
+
|
|
14
65
|
// src/utils/routing.ts
|
|
15
66
|
function pagePathToKey(path) {
|
|
16
67
|
const withoutExt = toPosix(path).replace(/\.html$/i, "");
|
|
@@ -35,27 +86,10 @@ function resolvePageName(url) {
|
|
|
35
86
|
return clean || "index";
|
|
36
87
|
}
|
|
37
88
|
function resolveDynamicPage(pageName, pagesMap) {
|
|
38
|
-
const requestedSegments = pageName.split("/").filter(Boolean);
|
|
39
89
|
for (const [key, mod] of Object.entries(pagesMap)) {
|
|
40
90
|
if (!key.includes("[") || !key.includes("]") || key.includes(".")) continue;
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
43
|
-
const params = {};
|
|
44
|
-
let matched = true;
|
|
45
|
-
for (let i = 0; i < keySegments.length; i++) {
|
|
46
|
-
const routeSegment = keySegments[i];
|
|
47
|
-
const requestSegment = requestedSegments[i];
|
|
48
|
-
const dynamicMatch = routeSegment.match(/^\[(.+)\]$/);
|
|
49
|
-
if (dynamicMatch) {
|
|
50
|
-
params[dynamicMatch[1]] = decodeURIComponent(requestSegment);
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
if (routeSegment !== requestSegment) {
|
|
54
|
-
matched = false;
|
|
55
|
-
break;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (matched) {
|
|
91
|
+
const params = matchRoutePattern(key, pageName);
|
|
92
|
+
if (params != null) {
|
|
59
93
|
return { module: mod, pageName: key, params };
|
|
60
94
|
}
|
|
61
95
|
}
|
|
@@ -91,6 +125,8 @@ function resolvePageTarget(component, pagesMap) {
|
|
|
91
125
|
export {
|
|
92
126
|
toPosix,
|
|
93
127
|
toPosixRelative,
|
|
128
|
+
isDynamicRoutePattern,
|
|
129
|
+
expandRoutePattern,
|
|
94
130
|
pagePathToKey,
|
|
95
131
|
resolvePageName,
|
|
96
132
|
resolvePageTarget
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// src/compiler/tokenizer.ts
|
|
2
|
+
import {
|
|
3
|
+
tokenizeCurlyInterpolation,
|
|
4
|
+
compileInterpolationFromSegments
|
|
5
|
+
} from "@aerobuilt/interpolation";
|
|
6
|
+
|
|
7
|
+
// src/compiler/directive-attributes.ts
|
|
8
|
+
var DEFAULT_DIRECTIVE_PREFIXES = ["x-", "@", ":", "."];
|
|
9
|
+
var defaultConfig = {
|
|
10
|
+
prefixes: DEFAULT_DIRECTIVE_PREFIXES,
|
|
11
|
+
exactNames: []
|
|
12
|
+
};
|
|
13
|
+
function isDirectiveAttr(attrName, config = defaultConfig) {
|
|
14
|
+
const prefixes = config.prefixes ?? defaultConfig.prefixes;
|
|
15
|
+
const exactNames = config.exactNames ?? defaultConfig.exactNames;
|
|
16
|
+
if (exactNames.includes(attrName)) return true;
|
|
17
|
+
return prefixes.some((p) => attrName.startsWith(p));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/compiler/build-script-analysis.ts
|
|
21
|
+
import { parseSync, ImportNameKind } from "oxc-parser";
|
|
22
|
+
var BUILD_SCRIPT_FILENAME = "build.ts";
|
|
23
|
+
function analyzeBuildScript(script) {
|
|
24
|
+
if (!script.trim()) {
|
|
25
|
+
return {
|
|
26
|
+
imports: [],
|
|
27
|
+
getStaticPathsFn: null,
|
|
28
|
+
scriptWithoutImportsAndGetStaticPaths: script
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const result = parseSync(BUILD_SCRIPT_FILENAME, script, {
|
|
32
|
+
sourceType: "module",
|
|
33
|
+
range: true,
|
|
34
|
+
lang: "ts"
|
|
35
|
+
});
|
|
36
|
+
const errors = result.errors;
|
|
37
|
+
if (errors.length > 0) {
|
|
38
|
+
const first = errors[0];
|
|
39
|
+
throw new Error(
|
|
40
|
+
`[aero] Build script parse error: ${first.message}${first.codeframe ? "\n" + first.codeframe : ""}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
const mod = result.module;
|
|
44
|
+
const program = result.program;
|
|
45
|
+
const imports = [];
|
|
46
|
+
for (const imp of mod.staticImports) {
|
|
47
|
+
const specifier = imp.moduleRequest.value;
|
|
48
|
+
let defaultBinding = null;
|
|
49
|
+
const namedBindings = [];
|
|
50
|
+
let namespaceBinding = null;
|
|
51
|
+
for (const entry of imp.entries) {
|
|
52
|
+
if (entry.isType) continue;
|
|
53
|
+
const local = entry.localName.value;
|
|
54
|
+
switch (entry.importName.kind) {
|
|
55
|
+
case ImportNameKind.Default:
|
|
56
|
+
defaultBinding = local;
|
|
57
|
+
break;
|
|
58
|
+
case ImportNameKind.NamespaceObject:
|
|
59
|
+
namespaceBinding = local;
|
|
60
|
+
break;
|
|
61
|
+
case ImportNameKind.Name: {
|
|
62
|
+
const imported = entry.importName.name ?? local;
|
|
63
|
+
namedBindings.push({ imported, local });
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
default:
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
imports.push({
|
|
71
|
+
specifier,
|
|
72
|
+
defaultBinding,
|
|
73
|
+
namedBindings,
|
|
74
|
+
namespaceBinding
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
let getStaticPathsRange = null;
|
|
78
|
+
const body = program.body;
|
|
79
|
+
if (body) {
|
|
80
|
+
for (const stmt of body) {
|
|
81
|
+
if (stmt.type !== "ExportNamedDeclaration") continue;
|
|
82
|
+
const decl = stmt.declaration;
|
|
83
|
+
if (!decl || decl.type !== "FunctionDeclaration") continue;
|
|
84
|
+
const name = decl.id?.name;
|
|
85
|
+
if (name !== "getStaticPaths") continue;
|
|
86
|
+
const range = stmt.range;
|
|
87
|
+
if (range) {
|
|
88
|
+
getStaticPathsRange = range;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const getStaticPathsFn = getStaticPathsRange !== null ? script.slice(getStaticPathsRange[0], getStaticPathsRange[1]) : null;
|
|
94
|
+
const rangesToRemove = [];
|
|
95
|
+
if (getStaticPathsRange) {
|
|
96
|
+
rangesToRemove.push(getStaticPathsRange);
|
|
97
|
+
}
|
|
98
|
+
for (const imp of mod.staticImports) {
|
|
99
|
+
rangesToRemove.push([imp.start, imp.end]);
|
|
100
|
+
}
|
|
101
|
+
rangesToRemove.sort((a, b) => a[0] - b[0]);
|
|
102
|
+
const parts = [];
|
|
103
|
+
let lastEnd = 0;
|
|
104
|
+
for (const [start, end] of rangesToRemove) {
|
|
105
|
+
if (start > lastEnd) {
|
|
106
|
+
parts.push(script.slice(lastEnd, start));
|
|
107
|
+
}
|
|
108
|
+
lastEnd = end;
|
|
109
|
+
}
|
|
110
|
+
if (lastEnd < script.length) {
|
|
111
|
+
parts.push(script.slice(lastEnd));
|
|
112
|
+
}
|
|
113
|
+
const scriptWithoutImportsAndGetStaticPaths = parts.join("").trim();
|
|
114
|
+
return {
|
|
115
|
+
imports,
|
|
116
|
+
getStaticPathsFn,
|
|
117
|
+
scriptWithoutImportsAndGetStaticPaths
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function analyzeBuildScriptForEditor(script) {
|
|
121
|
+
if (!script.trim()) {
|
|
122
|
+
return { imports: [] };
|
|
123
|
+
}
|
|
124
|
+
const result = parseSync(BUILD_SCRIPT_FILENAME, script, {
|
|
125
|
+
sourceType: "module",
|
|
126
|
+
range: true,
|
|
127
|
+
lang: "ts"
|
|
128
|
+
});
|
|
129
|
+
const errors = result.errors;
|
|
130
|
+
if (errors.length > 0) {
|
|
131
|
+
const first = errors[0];
|
|
132
|
+
throw new Error(
|
|
133
|
+
`[aero] Build script parse error: ${first.message}${first.codeframe ? "\n" + first.codeframe : ""}`
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
const mod = result.module;
|
|
137
|
+
const imports = [];
|
|
138
|
+
for (const imp of mod.staticImports) {
|
|
139
|
+
const specifier = imp.moduleRequest.value;
|
|
140
|
+
let defaultBinding = null;
|
|
141
|
+
const namedBindings = [];
|
|
142
|
+
let namespaceBinding = null;
|
|
143
|
+
const bindingRanges = {};
|
|
144
|
+
for (const entry of imp.entries) {
|
|
145
|
+
if (entry.isType) continue;
|
|
146
|
+
const local = entry.localName.value;
|
|
147
|
+
bindingRanges[local] = [entry.localName.start, entry.localName.end];
|
|
148
|
+
switch (entry.importName.kind) {
|
|
149
|
+
case ImportNameKind.Default:
|
|
150
|
+
defaultBinding = local;
|
|
151
|
+
break;
|
|
152
|
+
case ImportNameKind.NamespaceObject:
|
|
153
|
+
namespaceBinding = local;
|
|
154
|
+
break;
|
|
155
|
+
case ImportNameKind.Name: {
|
|
156
|
+
const imported = entry.importName.name ?? local;
|
|
157
|
+
namedBindings.push({ imported, local });
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
default:
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
imports.push({
|
|
165
|
+
specifier,
|
|
166
|
+
defaultBinding,
|
|
167
|
+
namedBindings,
|
|
168
|
+
namespaceBinding,
|
|
169
|
+
range: [imp.start, imp.end],
|
|
170
|
+
specifierRange: [imp.moduleRequest.start, imp.moduleRequest.end],
|
|
171
|
+
bindingRanges
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return { imports };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export {
|
|
178
|
+
tokenizeCurlyInterpolation,
|
|
179
|
+
compileInterpolationFromSegments,
|
|
180
|
+
DEFAULT_DIRECTIVE_PREFIXES,
|
|
181
|
+
isDirectiveAttr,
|
|
182
|
+
analyzeBuildScript,
|
|
183
|
+
analyzeBuildScriptForEditor
|
|
184
|
+
};
|
package/dist/entry-dev.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
aero,
|
|
3
3
|
onUpdate
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-4DAK56WB.js";
|
|
5
|
+
import "./chunk-5ZNUGZOW.js";
|
|
6
6
|
import {
|
|
7
7
|
resolvePageName
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-JAMYN2VX.js";
|
|
9
9
|
|
|
10
10
|
// src/runtime/client.ts
|
|
11
11
|
function extractDocumentParts(html) {
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export { InterpolationSegment, LiteralSegment, Segment, TokenizeOptions, compileInterpolationFromSegments, tokenizeCurlyInterpolation } from '@aerobuilt/interpolation';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Classifier for directive attributes (Alpine.js, HTMX, Vue, etc.) that should
|
|
5
|
+
* skip { } interpolation in the compiler. Replaces ALPINE_ATTR_REGEX with a
|
|
6
|
+
* declarative list for clearer semantics and easier extension.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Configurable list of directive attribute prefixes and optional exact names.
|
|
12
|
+
* Prefixes are checked with attrName.startsWith(prefix); single-char prefixes
|
|
13
|
+
* like @, :, . match event and binding syntax.
|
|
14
|
+
*/
|
|
15
|
+
interface DirectiveAttrConfig {
|
|
16
|
+
/** Prefixes that identify directive attributes (e.g. 'x-', '@', 'hx-'). */
|
|
17
|
+
prefixes?: string[];
|
|
18
|
+
/** Exact attribute names to treat as directives. */
|
|
19
|
+
exactNames?: string[];
|
|
20
|
+
}
|
|
21
|
+
/** Default prefixes: Alpine.js (x-*) and shorthand (@, :, .). */
|
|
22
|
+
declare const DEFAULT_DIRECTIVE_PREFIXES: string[];
|
|
23
|
+
/**
|
|
24
|
+
* Returns true if the attribute name is a directive that should skip
|
|
25
|
+
* { } interpolation (e.g. Alpine x-model, :disabled, @click).
|
|
26
|
+
*
|
|
27
|
+
* @param attrName - HTML attribute name (e.g. 'x-data', ':disabled').
|
|
28
|
+
* @param config - Optional config; uses default Alpine/shorthand prefixes when omitted.
|
|
29
|
+
*/
|
|
30
|
+
declare function isDirectiveAttr(attrName: string, config?: DirectiveAttrConfig): boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* AST-based analysis of Aero build scripts: extract imports and getStaticPaths export.
|
|
34
|
+
*
|
|
35
|
+
* @remarks
|
|
36
|
+
* Uses oxc-parser (TypeScript-capable) so the same pipeline supports JS and TS in
|
|
37
|
+
* `<script is:build>`. Returns structured data for codegen to rewrite imports and
|
|
38
|
+
* emit getStaticPaths as a named export.
|
|
39
|
+
*/
|
|
40
|
+
/** Single import entry for codegen: specifier and bindings. */
|
|
41
|
+
interface BuildScriptImport {
|
|
42
|
+
specifier: string;
|
|
43
|
+
defaultBinding: string | null;
|
|
44
|
+
namedBindings: Array<{
|
|
45
|
+
imported: string;
|
|
46
|
+
local: string;
|
|
47
|
+
}>;
|
|
48
|
+
namespaceBinding: string | null;
|
|
49
|
+
}
|
|
50
|
+
/** Editor-oriented import entry: same bindings as BuildScriptImport plus source range and per-binding ranges. */
|
|
51
|
+
interface BuildScriptImportForEditor extends BuildScriptImport {
|
|
52
|
+
/** Character range of the full import statement [start, end]. */
|
|
53
|
+
range: [number, number];
|
|
54
|
+
/** Character range of the specifier string (path) within the script. */
|
|
55
|
+
specifierRange: [number, number];
|
|
56
|
+
/** Per-binding character ranges: local name -> [start, end]. */
|
|
57
|
+
bindingRanges?: Record<string, [number, number]>;
|
|
58
|
+
}
|
|
59
|
+
/** Result of analyzeBuildScriptForEditor: imports with source ranges for editor use (e.g. definition provider). */
|
|
60
|
+
interface BuildScriptAnalysisForEditorResult {
|
|
61
|
+
imports: BuildScriptImportForEditor[];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Analyze build script for editor use: same as analyzeBuildScript but returns imports with
|
|
65
|
+
* source ranges (full statement and per-binding) so the extension can map to vscode.Range.
|
|
66
|
+
*
|
|
67
|
+
* @param script - Raw build script content (JS or TS).
|
|
68
|
+
* @returns Imports with range and bindingRanges. On parse error, throws.
|
|
69
|
+
*/
|
|
70
|
+
declare function analyzeBuildScriptForEditor(script: string): BuildScriptAnalysisForEditorResult;
|
|
71
|
+
|
|
72
|
+
export { type BuildScriptAnalysisForEditorResult, type BuildScriptImportForEditor, DEFAULT_DIRECTIVE_PREFIXES, type DirectiveAttrConfig, analyzeBuildScriptForEditor, isDirectiveAttr };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_DIRECTIVE_PREFIXES,
|
|
3
|
+
analyzeBuildScriptForEditor,
|
|
4
|
+
compileInterpolationFromSegments,
|
|
5
|
+
isDirectiveAttr,
|
|
6
|
+
tokenizeCurlyInterpolation
|
|
7
|
+
} from "./chunk-VTEG2UU3.js";
|
|
8
|
+
export {
|
|
9
|
+
DEFAULT_DIRECTIVE_PREFIXES,
|
|
10
|
+
analyzeBuildScriptForEditor,
|
|
11
|
+
compileInterpolationFromSegments,
|
|
12
|
+
isDirectiveAttr,
|
|
13
|
+
tokenizeCurlyInterpolation
|
|
14
|
+
};
|
package/dist/entry-prod.js
CHANGED
package/dist/runtime/index.js
CHANGED
package/dist/runtime/instance.js
CHANGED
package/dist/vite/index.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
+
analyzeBuildScript,
|
|
3
|
+
compileInterpolationFromSegments,
|
|
4
|
+
isDirectiveAttr,
|
|
5
|
+
tokenizeCurlyInterpolation
|
|
6
|
+
} from "../chunk-VTEG2UU3.js";
|
|
7
|
+
import {
|
|
8
|
+
expandRoutePattern,
|
|
9
|
+
isDynamicRoutePattern,
|
|
2
10
|
pagePathToKey,
|
|
3
11
|
resolvePageName,
|
|
4
12
|
toPosix,
|
|
5
13
|
toPosixRelative
|
|
6
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-JAMYN2VX.js";
|
|
7
15
|
import {
|
|
8
16
|
redirectsToRouteRules
|
|
9
17
|
} from "../chunk-F7MXQXLM.js";
|
|
@@ -95,176 +103,6 @@ function resolveDirs(dirs) {
|
|
|
95
103
|
|
|
96
104
|
// src/compiler/parser.ts
|
|
97
105
|
import { parseHTML } from "linkedom";
|
|
98
|
-
function getCommentRanges(html) {
|
|
99
|
-
const ranges = [];
|
|
100
|
-
const commentRegex = /<!--[\s\S]*?-->/g;
|
|
101
|
-
let match;
|
|
102
|
-
while ((match = commentRegex.exec(html)) !== null) {
|
|
103
|
-
ranges.push([match.index, match.index + match[0].length]);
|
|
104
|
-
}
|
|
105
|
-
return ranges;
|
|
106
|
-
}
|
|
107
|
-
function isInsideComment(pos, commentRanges) {
|
|
108
|
-
return commentRanges.some(([start, end]) => pos >= start && pos < end);
|
|
109
|
-
}
|
|
110
|
-
function isInsideForeignNamespace(html, pos) {
|
|
111
|
-
const before = html.slice(0, pos);
|
|
112
|
-
const svgOpens = (before.match(/<svg[\s>]/gi) || []).length;
|
|
113
|
-
const svgCloses = (before.match(/<\/svg\s*>/gi) || []).length;
|
|
114
|
-
if (svgOpens > svgCloses) return true;
|
|
115
|
-
const mathOpens = (before.match(/<math[\s>]/gi) || []).length;
|
|
116
|
-
const mathCloses = (before.match(/<\/math\s*>/gi) || []).length;
|
|
117
|
-
return mathOpens > mathCloses;
|
|
118
|
-
}
|
|
119
|
-
function parse(html) {
|
|
120
|
-
html = html.replace(/^\uFEFF/, "");
|
|
121
|
-
const commentRanges = getCommentRanges(html);
|
|
122
|
-
let buildContent = [];
|
|
123
|
-
let clientScripts = [];
|
|
124
|
-
let inlineScripts = [];
|
|
125
|
-
let blockingScripts = [];
|
|
126
|
-
const SCRIPT_REGEX = /<script\b([^>]*)>([\s\S]*?)<\/script>/gi;
|
|
127
|
-
const edits = [];
|
|
128
|
-
const scriptsToRemove = [];
|
|
129
|
-
const isInHead = (html2, scriptStart) => {
|
|
130
|
-
const beforeScript = html2.slice(0, scriptStart);
|
|
131
|
-
let headOpen = -1;
|
|
132
|
-
const headOpenRe = /<head(?=[\s>])/gi;
|
|
133
|
-
let m;
|
|
134
|
-
while ((m = headOpenRe.exec(beforeScript)) !== null) headOpen = m.index;
|
|
135
|
-
const headClose = beforeScript.lastIndexOf("</head>");
|
|
136
|
-
return headOpen > headClose;
|
|
137
|
-
};
|
|
138
|
-
let match = SCRIPT_REGEX.exec(html);
|
|
139
|
-
while (match !== null) {
|
|
140
|
-
const start = match.index;
|
|
141
|
-
const end = match.index + match[0].length;
|
|
142
|
-
const fullTag = match[0];
|
|
143
|
-
const attrsMatch = match[1] || "";
|
|
144
|
-
const content = match[2] || "";
|
|
145
|
-
if (isInsideComment(start, commentRanges)) {
|
|
146
|
-
match = SCRIPT_REGEX.exec(html);
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
if (isInsideForeignNamespace(html, start)) {
|
|
150
|
-
match = SCRIPT_REGEX.exec(html);
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
const { document } = parseHTML(fullTag);
|
|
154
|
-
const scriptEl = document.querySelector("script");
|
|
155
|
-
if (scriptEl) {
|
|
156
|
-
const passData = scriptEl.getAttribute("pass:data") || void 0;
|
|
157
|
-
let cleanedAttrs = attrsMatch.replace(/\bis:build\b/g, "").replace(/\bis:inline\b/g, "").replace(/\bis:blocking\b/g, "");
|
|
158
|
-
const inHead = isInHead(html, start);
|
|
159
|
-
if (!scriptEl.hasAttribute("is:inline") && !inHead) {
|
|
160
|
-
cleanedAttrs = cleanedAttrs.replace(/pass:data="[^"]*"/g, "").replace(/pass:data='[^']*'/g, "").replace(/pass:data=\{[^}]*\}/g, "");
|
|
161
|
-
}
|
|
162
|
-
cleanedAttrs = cleanedAttrs.replace(/\s+/g, " ").trim();
|
|
163
|
-
const openingTag = fullTag.slice(0, fullTag.indexOf(">") + 1);
|
|
164
|
-
const isPlainDefault = /^<script\s*>$/i.test(openingTag);
|
|
165
|
-
if (isPlainDefault) {
|
|
166
|
-
scriptsToRemove.push({
|
|
167
|
-
start,
|
|
168
|
-
end,
|
|
169
|
-
type: "client",
|
|
170
|
-
content: content.trim(),
|
|
171
|
-
attrs: cleanedAttrs,
|
|
172
|
-
passDataExpr: passData,
|
|
173
|
-
injectInHead: inHead
|
|
174
|
-
});
|
|
175
|
-
edits.push({ start, end });
|
|
176
|
-
} else if (scriptEl.hasAttribute("is:build")) {
|
|
177
|
-
scriptsToRemove.push({
|
|
178
|
-
start,
|
|
179
|
-
end,
|
|
180
|
-
type: "build",
|
|
181
|
-
content: content.trim(),
|
|
182
|
-
attrs: cleanedAttrs
|
|
183
|
-
});
|
|
184
|
-
edits.push({ start, end });
|
|
185
|
-
} else if (scriptEl.hasAttribute("is:inline")) {
|
|
186
|
-
inlineScripts.push({
|
|
187
|
-
attrs: cleanedAttrs,
|
|
188
|
-
content: content.trim(),
|
|
189
|
-
passDataExpr: passData
|
|
190
|
-
});
|
|
191
|
-
edits.push({
|
|
192
|
-
start,
|
|
193
|
-
end,
|
|
194
|
-
newContent: `<script${cleanedAttrs ? " " + cleanedAttrs : ""}>${content.trim()}</script>`
|
|
195
|
-
});
|
|
196
|
-
} else if (scriptEl.hasAttribute("is:blocking")) {
|
|
197
|
-
scriptsToRemove.push({
|
|
198
|
-
start,
|
|
199
|
-
end,
|
|
200
|
-
type: "blocking",
|
|
201
|
-
content: content.trim(),
|
|
202
|
-
attrs: cleanedAttrs,
|
|
203
|
-
passDataExpr: passData
|
|
204
|
-
});
|
|
205
|
-
edits.push({ start, end });
|
|
206
|
-
} else if (scriptEl.hasAttribute("src")) {
|
|
207
|
-
const src = scriptEl.getAttribute("src") || "";
|
|
208
|
-
const isLocalScript = !src.startsWith("http://") && !src.startsWith("https://");
|
|
209
|
-
const hasType = cleanedAttrs.includes("type=");
|
|
210
|
-
if (isLocalScript && !hasType) {
|
|
211
|
-
const attrsForModule = cleanedAttrs.replace(/\bdefer\s*=\s*["'][^"']*["']/gi, "").replace(/\bdefer\b/gi, "").replace(/\bsrc\s*=\s*["'][^"']*["']/gi, "").replace(/\s+/g, " ").trim();
|
|
212
|
-
const newAttrs = attrsForModule ? attrsForModule + ' type="module"' : 'type="module"';
|
|
213
|
-
edits.push({
|
|
214
|
-
start,
|
|
215
|
-
end,
|
|
216
|
-
newContent: `<script ${newAttrs} src="${src}"></script>`
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
} else if (!scriptEl.hasAttribute("is:inline") && inHead) {
|
|
220
|
-
} else {
|
|
221
|
-
scriptsToRemove.push({
|
|
222
|
-
start,
|
|
223
|
-
end,
|
|
224
|
-
type: "client",
|
|
225
|
-
content: content.trim(),
|
|
226
|
-
attrs: cleanedAttrs,
|
|
227
|
-
passDataExpr: passData
|
|
228
|
-
});
|
|
229
|
-
edits.push({ start, end });
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
match = SCRIPT_REGEX.exec(html);
|
|
233
|
-
}
|
|
234
|
-
edits.sort((a, b) => a.start - b.start);
|
|
235
|
-
let template = "";
|
|
236
|
-
let last = 0;
|
|
237
|
-
for (const e of edits) {
|
|
238
|
-
template += html.slice(last, e.start);
|
|
239
|
-
if (e.newContent !== void 0) template += e.newContent;
|
|
240
|
-
last = e.end;
|
|
241
|
-
}
|
|
242
|
-
template += html.slice(last);
|
|
243
|
-
for (const s of scriptsToRemove) {
|
|
244
|
-
if (s.type === "build") buildContent.push(s.content);
|
|
245
|
-
if (s.type === "client")
|
|
246
|
-
clientScripts.push({
|
|
247
|
-
attrs: s.attrs,
|
|
248
|
-
content: s.content,
|
|
249
|
-
passDataExpr: s.passDataExpr,
|
|
250
|
-
injectInHead: s.injectInHead
|
|
251
|
-
});
|
|
252
|
-
if (s.type === "blocking")
|
|
253
|
-
blockingScripts.push({
|
|
254
|
-
attrs: s.attrs,
|
|
255
|
-
content: s.content,
|
|
256
|
-
passDataExpr: s.passDataExpr
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
const buildScript = buildContent.length > 0 ? { content: buildContent.join("\n") } : null;
|
|
260
|
-
return {
|
|
261
|
-
buildScript,
|
|
262
|
-
clientScripts,
|
|
263
|
-
inlineScripts,
|
|
264
|
-
blockingScripts,
|
|
265
|
-
template: template.trim()
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
106
|
|
|
269
107
|
// src/compiler/constants.ts
|
|
270
108
|
var ATTR_PREFIX = "data-";
|
|
@@ -275,17 +113,17 @@ var ATTR_ELSE_IF = "else-if";
|
|
|
275
113
|
var ATTR_ELSE = "else";
|
|
276
114
|
var ATTR_NAME = "name";
|
|
277
115
|
var ATTR_SLOT = "slot";
|
|
116
|
+
var ATTR_IS_BUILD = "is:build";
|
|
278
117
|
var ATTR_IS_INLINE = "is:inline";
|
|
118
|
+
var ATTR_IS_BLOCKING = "is:blocking";
|
|
279
119
|
var ATTR_PASS_DATA = "pass:data";
|
|
120
|
+
var ATTR_SRC = "src";
|
|
280
121
|
var TAG_SLOT = "slot";
|
|
281
122
|
var SLOT_NAME_DEFAULT = "default";
|
|
282
123
|
var EACH_REGEX = /^(\w+)\s+in\s+(.+)$/;
|
|
283
|
-
var CURLY_INTERPOLATION_REGEX = /{([\s\S]+?)}/g;
|
|
284
124
|
var COMPONENT_SUFFIX_REGEX = /-(component|layout)$/;
|
|
285
|
-
var IMPORT_REGEX = /((?:^|[\r\n;])\s*)import\s+(?:(\w+)|\{([^}]+)\}|\*\s+as\s+(\w+))\s+from\s+(['"])(.+?)\5/g;
|
|
286
125
|
var SELF_CLOSING_TAG_REGEX = /<([a-z0-9-]+)([^>]*?)\/>/gi;
|
|
287
126
|
var SELF_CLOSING_TAIL_REGEX = /\/>$/;
|
|
288
|
-
var ALPINE_ATTR_REGEX = /^(x-|[@:.]).*/;
|
|
289
127
|
var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
290
128
|
"area",
|
|
291
129
|
"base",
|
|
@@ -303,22 +141,157 @@ var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
|
303
141
|
"wbr"
|
|
304
142
|
]);
|
|
305
143
|
|
|
144
|
+
// src/compiler/parser.ts
|
|
145
|
+
function getAttrsString(element, exclude) {
|
|
146
|
+
const parts = [];
|
|
147
|
+
const attrs = element.attributes;
|
|
148
|
+
if (!attrs) return "";
|
|
149
|
+
const excludeLower = new Set([...exclude].map((s) => s.toLowerCase()));
|
|
150
|
+
for (let i = 0; i < attrs.length; i++) {
|
|
151
|
+
const a = attrs[i];
|
|
152
|
+
if (!a || excludeLower.has(a.name.toLowerCase())) continue;
|
|
153
|
+
const value = a.value;
|
|
154
|
+
const escaped = value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
155
|
+
parts.push(`${a.name}="${escaped}"`);
|
|
156
|
+
}
|
|
157
|
+
return parts.join(" ").trim();
|
|
158
|
+
}
|
|
159
|
+
function isInForeignNamespace(el) {
|
|
160
|
+
let parent = el.parentElement;
|
|
161
|
+
while (parent) {
|
|
162
|
+
const tag = parent.tagName?.toLowerCase();
|
|
163
|
+
if (tag === "svg" || tag === "math") return true;
|
|
164
|
+
parent = parent.parentElement;
|
|
165
|
+
}
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
function isInHead(el) {
|
|
169
|
+
let parent = el.parentElement;
|
|
170
|
+
while (parent) {
|
|
171
|
+
if (parent.tagName?.toLowerCase() === "head") return true;
|
|
172
|
+
parent = parent.parentElement;
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
function collectScriptElements(doc) {
|
|
177
|
+
const scripts = [];
|
|
178
|
+
const walk = (node) => {
|
|
179
|
+
if (node.nodeType === 1) {
|
|
180
|
+
const el = node;
|
|
181
|
+
if (el.tagName?.toLowerCase() === "script") {
|
|
182
|
+
if (!isInForeignNamespace(el)) scripts.push(el);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
for (let i = 0; i < node.childNodes.length; i++) walk(node.childNodes[i]);
|
|
187
|
+
};
|
|
188
|
+
walk(doc);
|
|
189
|
+
return scripts;
|
|
190
|
+
}
|
|
191
|
+
function parse(html) {
|
|
192
|
+
html = html.replace(/^\uFEFF/, "");
|
|
193
|
+
html = html.replace(SELF_CLOSING_TAG_REGEX, (match, tagName, attrs) => {
|
|
194
|
+
const tag = String(tagName).toLowerCase();
|
|
195
|
+
if (VOID_TAGS.has(tag)) return match;
|
|
196
|
+
return `<${tagName}${attrs}></${tagName}>`;
|
|
197
|
+
});
|
|
198
|
+
const isFullDocument = /<\s*html[\s>]/i.test(html);
|
|
199
|
+
let doc;
|
|
200
|
+
if (isFullDocument) {
|
|
201
|
+
const parsed = parseHTML(html);
|
|
202
|
+
doc = parsed.document;
|
|
203
|
+
} else {
|
|
204
|
+
const parsed = parseHTML(`<html><head></head><body>${html}</body></html>`);
|
|
205
|
+
doc = parsed.document;
|
|
206
|
+
}
|
|
207
|
+
const buildContent = [];
|
|
208
|
+
const clientScripts = [];
|
|
209
|
+
const inlineScripts = [];
|
|
210
|
+
const blockingScripts = [];
|
|
211
|
+
const scriptElements = collectScriptElements(doc);
|
|
212
|
+
const toRemove = [];
|
|
213
|
+
for (const scriptEl of scriptElements) {
|
|
214
|
+
const inHead = isInHead(scriptEl);
|
|
215
|
+
const hasBuild = scriptEl.hasAttribute(ATTR_IS_BUILD);
|
|
216
|
+
const hasInline = scriptEl.hasAttribute(ATTR_IS_INLINE);
|
|
217
|
+
const hasBlocking = scriptEl.hasAttribute(ATTR_IS_BLOCKING);
|
|
218
|
+
const src = scriptEl.getAttribute(ATTR_SRC) ?? "";
|
|
219
|
+
const passData = scriptEl.getAttribute(ATTR_PASS_DATA) ?? void 0;
|
|
220
|
+
const attrsExcludeTaxonomy = /* @__PURE__ */ new Set([ATTR_IS_BUILD, ATTR_IS_INLINE, ATTR_IS_BLOCKING]);
|
|
221
|
+
let cleanedAttrs = getAttrsString(scriptEl, attrsExcludeTaxonomy);
|
|
222
|
+
if (!hasInline && !inHead) {
|
|
223
|
+
cleanedAttrs = getAttrsString(scriptEl, /* @__PURE__ */ new Set([...attrsExcludeTaxonomy, ATTR_PASS_DATA]));
|
|
224
|
+
}
|
|
225
|
+
cleanedAttrs = cleanedAttrs.replace(/\s+/g, " ").trim();
|
|
226
|
+
const content = (scriptEl.textContent ?? "").trim();
|
|
227
|
+
if (hasBuild) {
|
|
228
|
+
buildContent.push(content);
|
|
229
|
+
toRemove.push(scriptEl);
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
if (hasInline) {
|
|
233
|
+
inlineScripts.push({
|
|
234
|
+
attrs: cleanedAttrs,
|
|
235
|
+
content,
|
|
236
|
+
passDataExpr: passData
|
|
237
|
+
});
|
|
238
|
+
scriptEl.removeAttribute(ATTR_IS_INLINE);
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
if (hasBlocking) {
|
|
242
|
+
blockingScripts.push({
|
|
243
|
+
attrs: cleanedAttrs,
|
|
244
|
+
content,
|
|
245
|
+
passDataExpr: passData
|
|
246
|
+
});
|
|
247
|
+
toRemove.push(scriptEl);
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (src) {
|
|
251
|
+
const isLocal = !src.startsWith("http://") && !src.startsWith("https://");
|
|
252
|
+
const hasType = scriptEl.hasAttribute("type");
|
|
253
|
+
if (isLocal && !hasType) {
|
|
254
|
+
scriptEl.setAttribute("type", "module");
|
|
255
|
+
scriptEl.removeAttribute("defer");
|
|
256
|
+
}
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (inHead && scriptEl.attributes.length > 0) continue;
|
|
260
|
+
clientScripts.push({
|
|
261
|
+
attrs: cleanedAttrs,
|
|
262
|
+
content,
|
|
263
|
+
passDataExpr: passData,
|
|
264
|
+
injectInHead: inHead
|
|
265
|
+
});
|
|
266
|
+
toRemove.push(scriptEl);
|
|
267
|
+
}
|
|
268
|
+
for (const el of toRemove) el.remove();
|
|
269
|
+
const buildScript = buildContent.length > 0 ? { content: buildContent.join("\n") } : null;
|
|
270
|
+
let template;
|
|
271
|
+
if (isFullDocument) {
|
|
272
|
+
template = doc.documentElement ? doc.documentElement.outerHTML : String(doc);
|
|
273
|
+
} else {
|
|
274
|
+
template = doc.body ? doc.body.innerHTML : "";
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
buildScript,
|
|
278
|
+
clientScripts,
|
|
279
|
+
inlineScripts,
|
|
280
|
+
blockingScripts,
|
|
281
|
+
template: template.trim()
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
306
285
|
// src/compiler/helpers.ts
|
|
307
286
|
function compileInterpolation(text) {
|
|
308
287
|
if (!text) return "";
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
return compiled;
|
|
288
|
+
const segments = tokenizeCurlyInterpolation(text, { attributeMode: false });
|
|
289
|
+
return compileInterpolationFromSegments(segments);
|
|
312
290
|
}
|
|
313
291
|
function compileAttributeInterpolation(text) {
|
|
314
292
|
if (!text) return "";
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
let compiled = text.replace(/`/g, "\\`");
|
|
318
|
-
compiled = compiled.replace(/{{/g, openSentinel).replace(/}}/g, closeSentinel);
|
|
319
|
-
compiled = compiled.replace(/{([\s\S]+?)}/g, "${$1}");
|
|
320
|
-
compiled = compiled.replace(new RegExp(openSentinel, "g"), "{").replace(new RegExp(closeSentinel, "g"), "}");
|
|
321
|
-
return compiled;
|
|
293
|
+
const segments = tokenizeCurlyInterpolation(text, { attributeMode: true });
|
|
294
|
+
return compileInterpolationFromSegments(segments);
|
|
322
295
|
}
|
|
323
296
|
function isAttr(name, attr, prefix) {
|
|
324
297
|
return name === attr || name === prefix + attr;
|
|
@@ -346,55 +319,6 @@ function emitSlotsObjectVars(slotsMap) {
|
|
|
346
319
|
const entries = Object.entries(slotsMap).map(([k, varName]) => `"${k}": ${varName}`).join(", ");
|
|
347
320
|
return "{ " + entries + " }";
|
|
348
321
|
}
|
|
349
|
-
function extractGetStaticPaths(script) {
|
|
350
|
-
const regex = /export\s+(async\s+)?function\s+getStaticPaths\s*\([^)]*\)\s*\{/;
|
|
351
|
-
const match = regex.exec(script);
|
|
352
|
-
if (!match) return { fnText: null, remaining: script };
|
|
353
|
-
const start = match.index;
|
|
354
|
-
const braceStart = start + match[0].length - 1;
|
|
355
|
-
let depth = 1;
|
|
356
|
-
let i = braceStart + 1;
|
|
357
|
-
let inString = null;
|
|
358
|
-
let inComment = null;
|
|
359
|
-
while (i < script.length && depth > 0) {
|
|
360
|
-
const char = script[i];
|
|
361
|
-
const next = script[i + 1];
|
|
362
|
-
if (inComment) {
|
|
363
|
-
if (inComment === "//" && char === "\n") inComment = null;
|
|
364
|
-
else if (inComment === "/*" && char === "*" && next === "/") {
|
|
365
|
-
inComment = null;
|
|
366
|
-
i++;
|
|
367
|
-
}
|
|
368
|
-
} else if (inString) {
|
|
369
|
-
if (char === "\\") {
|
|
370
|
-
i++;
|
|
371
|
-
} else if (char === inString) {
|
|
372
|
-
inString = null;
|
|
373
|
-
}
|
|
374
|
-
} else {
|
|
375
|
-
if (char === "/" && next === "/") {
|
|
376
|
-
inComment = "//";
|
|
377
|
-
i++;
|
|
378
|
-
} else if (char === "/" && next === "*") {
|
|
379
|
-
inComment = "/*";
|
|
380
|
-
i++;
|
|
381
|
-
} else if (char === '"' || char === "'" || char === "`") {
|
|
382
|
-
inString = char;
|
|
383
|
-
} else if (char === "{") {
|
|
384
|
-
depth++;
|
|
385
|
-
} else if (char === "}") {
|
|
386
|
-
depth--;
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
i++;
|
|
390
|
-
}
|
|
391
|
-
if (depth !== 0) {
|
|
392
|
-
return { fnText: null, remaining: script };
|
|
393
|
-
}
|
|
394
|
-
const fnText = script.slice(start, i);
|
|
395
|
-
const remaining = (script.slice(0, start) + script.slice(i)).trim();
|
|
396
|
-
return { fnText, remaining };
|
|
397
|
-
}
|
|
398
322
|
function emitRenderFunction(script, body, options = {}) {
|
|
399
323
|
const {
|
|
400
324
|
getStaticPathsFn,
|
|
@@ -762,11 +686,9 @@ var Lowerer = class {
|
|
|
762
686
|
if (attr.name === ATTR_IS_INLINE) {
|
|
763
687
|
continue;
|
|
764
688
|
}
|
|
765
|
-
let val =
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
if (!isAlpine) {
|
|
769
|
-
val = val.replace(CURLY_INTERPOLATION_REGEX, "${$1}");
|
|
689
|
+
let val = this.resolver.resolveAttrValue(attr.value ?? "");
|
|
690
|
+
if (!isDirectiveAttr(attr.name)) {
|
|
691
|
+
val = compileAttributeInterpolation(val);
|
|
770
692
|
}
|
|
771
693
|
attributes.push(`${attr.name}="${val}"`);
|
|
772
694
|
}
|
|
@@ -1018,21 +940,24 @@ function compile(parsed, options) {
|
|
|
1018
940
|
});
|
|
1019
941
|
const lowerer = new Lowerer(resolver);
|
|
1020
942
|
let script = parsed.buildScript ? parsed.buildScript.content : "";
|
|
1021
|
-
const
|
|
1022
|
-
script =
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
943
|
+
const analysis = analyzeBuildScript(script);
|
|
944
|
+
script = analysis.scriptWithoutImportsAndGetStaticPaths;
|
|
945
|
+
const getStaticPathsFn = analysis.getStaticPathsFn;
|
|
946
|
+
const importsLines = [];
|
|
947
|
+
const quote = '"';
|
|
948
|
+
for (const imp of analysis.imports) {
|
|
949
|
+
const resolved = resolver.resolveImport(imp.specifier);
|
|
950
|
+
const modExpr = `await import(${quote}${resolved}${quote})`;
|
|
951
|
+
if (imp.defaultBinding) {
|
|
952
|
+
importsLines.push(`const ${imp.defaultBinding} = (${modExpr}).default`);
|
|
953
|
+
} else if (imp.namedBindings.length > 0) {
|
|
954
|
+
const names = imp.namedBindings.map((b) => b.imported === b.local ? b.local : `${b.imported} as ${b.local}`).join(", ");
|
|
955
|
+
importsLines.push(`const {${names}} = ${modExpr}`);
|
|
956
|
+
} else if (imp.namespaceBinding) {
|
|
957
|
+
importsLines.push(`const ${imp.namespaceBinding} = ${modExpr}`);
|
|
1030
958
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
const importsCode = imports.join("\n");
|
|
1034
|
-
const { fnText: getStaticPathsFn, remaining: scriptWithoutPaths } = extractGetStaticPaths(script);
|
|
1035
|
-
script = scriptWithoutPaths;
|
|
959
|
+
}
|
|
960
|
+
const importsCode = importsLines.join("\n");
|
|
1036
961
|
const expandedTemplate = parsed.template.replace(
|
|
1037
962
|
SELF_CLOSING_TAG_REGEX,
|
|
1038
963
|
(match, tagName, attrs) => {
|
|
@@ -1185,17 +1110,10 @@ function registerClientScriptsToMap(parsed, baseName, target) {
|
|
|
1185
1110
|
}
|
|
1186
1111
|
}
|
|
1187
1112
|
function isDynamicPage(page) {
|
|
1188
|
-
return
|
|
1113
|
+
return isDynamicRoutePattern(page.pageName);
|
|
1189
1114
|
}
|
|
1190
1115
|
function expandPattern(pattern, params) {
|
|
1191
|
-
return pattern
|
|
1192
|
-
if (!(key in params)) {
|
|
1193
|
-
throw new Error(
|
|
1194
|
-
`[aero] getStaticPaths: missing param "${key}" for pattern "${pattern}". Provided params: ${JSON.stringify(params)}`
|
|
1195
|
-
);
|
|
1196
|
-
}
|
|
1197
|
-
return params[key];
|
|
1198
|
-
});
|
|
1116
|
+
return expandRoutePattern(pattern, params);
|
|
1199
1117
|
}
|
|
1200
1118
|
function walkHtmlFiles(dir) {
|
|
1201
1119
|
if (!fs.existsSync(dir)) return [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aerobuilt/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Jamie Wilson",
|
|
@@ -40,6 +40,10 @@
|
|
|
40
40
|
"./utils/redirects": {
|
|
41
41
|
"types": "./dist/utils/redirects.d.ts",
|
|
42
42
|
"default": "./dist/utils/redirects.js"
|
|
43
|
+
},
|
|
44
|
+
"./editor": {
|
|
45
|
+
"types": "./dist/entry-editor.d.ts",
|
|
46
|
+
"default": "./dist/entry-editor.js"
|
|
43
47
|
}
|
|
44
48
|
},
|
|
45
49
|
"dependencies": {
|
|
@@ -47,13 +51,20 @@
|
|
|
47
51
|
"html-minifier-next": "^5.1.1",
|
|
48
52
|
"linkedom": "^0.18.12",
|
|
49
53
|
"nitro": "^3.0.1-alpha.2",
|
|
54
|
+
"oxc-parser": "^0.115.0",
|
|
50
55
|
"sharp": "^0.34.5",
|
|
51
56
|
"svgo": "^4.0.0",
|
|
52
|
-
"vite-plugin-image-optimizer": "^2.0.3"
|
|
57
|
+
"vite-plugin-image-optimizer": "^2.0.3",
|
|
58
|
+
"@aerobuilt/interpolation": "0.2.3"
|
|
53
59
|
},
|
|
54
60
|
"peerDependencies": {
|
|
55
61
|
"vite": "8.0.0-beta.15"
|
|
56
62
|
},
|
|
63
|
+
"peerDependenciesMeta": {
|
|
64
|
+
"vite": {
|
|
65
|
+
"optional": true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
57
68
|
"devDependencies": {
|
|
58
69
|
"@types/node": "^25.3.0",
|
|
59
70
|
"tsup": "^8.5.1",
|
|
@@ -61,7 +72,7 @@
|
|
|
61
72
|
"vitest": "^4.0.18"
|
|
62
73
|
},
|
|
63
74
|
"scripts": {
|
|
64
|
-
"build": "tsup src/entry-dev.ts src/entry-prod.ts src/types.ts src/vite/index.ts src/utils/redirects.ts src/runtime/index.ts src/runtime/instance.ts --format esm --dts --clean --out-dir dist --external @content/site",
|
|
75
|
+
"build": "tsup src/entry-dev.ts src/entry-prod.ts src/entry-editor.ts src/types.ts src/vite/index.ts src/utils/redirects.ts src/runtime/index.ts src/runtime/instance.ts --format esm --dts --clean --out-dir dist --external @content/site",
|
|
65
76
|
"typecheck": "tsc --noEmit",
|
|
66
77
|
"test": "vitest run"
|
|
67
78
|
}
|