@kuratchi/js 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +770 -691
- package/dist/compiler/index.js +1122 -856
- package/dist/compiler/template.js +74 -28
- package/dist/runtime/types.d.ts +0 -14
- package/package.json +1 -1
|
@@ -175,10 +175,56 @@ export function compileTemplate(template, componentNames, actionNames, rpcNameMa
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
// HTML line → compile {expr} interpolations
|
|
178
|
-
|
|
178
|
+
// Handle multi-line expressions: if a line has unclosed {, join continuation lines
|
|
179
|
+
let htmlLine = line;
|
|
180
|
+
let extraLines = 0;
|
|
181
|
+
if (hasUnclosedBrace(htmlLine)) {
|
|
182
|
+
let j = i + 1;
|
|
183
|
+
while (j < lines.length && hasUnclosedBrace(htmlLine)) {
|
|
184
|
+
htmlLine += '\n' + lines[j];
|
|
185
|
+
extraLines++;
|
|
186
|
+
j++;
|
|
187
|
+
}
|
|
188
|
+
i += extraLines;
|
|
189
|
+
}
|
|
190
|
+
out.push(compileHtmlLine(htmlLine, actionNames, rpcNameMap));
|
|
179
191
|
}
|
|
180
192
|
return out.join('\n');
|
|
181
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Check if a string has unclosed template braces (more { than }).
|
|
196
|
+
* Respects string quotes to avoid false positives.
|
|
197
|
+
*/
|
|
198
|
+
function hasUnclosedBrace(src) {
|
|
199
|
+
let depth = 0;
|
|
200
|
+
let quote = null;
|
|
201
|
+
let escaped = false;
|
|
202
|
+
for (let i = 0; i < src.length; i++) {
|
|
203
|
+
const ch = src[i];
|
|
204
|
+
if (quote) {
|
|
205
|
+
if (escaped) {
|
|
206
|
+
escaped = false;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (ch === '\\') {
|
|
210
|
+
escaped = true;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (ch === quote)
|
|
214
|
+
quote = null;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (ch === '"' || ch === "'" || ch === '`') {
|
|
218
|
+
quote = ch;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (ch === '{')
|
|
222
|
+
depth++;
|
|
223
|
+
if (ch === '}')
|
|
224
|
+
depth--;
|
|
225
|
+
}
|
|
226
|
+
return depth > 0;
|
|
227
|
+
}
|
|
182
228
|
function advanceHtmlTagState(src, startInTag, startQuote) {
|
|
183
229
|
let inTag = startInTag;
|
|
184
230
|
let quote = startQuote;
|
|
@@ -861,33 +907,33 @@ function findClosingBrace(src, openPos) {
|
|
|
861
907
|
*/
|
|
862
908
|
export function generateRenderFunction(template) {
|
|
863
909
|
const body = compileTemplate(template);
|
|
864
|
-
return `function render(data) {
|
|
865
|
-
const __rawHtml = (v) => {
|
|
866
|
-
if (v == null) return '';
|
|
867
|
-
return String(v);
|
|
868
|
-
};
|
|
869
|
-
const __sanitizeHtml = (v) => {
|
|
870
|
-
let html = __rawHtml(v);
|
|
871
|
-
html = html.replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, '');
|
|
872
|
-
html = html.replace(/<iframe\\b[^>]*>[\\s\\S]*?<\\/iframe>/gi, '');
|
|
873
|
-
html = html.replace(/<object\\b[^>]*>[\\s\\S]*?<\\/object>/gi, '');
|
|
874
|
-
html = html.replace(/<embed\\b[^>]*>/gi, '');
|
|
875
|
-
html = html.replace(/\\son[a-z]+\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s>]+)/gi, '');
|
|
876
|
-
html = html.replace(/\\s(href|src|xlink:href)\\s*=\\s*([\"'])\\s*javascript:[\\s\\S]*?\\2/gi, ' $1="#"');
|
|
877
|
-
html = html.replace(/\\s(href|src|xlink:href)\\s*=\\s*javascript:[^\\s>]+/gi, ' $1="#"');
|
|
878
|
-
html = html.replace(/\\ssrcdoc\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s>]+)/gi, '');
|
|
879
|
-
return html;
|
|
880
|
-
};
|
|
881
|
-
const __esc = (v) => {
|
|
882
|
-
if (v == null) return '';
|
|
883
|
-
return String(v)
|
|
884
|
-
.replace(/&/g, '&')
|
|
885
|
-
.replace(/</g, '<')
|
|
886
|
-
.replace(/>/g, '>')
|
|
887
|
-
.replace(/"/g, '"')
|
|
888
|
-
.replace(/'/g, ''');
|
|
889
|
-
};
|
|
890
|
-
${body}
|
|
910
|
+
return `function render(data) {
|
|
911
|
+
const __rawHtml = (v) => {
|
|
912
|
+
if (v == null) return '';
|
|
913
|
+
return String(v);
|
|
914
|
+
};
|
|
915
|
+
const __sanitizeHtml = (v) => {
|
|
916
|
+
let html = __rawHtml(v);
|
|
917
|
+
html = html.replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, '');
|
|
918
|
+
html = html.replace(/<iframe\\b[^>]*>[\\s\\S]*?<\\/iframe>/gi, '');
|
|
919
|
+
html = html.replace(/<object\\b[^>]*>[\\s\\S]*?<\\/object>/gi, '');
|
|
920
|
+
html = html.replace(/<embed\\b[^>]*>/gi, '');
|
|
921
|
+
html = html.replace(/\\son[a-z]+\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s>]+)/gi, '');
|
|
922
|
+
html = html.replace(/\\s(href|src|xlink:href)\\s*=\\s*([\"'])\\s*javascript:[\\s\\S]*?\\2/gi, ' $1="#"');
|
|
923
|
+
html = html.replace(/\\s(href|src|xlink:href)\\s*=\\s*javascript:[^\\s>]+/gi, ' $1="#"');
|
|
924
|
+
html = html.replace(/\\ssrcdoc\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s>]+)/gi, '');
|
|
925
|
+
return html;
|
|
926
|
+
};
|
|
927
|
+
const __esc = (v) => {
|
|
928
|
+
if (v == null) return '';
|
|
929
|
+
return String(v)
|
|
930
|
+
.replace(/&/g, '&')
|
|
931
|
+
.replace(/</g, '<')
|
|
932
|
+
.replace(/>/g, '>')
|
|
933
|
+
.replace(/"/g, '"')
|
|
934
|
+
.replace(/'/g, ''');
|
|
935
|
+
};
|
|
936
|
+
${body}
|
|
891
937
|
}`;
|
|
892
938
|
}
|
|
893
939
|
import { transpileTypeScript } from './transpile.js';
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -129,20 +129,6 @@ export interface kuratchiConfig<E extends Env = Env> {
|
|
|
129
129
|
/** DO source files (e.g. ['auth.do.ts', 'sites.do.ts']) */
|
|
130
130
|
files?: string[];
|
|
131
131
|
}>;
|
|
132
|
-
/** Container classes exported into the generated worker entry. */
|
|
133
|
-
containers?: Record<string, string | {
|
|
134
|
-
/** Relative path from project root. Must end in `.container.ts|js|mjs|cjs`. */
|
|
135
|
-
file: string;
|
|
136
|
-
/** Optional override; inferred from exported class in `file` when omitted. */
|
|
137
|
-
className?: string;
|
|
138
|
-
}>;
|
|
139
|
-
/** Workflow classes exported into the generated worker entry. */
|
|
140
|
-
workflows?: Record<string, string | {
|
|
141
|
-
/** Relative path from project root. Must end in `.workflow.ts|js|mjs|cjs`. */
|
|
142
|
-
file: string;
|
|
143
|
-
/** Optional override; inferred from exported class in `file` when omitted. */
|
|
144
|
-
className?: string;
|
|
145
|
-
}>;
|
|
146
132
|
}
|
|
147
133
|
/** Auth configuration for kuratchi.config.ts */
|
|
148
134
|
export interface AuthConfig {
|