@jay-framework/compiler-jay-html 0.19.5 → 0.19.7
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/index.d.cts +8 -1
- package/dist/index.js +124 -8
- package/package.json +9 -9
package/dist/index.d.cts
CHANGED
|
@@ -180,6 +180,12 @@ interface JayHtmlHeadLink {
|
|
|
180
180
|
href: string;
|
|
181
181
|
attributes: Record<string, string>;
|
|
182
182
|
}
|
|
183
|
+
interface JayHtmlScript {
|
|
184
|
+
src?: string;
|
|
185
|
+
inline?: string;
|
|
186
|
+
attributes: Record<string, string>;
|
|
187
|
+
position: 'head' | 'body';
|
|
188
|
+
}
|
|
183
189
|
interface JayHtmlSourceFile extends CompilerSourceFile {
|
|
184
190
|
format: SourceFileFormat.JayHtml;
|
|
185
191
|
baseElementName: string;
|
|
@@ -214,6 +220,7 @@ interface JayHtmlSourceFile extends CompilerSourceFile {
|
|
|
214
220
|
*/
|
|
215
221
|
clientTrackByMap?: Record<string, string>;
|
|
216
222
|
headMeta?: JayHtmlHeadMeta;
|
|
223
|
+
scripts?: JayHtmlScript[];
|
|
217
224
|
}
|
|
218
225
|
|
|
219
226
|
declare function parseTemplateParts(value: string): TemplatePart[];
|
|
@@ -601,4 +608,4 @@ declare function resolveHeadlessInstances(preRenderedJayHtml: string, instanceDa
|
|
|
601
608
|
*/
|
|
602
609
|
declare function hasSlowPhaseProperties(contract: Contract | undefined): boolean;
|
|
603
610
|
|
|
604
|
-
export { type ActionDefinition, type AssignCoordinatesOptions, type AssignCoordinatesResult, type Contract, type ContractImportInfo, type ContractParam, type ContractParamKind, type ContractProp, type ContractResolver, type ContractTag, ContractTagType, type DiscoveredHeadlessInstance, type EnumToImport, type ForEachHeadlessInstance, type HeadlessContractInfo, type HeadlessInstanceDiscoveryResult, type HeadlessInstanceResolvedData, JAY_IMPORT_RESOLVER, type JayContractImportLink, type JayHtmlSourceFile, type JayImportResolver, type PhaseViewStates, type RenderingPhase, type ServerElementOptions, type SlowRenderInput, type SlowRenderOutput, assignCoordinates, assignCoordinatesToJayHtml, buildInstanceCoordinateKey, compileAction, compileContract, contractToAllPhaseViewStates, contractToImportsViewStateAndRefs, contractToPhaseViewState, createPhaseContract, defaultContractResolver, discoverHeadlessInstances, filterTagsByPhase, generateElementBridgeFile, generateElementDefinitionFile, generateElementFile, generateElementFileReactTarget, generateElementHydrateFile, generateSandboxRootFile, generateServerElementFile, generateTypes, getEffectivePhase, getJayHtmlImports, getLinkedContractDir, hasSlowPhaseProperties, htmlElementTagNameMap, injectHeadfullFSTemplates, isTagInPhase, loadLinkedContract, parseAction, parseContract, parseEnumValues, parseIsEnum, parseJayFile, parseTemplateParts, renderRefsType, resolveHeadlessInstances, slowRenderTransform, validateContractPhases };
|
|
611
|
+
export { type ActionDefinition, type AssignCoordinatesOptions, type AssignCoordinatesResult, type Contract, type ContractImportInfo, type ContractParam, type ContractParamKind, type ContractProp, type ContractResolver, type ContractTag, ContractTagType, type DiscoveredHeadlessInstance, type EnumToImport, type ForEachHeadlessInstance, type HeadlessContractInfo, type HeadlessInstanceDiscoveryResult, type HeadlessInstanceResolvedData, JAY_IMPORT_RESOLVER, type JayContractImportLink, type JayHtmlScript, type JayHtmlSourceFile, type JayImportResolver, type PhaseViewStates, type RenderingPhase, type ServerElementOptions, type SlowRenderInput, type SlowRenderOutput, assignCoordinates, assignCoordinatesToJayHtml, buildInstanceCoordinateKey, compileAction, compileContract, contractToAllPhaseViewStates, contractToImportsViewStateAndRefs, contractToPhaseViewState, createPhaseContract, defaultContractResolver, discoverHeadlessInstances, filterTagsByPhase, generateElementBridgeFile, generateElementDefinitionFile, generateElementFile, generateElementFileReactTarget, generateElementHydrateFile, generateSandboxRootFile, generateServerElementFile, generateTypes, getEffectivePhase, getJayHtmlImports, getLinkedContractDir, hasSlowPhaseProperties, htmlElementTagNameMap, injectHeadfullFSTemplates, isTagInPhase, loadLinkedContract, parseAction, parseContract, parseEnumValues, parseIsEnum, parseJayFile, parseTemplateParts, renderRefsType, resolveHeadlessInstances, slowRenderTransform, validateContractPhases };
|
package/dist/index.js
CHANGED
|
@@ -14657,16 +14657,52 @@ function mergeContractStubRefs(templateRefs, contractRefs) {
|
|
|
14657
14657
|
);
|
|
14658
14658
|
}
|
|
14659
14659
|
}
|
|
14660
|
-
|
|
14660
|
+
const mergedChildren = { ...templateRefs.children };
|
|
14661
|
+
for (const [childName, contractChild] of Object.entries(contractRefs.children)) {
|
|
14662
|
+
if (mergedChildren[childName]) {
|
|
14663
|
+
mergedChildren[childName] = mergeContractStubRefs(
|
|
14664
|
+
mergedChildren[childName],
|
|
14665
|
+
contractChild
|
|
14666
|
+
);
|
|
14667
|
+
} else {
|
|
14668
|
+
mergedChildren[childName] = markAllRefsAsStubs(contractChild);
|
|
14669
|
+
}
|
|
14670
|
+
}
|
|
14671
|
+
const childrenChanged = Object.keys(mergedChildren).length !== Object.keys(templateRefs.children).length || Object.keys(mergedChildren).some((k) => mergedChildren[k] !== templateRefs.children[k]);
|
|
14672
|
+
if (stubRefs.length === 0 && !childrenChanged)
|
|
14661
14673
|
return templateRefs;
|
|
14662
14674
|
return mkRefsTree(
|
|
14663
14675
|
[...templateRefs.refs, ...stubRefs],
|
|
14664
|
-
|
|
14676
|
+
mergedChildren,
|
|
14665
14677
|
templateRefs.repeated,
|
|
14666
14678
|
templateRefs.imported?.refsTypeName,
|
|
14667
14679
|
templateRefs.imported?.repeatedRefsTypeName
|
|
14668
14680
|
);
|
|
14669
14681
|
}
|
|
14682
|
+
function markAllRefsAsStubs(tree) {
|
|
14683
|
+
const stubbedRefs = tree.refs.map(
|
|
14684
|
+
(ref) => mkRef(
|
|
14685
|
+
ref.originalName,
|
|
14686
|
+
ref.originalName,
|
|
14687
|
+
camelCase(`ref ${ref.originalName}`),
|
|
14688
|
+
ref.repeated,
|
|
14689
|
+
true,
|
|
14690
|
+
ref.viewStateType,
|
|
14691
|
+
ref.elementType
|
|
14692
|
+
)
|
|
14693
|
+
);
|
|
14694
|
+
const stubbedChildren = {};
|
|
14695
|
+
for (const [name, child] of Object.entries(tree.children)) {
|
|
14696
|
+
stubbedChildren[name] = markAllRefsAsStubs(child);
|
|
14697
|
+
}
|
|
14698
|
+
return mkRefsTree(
|
|
14699
|
+
stubbedRefs,
|
|
14700
|
+
stubbedChildren,
|
|
14701
|
+
tree.repeated,
|
|
14702
|
+
tree.imported?.refsTypeName,
|
|
14703
|
+
tree.imported?.repeatedRefsTypeName
|
|
14704
|
+
);
|
|
14705
|
+
}
|
|
14670
14706
|
const COORD_ATTR = "jay-coordinate-base";
|
|
14671
14707
|
function expandContractType(renderedElement, baseName) {
|
|
14672
14708
|
const contractPattern = new RegExp(
|
|
@@ -18264,7 +18300,11 @@ function parseHeadfullImports(elements, validations, filePath, options, importRe
|
|
|
18264
18300
|
const exportedTypes = importResolver.analyzeExportedTypes(importedFile, options);
|
|
18265
18301
|
for (const name of names) {
|
|
18266
18302
|
const exportedType = exportedTypes.find((_) => _.name === name.name);
|
|
18267
|
-
if (exportedType && exportedType
|
|
18303
|
+
if (exportedType instanceof JayComponentType && exportedType.fullStack) {
|
|
18304
|
+
validations.push(
|
|
18305
|
+
`${name.name} from ${module} is a full-stack component (makeJayStackComponent). Create a .jay-contract file for the component and add a contract attribute to the import`
|
|
18306
|
+
);
|
|
18307
|
+
} else if (exportedType && exportedType !== JayUnknown)
|
|
18268
18308
|
name.type = new JayImportedType(name.as ? name.as : name.name, exportedType);
|
|
18269
18309
|
else if (exportedType === JayUnknown)
|
|
18270
18310
|
validations.push(
|
|
@@ -18746,6 +18786,49 @@ async function parseHeadfullFSImports(elements, validations, filePath, importRes
|
|
|
18746
18786
|
function normalizeFilename(filename) {
|
|
18747
18787
|
return filename.replace(".jay-html", "");
|
|
18748
18788
|
}
|
|
18789
|
+
function isLocalSrc(src) {
|
|
18790
|
+
return src.startsWith("./") || src.startsWith("../") || !src.includes("://") && !src.startsWith("//");
|
|
18791
|
+
}
|
|
18792
|
+
function validateAndCollectScripts(root, validations) {
|
|
18793
|
+
const scripts = [];
|
|
18794
|
+
const allScripts = root.querySelectorAll("script");
|
|
18795
|
+
for (const script of allScripts) {
|
|
18796
|
+
const type2 = script.getAttribute("type");
|
|
18797
|
+
if (type2?.startsWith("application/jay-"))
|
|
18798
|
+
continue;
|
|
18799
|
+
const jayScript = script.getAttribute("jay-script");
|
|
18800
|
+
const src = script.getAttribute("src");
|
|
18801
|
+
const inline = script.textContent?.trim();
|
|
18802
|
+
const isInHead = !!script.closest("head");
|
|
18803
|
+
if (src && isLocalSrc(src)) {
|
|
18804
|
+
validations.push(
|
|
18805
|
+
`Local script imports are not supported in jay-html. Move the script logic into page.ts with makeJayStackComponent. See designer/script-tags.md.`
|
|
18806
|
+
);
|
|
18807
|
+
continue;
|
|
18808
|
+
}
|
|
18809
|
+
if (jayScript === "allow") {
|
|
18810
|
+
const attributes2 = { ...script.attributes };
|
|
18811
|
+
delete attributes2["jay-script"];
|
|
18812
|
+
delete attributes2["src"];
|
|
18813
|
+
if (src) {
|
|
18814
|
+
scripts.push({ src, attributes: attributes2, position: isInHead ? "head" : "body" });
|
|
18815
|
+
} else if (inline) {
|
|
18816
|
+
scripts.push({ inline, attributes: attributes2, position: isInHead ? "head" : "body" });
|
|
18817
|
+
}
|
|
18818
|
+
continue;
|
|
18819
|
+
}
|
|
18820
|
+
if (src) {
|
|
18821
|
+
validations.push(
|
|
18822
|
+
`External scripts should be explicitly marked. If this script is required (e.g., analytics or tag manager), add jay-script="allow". Prefer page.ts for page behavior. See designer/script-tags.md.`
|
|
18823
|
+
);
|
|
18824
|
+
} else if (inline) {
|
|
18825
|
+
validations.push(
|
|
18826
|
+
`Inline scripts are not supported in jay-html. Use page.ts with makeJayStackComponent for page behavior. If this is a third-party script that must be included as-is, add jay-script="allow". See designer/script-tags.md.`
|
|
18827
|
+
);
|
|
18828
|
+
}
|
|
18829
|
+
}
|
|
18830
|
+
return scripts;
|
|
18831
|
+
}
|
|
18749
18832
|
function parseHeadLinks(root, excludeCssLinks = false) {
|
|
18750
18833
|
const allLinks = root.querySelectorAll("head link");
|
|
18751
18834
|
return allLinks.filter((link) => {
|
|
@@ -18766,12 +18849,20 @@ function parseHeadLinks(root, excludeCssLinks = false) {
|
|
|
18766
18849
|
};
|
|
18767
18850
|
});
|
|
18768
18851
|
}
|
|
18852
|
+
function toParts(value) {
|
|
18853
|
+
try {
|
|
18854
|
+
return parseTemplateParts(value);
|
|
18855
|
+
} catch {
|
|
18856
|
+
return [{ kind: "static", value }];
|
|
18857
|
+
}
|
|
18858
|
+
}
|
|
18769
18859
|
function parseHeadMeta(root) {
|
|
18770
18860
|
const head = root.querySelector("head");
|
|
18771
18861
|
if (!head)
|
|
18772
18862
|
return void 0;
|
|
18773
18863
|
const titleEl = head.querySelector("title");
|
|
18774
|
-
const
|
|
18864
|
+
const titleText = titleEl?.textContent?.trim();
|
|
18865
|
+
const title = titleText ? toParts(titleText) : void 0;
|
|
18775
18866
|
const meta = [];
|
|
18776
18867
|
for (const el of head.querySelectorAll("meta")) {
|
|
18777
18868
|
const content = el.getAttribute("content");
|
|
@@ -18780,7 +18871,11 @@ function parseHeadMeta(root) {
|
|
|
18780
18871
|
const name = el.getAttribute("name");
|
|
18781
18872
|
const property = el.getAttribute("property");
|
|
18782
18873
|
if (name || property) {
|
|
18783
|
-
meta.push({
|
|
18874
|
+
meta.push({
|
|
18875
|
+
name: name || void 0,
|
|
18876
|
+
property: property || void 0,
|
|
18877
|
+
content: toParts(content)
|
|
18878
|
+
});
|
|
18784
18879
|
}
|
|
18785
18880
|
}
|
|
18786
18881
|
const links = [];
|
|
@@ -18788,8 +18883,13 @@ function parseHeadMeta(root) {
|
|
|
18788
18883
|
const rel = el.getAttribute("rel");
|
|
18789
18884
|
if (!rel)
|
|
18790
18885
|
continue;
|
|
18791
|
-
const
|
|
18792
|
-
|
|
18886
|
+
const hrefRaw = el.getAttribute("href") || "";
|
|
18887
|
+
const extraAttrs = {};
|
|
18888
|
+
for (const [k, v] of Object.entries(el.attributes)) {
|
|
18889
|
+
if (k !== "rel" && k !== "href")
|
|
18890
|
+
extraAttrs[k] = v;
|
|
18891
|
+
}
|
|
18892
|
+
links.push({ rel, href: toParts(hrefRaw), ...extraAttrs });
|
|
18793
18893
|
}
|
|
18794
18894
|
return { title, meta, links };
|
|
18795
18895
|
}
|
|
@@ -18928,6 +19028,7 @@ async function parseJayFile(html2, filename, filePath, options, linkedContractRe
|
|
|
18928
19028
|
const excludeCssLinks = !!filePath;
|
|
18929
19029
|
const headLinks = parseHeadLinks(root, excludeCssLinks);
|
|
18930
19030
|
const headMeta = parseHeadMeta(root);
|
|
19031
|
+
const scripts = validateAndCollectScripts(root, validations);
|
|
18931
19032
|
validations.push(...cssResult.validations);
|
|
18932
19033
|
if (validations.length > 0)
|
|
18933
19034
|
return new WithValidations(void 0, validations);
|
|
@@ -18963,7 +19064,8 @@ async function parseJayFile(html2, filename, filePath, options, linkedContractRe
|
|
|
18963
19064
|
hasInlineData: jayYaml.hasInlineData,
|
|
18964
19065
|
serverTrackByMap: Object.keys(serverTrackByMap).length > 0 ? serverTrackByMap : void 0,
|
|
18965
19066
|
clientTrackByMap: Object.keys(clientTrackByMap).length > 0 ? clientTrackByMap : void 0,
|
|
18966
|
-
headMeta
|
|
19067
|
+
headMeta,
|
|
19068
|
+
scripts: scripts.length > 0 ? scripts : void 0
|
|
18967
19069
|
},
|
|
18968
19070
|
validations
|
|
18969
19071
|
);
|
|
@@ -19855,6 +19957,11 @@ ${context.indent.firstLine} ${createBody})`,
|
|
|
19855
19957
|
childContent.refs
|
|
19856
19958
|
);
|
|
19857
19959
|
}
|
|
19960
|
+
if (isConditional(element) && isForEach(element)) {
|
|
19961
|
+
return new RenderFragment("", Imports.none(), [
|
|
19962
|
+
`"if" and "forEach" cannot be on the same element. Wrap the forEach in a separate element: <div if="..."><div forEach="...">...</div></div>`
|
|
19963
|
+
]);
|
|
19964
|
+
}
|
|
19858
19965
|
if (isConditional(element) && context.interactivePaths.size > 0) {
|
|
19859
19966
|
const condition = element.getAttribute("if");
|
|
19860
19967
|
const viewStateVars = new Variables(
|
|
@@ -21279,6 +21386,10 @@ const ${componentSymbol} = makeHeadlessInstanceComponent(
|
|
|
21279
21386
|
mkRefsTree([], {})
|
|
21280
21387
|
);
|
|
21281
21388
|
}
|
|
21389
|
+
} else if (isConditional(htmlElement) && isForEach(htmlElement)) {
|
|
21390
|
+
return new RenderFragment("", Imports.none(), [
|
|
21391
|
+
`"if" and "forEach" cannot be on the same element. Wrap the forEach in a separate element: <div if="..."><div forEach="...">...</div></div>`
|
|
21392
|
+
]);
|
|
21282
21393
|
} else if (isConditional(htmlElement)) {
|
|
21283
21394
|
let condition = htmlElement.getAttribute("if");
|
|
21284
21395
|
let childElement = renderHtmlElement(htmlElement, {
|
|
@@ -22384,6 +22495,11 @@ function renderServerElement(element, context) {
|
|
|
22384
22495
|
if (componentMatch !== null && componentMatch.kind === "headless-instance") {
|
|
22385
22496
|
return renderServerHeadlessInstance(element, context, componentMatch.name);
|
|
22386
22497
|
}
|
|
22498
|
+
if (isConditional(element) && isForEach(element)) {
|
|
22499
|
+
return new RenderFragment("", Imports.none(), [
|
|
22500
|
+
`"if" and "forEach" cannot be on the same element. Wrap the forEach in a separate element: <div if="..."><div forEach="...">...</div></div>`
|
|
22501
|
+
]);
|
|
22502
|
+
}
|
|
22387
22503
|
if (isConditional(element)) {
|
|
22388
22504
|
const condition = element.getAttribute("if");
|
|
22389
22505
|
const renderedCondition = parseServerCondition(condition, variables);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/compiler-jay-html",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.7",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
},
|
|
35
35
|
"author": "",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@jay-framework/compiler-analyze-exported-types": "^0.19.
|
|
38
|
-
"@jay-framework/compiler-shared": "^0.19.
|
|
39
|
-
"@jay-framework/component": "^0.19.
|
|
40
|
-
"@jay-framework/logger": "^0.19.
|
|
41
|
-
"@jay-framework/runtime": "^0.19.
|
|
42
|
-
"@jay-framework/secure": "^0.19.
|
|
37
|
+
"@jay-framework/compiler-analyze-exported-types": "^0.19.7",
|
|
38
|
+
"@jay-framework/compiler-shared": "^0.19.7",
|
|
39
|
+
"@jay-framework/component": "^0.19.7",
|
|
40
|
+
"@jay-framework/logger": "^0.19.7",
|
|
41
|
+
"@jay-framework/runtime": "^0.19.7",
|
|
42
|
+
"@jay-framework/secure": "^0.19.7",
|
|
43
43
|
"@types/js-yaml": "^4.0.9",
|
|
44
44
|
"change-case": "^4.1.2",
|
|
45
45
|
"he": "^1.2.0",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@caiogondim/strip-margin": "^1.0.0",
|
|
55
|
-
"@jay-framework/4-react": "^0.19.
|
|
56
|
-
"@jay-framework/dev-environment": "^0.19.
|
|
55
|
+
"@jay-framework/4-react": "^0.19.7",
|
|
56
|
+
"@jay-framework/dev-environment": "^0.19.7",
|
|
57
57
|
"@testing-library/jest-dom": "^6.2.0",
|
|
58
58
|
"@types/js-beautify": "^1",
|
|
59
59
|
"@types/node": "^20.11.5",
|