@webstudio-is/sdk 0.142.0 → 0.144.0
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/lib/index.js +528 -1
- package/lib/types/expression.d.ts +107 -0
- package/lib/types/forms-generator.d.ts +84 -0
- package/lib/types/forms-generator.test.d.ts +1 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/page-meta-generator.d.ts +55 -0
- package/lib/types/page-meta-generator.test.d.ts +1 -0
- package/lib/types/page-utils.test.d.ts +1 -0
- package/lib/types/resources-generator.d.ts +52 -0
- package/lib/types/resources-generator.test.d.ts +1 -0
- package/lib/types/schema/assets.d.ts +12 -12
- package/lib/types/schema/data-sources.d.ts +12 -12
- package/lib/types/schema/pages.d.ts +20 -20
- package/lib/types/schema/props.d.ts +40 -40
- package/lib/types/schema/resources.d.ts +12 -12
- package/lib/types/schema/style-sources.d.ts +6 -6
- package/lib/types/schema/styles.d.ts +516 -312
- package/lib/types/schema/webstudio.d.ts +212 -180
- package/package.json +7 -5
- /package/lib/types/{page-utilts.test.d.ts → expression.test.d.ts} +0 -0
package/lib/index.js
CHANGED
|
@@ -579,6 +579,522 @@ var loadResource = async (resourceData) => {
|
|
|
579
579
|
};
|
|
580
580
|
}
|
|
581
581
|
};
|
|
582
|
+
|
|
583
|
+
// src/expression.ts
|
|
584
|
+
import { parseExpressionAt } from "acorn";
|
|
585
|
+
import { simple } from "acorn-walk";
|
|
586
|
+
var lintExpression = ({
|
|
587
|
+
expression,
|
|
588
|
+
availableVariables = /* @__PURE__ */ new Set(),
|
|
589
|
+
allowAssignment = false
|
|
590
|
+
}) => {
|
|
591
|
+
const diagnostics = [];
|
|
592
|
+
const addError = (message) => {
|
|
593
|
+
return (node) => {
|
|
594
|
+
diagnostics.push({
|
|
595
|
+
from: node.start,
|
|
596
|
+
to: node.end,
|
|
597
|
+
severity: "error",
|
|
598
|
+
message
|
|
599
|
+
});
|
|
600
|
+
};
|
|
601
|
+
};
|
|
602
|
+
if (expression.trim().length === 0) {
|
|
603
|
+
diagnostics.push({
|
|
604
|
+
from: 0,
|
|
605
|
+
to: 0,
|
|
606
|
+
severity: "error",
|
|
607
|
+
message: "Expression cannot be empty"
|
|
608
|
+
});
|
|
609
|
+
return diagnostics;
|
|
610
|
+
}
|
|
611
|
+
try {
|
|
612
|
+
const root = parseExpressionAt(expression, 0, {
|
|
613
|
+
ecmaVersion: "latest",
|
|
614
|
+
// support parsing import to forbid explicitly
|
|
615
|
+
sourceType: "module"
|
|
616
|
+
});
|
|
617
|
+
simple(root, {
|
|
618
|
+
Identifier(node) {
|
|
619
|
+
if (availableVariables.has(node.name) === false) {
|
|
620
|
+
addError(`"${node.name}" is not available in the scope`)(node);
|
|
621
|
+
}
|
|
622
|
+
},
|
|
623
|
+
Literal() {
|
|
624
|
+
},
|
|
625
|
+
ArrayExpression() {
|
|
626
|
+
},
|
|
627
|
+
ObjectExpression() {
|
|
628
|
+
},
|
|
629
|
+
UnaryExpression() {
|
|
630
|
+
},
|
|
631
|
+
BinaryExpression() {
|
|
632
|
+
},
|
|
633
|
+
LogicalExpression() {
|
|
634
|
+
},
|
|
635
|
+
MemberExpression() {
|
|
636
|
+
},
|
|
637
|
+
ConditionalExpression() {
|
|
638
|
+
},
|
|
639
|
+
TemplateLiteral() {
|
|
640
|
+
},
|
|
641
|
+
ChainExpression() {
|
|
642
|
+
},
|
|
643
|
+
ParenthesizedExpression() {
|
|
644
|
+
},
|
|
645
|
+
AssignmentExpression(node) {
|
|
646
|
+
if (allowAssignment === false) {
|
|
647
|
+
addError("Assignment is supported only inside actions")(node);
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
simple(node.left, {
|
|
651
|
+
Identifier(node2) {
|
|
652
|
+
if (availableVariables.has(node2.name) === false) {
|
|
653
|
+
addError(`"${node2.name}" is not available in the scope`)(node2);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
},
|
|
658
|
+
// parser forbids to yield inside module
|
|
659
|
+
YieldExpression() {
|
|
660
|
+
},
|
|
661
|
+
ThisExpression: addError(`"this" keyword is not supported`),
|
|
662
|
+
FunctionExpression: addError("Functions are not supported"),
|
|
663
|
+
UpdateExpression: addError("Increment and decrement are not supported"),
|
|
664
|
+
CallExpression: addError("Functions are not supported"),
|
|
665
|
+
NewExpression: addError("Classes are not supported"),
|
|
666
|
+
SequenceExpression: addError(`Only single expression is supported`),
|
|
667
|
+
ArrowFunctionExpression: addError("Functions are not supported"),
|
|
668
|
+
TaggedTemplateExpression: addError("Tagged template is not supported"),
|
|
669
|
+
ClassExpression: addError("Classes are not supported"),
|
|
670
|
+
MetaProperty: addError("Imports are not supported"),
|
|
671
|
+
AwaitExpression: addError(`"await" keyword is not supported`),
|
|
672
|
+
ImportExpression: addError("Imports are not supported")
|
|
673
|
+
});
|
|
674
|
+
} catch (error) {
|
|
675
|
+
const castedError = error;
|
|
676
|
+
diagnostics.push({
|
|
677
|
+
from: castedError.pos,
|
|
678
|
+
to: castedError.pos,
|
|
679
|
+
severity: "error",
|
|
680
|
+
message: castedError.message
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
return diagnostics;
|
|
684
|
+
};
|
|
685
|
+
var isLiteralNode = (node) => {
|
|
686
|
+
if (node.type === "Literal") {
|
|
687
|
+
return true;
|
|
688
|
+
}
|
|
689
|
+
if (node.type === "ArrayExpression") {
|
|
690
|
+
return node.elements.every((node2) => {
|
|
691
|
+
if (node2 === null || node2.type === "SpreadElement") {
|
|
692
|
+
return false;
|
|
693
|
+
}
|
|
694
|
+
return isLiteralNode(node2);
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
if (node.type === "ObjectExpression") {
|
|
698
|
+
return node.properties.every((property) => {
|
|
699
|
+
if (property.type === "SpreadElement") {
|
|
700
|
+
return false;
|
|
701
|
+
}
|
|
702
|
+
const key = property.key;
|
|
703
|
+
const isIdentifierKey = key.type === "Identifier" && property.computed === false;
|
|
704
|
+
const isLiteralKey = key.type === "Literal";
|
|
705
|
+
return (isLiteralKey || isIdentifierKey) && isLiteralNode(property.value);
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
return false;
|
|
709
|
+
};
|
|
710
|
+
var isLiteralExpression = (expression) => {
|
|
711
|
+
try {
|
|
712
|
+
const node = parseExpressionAt(expression, 0, { ecmaVersion: "latest" });
|
|
713
|
+
return isLiteralNode(node);
|
|
714
|
+
} catch {
|
|
715
|
+
return false;
|
|
716
|
+
}
|
|
717
|
+
};
|
|
718
|
+
var getExpressionIdentifiers = (expression) => {
|
|
719
|
+
const identifiers = /* @__PURE__ */ new Set();
|
|
720
|
+
try {
|
|
721
|
+
const root = parseExpressionAt(expression, 0, { ecmaVersion: "latest" });
|
|
722
|
+
simple(root, {
|
|
723
|
+
Identifier: (node) => identifiers.add(node.name),
|
|
724
|
+
AssignmentExpression(node) {
|
|
725
|
+
simple(node.left, {
|
|
726
|
+
Identifier: (node2) => identifiers.add(node2.name)
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
} catch {
|
|
731
|
+
}
|
|
732
|
+
return identifiers;
|
|
733
|
+
};
|
|
734
|
+
var transpileExpression = ({
|
|
735
|
+
expression,
|
|
736
|
+
executable = false,
|
|
737
|
+
replaceVariable
|
|
738
|
+
}) => {
|
|
739
|
+
let root;
|
|
740
|
+
try {
|
|
741
|
+
root = parseExpressionAt(expression, 0, { ecmaVersion: "latest" });
|
|
742
|
+
} catch (error) {
|
|
743
|
+
const message = error.message;
|
|
744
|
+
throw Error(`${message} in ${JSON.stringify(expression)}`);
|
|
745
|
+
}
|
|
746
|
+
const replacements = [];
|
|
747
|
+
const replaceIdentifier = (node, assignee) => {
|
|
748
|
+
const newName = replaceVariable?.(node.name, assignee);
|
|
749
|
+
if (newName) {
|
|
750
|
+
replacements.push([node.start, node.end, newName]);
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
simple(root, {
|
|
754
|
+
Identifier: (node) => replaceIdentifier(node, false),
|
|
755
|
+
AssignmentExpression(node) {
|
|
756
|
+
simple(node.left, {
|
|
757
|
+
Identifier: (node2) => replaceIdentifier(node2, true)
|
|
758
|
+
});
|
|
759
|
+
},
|
|
760
|
+
MemberExpression(node) {
|
|
761
|
+
if (executable === false || node.optional) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
if (node.computed === false) {
|
|
765
|
+
const dotIndex = expression.indexOf(".", node.object.end);
|
|
766
|
+
replacements.push([dotIndex, dotIndex, "?"]);
|
|
767
|
+
}
|
|
768
|
+
if (node.computed === true) {
|
|
769
|
+
const dotIndex = expression.indexOf("[", node.object.end);
|
|
770
|
+
replacements.push([dotIndex, dotIndex, "?."]);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
});
|
|
774
|
+
replacements.sort(([leftStart], [rightStart]) => rightStart - leftStart);
|
|
775
|
+
for (const [start, end, fragment] of replacements) {
|
|
776
|
+
const before = expression.slice(0, start);
|
|
777
|
+
const after = expression.slice(end);
|
|
778
|
+
expression = before + fragment + after;
|
|
779
|
+
}
|
|
780
|
+
return expression;
|
|
781
|
+
};
|
|
782
|
+
var dataSourceVariablePrefix = "$ws$dataSource$";
|
|
783
|
+
var encodeDataSourceVariable = (id) => {
|
|
784
|
+
const encoded = id.replaceAll("-", "__DASH__");
|
|
785
|
+
return `${dataSourceVariablePrefix}${encoded}`;
|
|
786
|
+
};
|
|
787
|
+
var decodeDataSourceVariable = (name) => {
|
|
788
|
+
if (name.startsWith(dataSourceVariablePrefix)) {
|
|
789
|
+
const encoded = name.slice(dataSourceVariablePrefix.length);
|
|
790
|
+
return encoded.replaceAll("__DASH__", "-");
|
|
791
|
+
}
|
|
792
|
+
return;
|
|
793
|
+
};
|
|
794
|
+
var generateExpression = ({
|
|
795
|
+
expression,
|
|
796
|
+
dataSources,
|
|
797
|
+
usedDataSources,
|
|
798
|
+
scope
|
|
799
|
+
}) => {
|
|
800
|
+
return transpileExpression({
|
|
801
|
+
expression,
|
|
802
|
+
executable: true,
|
|
803
|
+
replaceVariable: (identifier) => {
|
|
804
|
+
const depId = decodeDataSourceVariable(identifier);
|
|
805
|
+
const dep = depId ? dataSources.get(depId) : void 0;
|
|
806
|
+
if (dep) {
|
|
807
|
+
usedDataSources?.set(dep.id, dep);
|
|
808
|
+
return scope.getName(dep.id, dep.name);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
};
|
|
813
|
+
var executeExpression = (expression) => {
|
|
814
|
+
try {
|
|
815
|
+
const fn = new Function(`return (${expression})`);
|
|
816
|
+
return fn();
|
|
817
|
+
} catch {
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
// src/forms-generator.ts
|
|
822
|
+
var generateFormsProperties = (props) => {
|
|
823
|
+
const formsProperties = /* @__PURE__ */ new Map();
|
|
824
|
+
for (const prop of props.values()) {
|
|
825
|
+
if (prop.type === "string") {
|
|
826
|
+
if (prop.name === "action" || prop.name === "method") {
|
|
827
|
+
let properties = formsProperties.get(prop.instanceId);
|
|
828
|
+
if (properties === void 0) {
|
|
829
|
+
properties = {};
|
|
830
|
+
}
|
|
831
|
+
properties[prop.name] = prop.value;
|
|
832
|
+
formsProperties.set(prop.instanceId, properties);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
const entriesString = JSON.stringify(Array.from(formsProperties.entries()));
|
|
837
|
+
let generated = "";
|
|
838
|
+
generated += `type FormProperties = { method?: string, action?: string }
|
|
839
|
+
`;
|
|
840
|
+
generated += `export const formsProperties = new Map<string, FormProperties>(${entriesString})
|
|
841
|
+
`;
|
|
842
|
+
return generated;
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
// src/resources-generator.ts
|
|
846
|
+
var generateResourcesLoader = ({
|
|
847
|
+
scope,
|
|
848
|
+
page,
|
|
849
|
+
dataSources,
|
|
850
|
+
resources
|
|
851
|
+
}) => {
|
|
852
|
+
let generatedOutput = "";
|
|
853
|
+
let generatedLoaders = "";
|
|
854
|
+
let hasResources = false;
|
|
855
|
+
const usedDataSources = /* @__PURE__ */ new Map();
|
|
856
|
+
for (const dataSource of dataSources.values()) {
|
|
857
|
+
if (dataSource.type === "resource") {
|
|
858
|
+
const resource = resources.get(dataSource.resourceId);
|
|
859
|
+
if (resource === void 0) {
|
|
860
|
+
continue;
|
|
861
|
+
}
|
|
862
|
+
hasResources = true;
|
|
863
|
+
const resourceName = scope.getName(resource.id, dataSource.name);
|
|
864
|
+
generatedOutput += `${resourceName},
|
|
865
|
+
`;
|
|
866
|
+
generatedLoaders += `loadResource({
|
|
867
|
+
`;
|
|
868
|
+
generatedLoaders += `id: "${resource.id}",
|
|
869
|
+
`;
|
|
870
|
+
generatedLoaders += `name: ${JSON.stringify(resource.name)},
|
|
871
|
+
`;
|
|
872
|
+
const url = generateExpression({
|
|
873
|
+
expression: resource.url,
|
|
874
|
+
dataSources,
|
|
875
|
+
usedDataSources,
|
|
876
|
+
scope
|
|
877
|
+
});
|
|
878
|
+
generatedLoaders += `url: ${url},
|
|
879
|
+
`;
|
|
880
|
+
generatedLoaders += `method: "${resource.method}",
|
|
881
|
+
`;
|
|
882
|
+
generatedLoaders += `headers: [
|
|
883
|
+
`;
|
|
884
|
+
for (const header of resource.headers) {
|
|
885
|
+
const value = generateExpression({
|
|
886
|
+
expression: header.value,
|
|
887
|
+
dataSources,
|
|
888
|
+
usedDataSources,
|
|
889
|
+
scope
|
|
890
|
+
});
|
|
891
|
+
generatedLoaders += `{ name: "${header.name}", value: ${value} },
|
|
892
|
+
`;
|
|
893
|
+
}
|
|
894
|
+
generatedLoaders += `],
|
|
895
|
+
`;
|
|
896
|
+
if (resource.body !== void 0 && resource.body.length > 0) {
|
|
897
|
+
const body = generateExpression({
|
|
898
|
+
expression: resource.body,
|
|
899
|
+
dataSources,
|
|
900
|
+
usedDataSources,
|
|
901
|
+
scope
|
|
902
|
+
});
|
|
903
|
+
generatedLoaders += `body: ${body},
|
|
904
|
+
`;
|
|
905
|
+
}
|
|
906
|
+
generatedLoaders += `}),
|
|
907
|
+
`;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
let generatedVariables = "";
|
|
911
|
+
for (const dataSource of usedDataSources.values()) {
|
|
912
|
+
if (dataSource.type === "variable") {
|
|
913
|
+
const name = scope.getName(dataSource.id, dataSource.name);
|
|
914
|
+
const value = JSON.stringify(dataSource.value.value);
|
|
915
|
+
generatedVariables += `let ${name} = ${value}
|
|
916
|
+
`;
|
|
917
|
+
}
|
|
918
|
+
if (dataSource.type === "parameter") {
|
|
919
|
+
if (dataSource.id !== page.systemDataSourceId) {
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
const name = scope.getName(dataSource.id, dataSource.name);
|
|
923
|
+
generatedVariables += `const ${name} = _props.system
|
|
924
|
+
`;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
let generated = "";
|
|
928
|
+
generated += `import { loadResource, type System } from "@webstudio-is/sdk";
|
|
929
|
+
`;
|
|
930
|
+
generated += `export const loadResources = async (_props: { system: System }) => {
|
|
931
|
+
`;
|
|
932
|
+
generated += generatedVariables;
|
|
933
|
+
if (hasResources) {
|
|
934
|
+
generated += `const [
|
|
935
|
+
`;
|
|
936
|
+
generated += generatedOutput;
|
|
937
|
+
generated += `] = await Promise.all([
|
|
938
|
+
`;
|
|
939
|
+
generated += generatedLoaders;
|
|
940
|
+
generated += `])
|
|
941
|
+
`;
|
|
942
|
+
}
|
|
943
|
+
generated += `return {
|
|
944
|
+
`;
|
|
945
|
+
generated += generatedOutput;
|
|
946
|
+
generated += `} as Record<string, unknown>
|
|
947
|
+
`;
|
|
948
|
+
generated += `}
|
|
949
|
+
`;
|
|
950
|
+
return generated;
|
|
951
|
+
};
|
|
952
|
+
|
|
953
|
+
// src/page-meta-generator.ts
|
|
954
|
+
var generatePageMeta = ({
|
|
955
|
+
globalScope,
|
|
956
|
+
page,
|
|
957
|
+
dataSources
|
|
958
|
+
}) => {
|
|
959
|
+
const localScope = createScope(["system", "resources"]);
|
|
960
|
+
const usedDataSources = /* @__PURE__ */ new Map();
|
|
961
|
+
const titleExpression = generateExpression({
|
|
962
|
+
expression: page.title,
|
|
963
|
+
dataSources,
|
|
964
|
+
usedDataSources,
|
|
965
|
+
scope: localScope
|
|
966
|
+
});
|
|
967
|
+
const descriptionExpression = generateExpression({
|
|
968
|
+
expression: page.meta.description ?? "undefined",
|
|
969
|
+
dataSources,
|
|
970
|
+
usedDataSources,
|
|
971
|
+
scope: localScope
|
|
972
|
+
});
|
|
973
|
+
const excludePageFromSearchExpression = generateExpression({
|
|
974
|
+
expression: page.meta.excludePageFromSearch ?? "undefined",
|
|
975
|
+
dataSources,
|
|
976
|
+
usedDataSources,
|
|
977
|
+
scope: localScope
|
|
978
|
+
});
|
|
979
|
+
const languageExpression = generateExpression({
|
|
980
|
+
expression: page.meta.language ?? "undefined",
|
|
981
|
+
dataSources,
|
|
982
|
+
usedDataSources,
|
|
983
|
+
scope: localScope
|
|
984
|
+
});
|
|
985
|
+
const socialImageAssetIdExpression = JSON.stringify(
|
|
986
|
+
page.meta.socialImageAssetId
|
|
987
|
+
);
|
|
988
|
+
const socialImageUrlExpression = generateExpression({
|
|
989
|
+
expression: page.meta.socialImageUrl ?? "undefined",
|
|
990
|
+
dataSources,
|
|
991
|
+
usedDataSources,
|
|
992
|
+
scope: localScope
|
|
993
|
+
});
|
|
994
|
+
const statusExpression = generateExpression({
|
|
995
|
+
expression: page.meta.status ?? "undefined",
|
|
996
|
+
dataSources,
|
|
997
|
+
usedDataSources,
|
|
998
|
+
scope: localScope
|
|
999
|
+
});
|
|
1000
|
+
const redirectExpression = generateExpression({
|
|
1001
|
+
expression: page.meta.redirect ?? "undefined",
|
|
1002
|
+
dataSources,
|
|
1003
|
+
usedDataSources,
|
|
1004
|
+
scope: localScope
|
|
1005
|
+
});
|
|
1006
|
+
let customExpression = "";
|
|
1007
|
+
customExpression += `[
|
|
1008
|
+
`;
|
|
1009
|
+
for (const customMeta of page.meta.custom ?? []) {
|
|
1010
|
+
if (customMeta.property.trim().length === 0) {
|
|
1011
|
+
continue;
|
|
1012
|
+
}
|
|
1013
|
+
const propertyExpression = JSON.stringify(customMeta.property);
|
|
1014
|
+
const contentExpression = generateExpression({
|
|
1015
|
+
expression: customMeta.content,
|
|
1016
|
+
dataSources,
|
|
1017
|
+
usedDataSources,
|
|
1018
|
+
scope: localScope
|
|
1019
|
+
});
|
|
1020
|
+
customExpression += ` {
|
|
1021
|
+
`;
|
|
1022
|
+
customExpression += ` property: ${propertyExpression},
|
|
1023
|
+
`;
|
|
1024
|
+
customExpression += ` content: ${contentExpression},
|
|
1025
|
+
`;
|
|
1026
|
+
customExpression += ` },
|
|
1027
|
+
`;
|
|
1028
|
+
}
|
|
1029
|
+
customExpression += ` ]`;
|
|
1030
|
+
let generated = "";
|
|
1031
|
+
generated += `export const getPageMeta = ({
|
|
1032
|
+
`;
|
|
1033
|
+
generated += ` system,
|
|
1034
|
+
`;
|
|
1035
|
+
generated += ` resources,
|
|
1036
|
+
`;
|
|
1037
|
+
generated += `}: {
|
|
1038
|
+
`;
|
|
1039
|
+
generated += ` system: System;
|
|
1040
|
+
`;
|
|
1041
|
+
generated += ` resources: Record<string, any>;
|
|
1042
|
+
`;
|
|
1043
|
+
generated += `}): PageMeta => {
|
|
1044
|
+
`;
|
|
1045
|
+
for (const dataSource of usedDataSources.values()) {
|
|
1046
|
+
if (dataSource.type === "variable") {
|
|
1047
|
+
const valueName = localScope.getName(dataSource.id, dataSource.name);
|
|
1048
|
+
const initialValueString = JSON.stringify(dataSource.value.value);
|
|
1049
|
+
generated += ` let ${valueName} = ${initialValueString}
|
|
1050
|
+
`;
|
|
1051
|
+
continue;
|
|
1052
|
+
}
|
|
1053
|
+
if (dataSource.type === "parameter") {
|
|
1054
|
+
if (dataSource.id === page.systemDataSourceId) {
|
|
1055
|
+
const valueName = localScope.getName(dataSource.id, dataSource.name);
|
|
1056
|
+
generated += ` let ${valueName} = system
|
|
1057
|
+
`;
|
|
1058
|
+
}
|
|
1059
|
+
continue;
|
|
1060
|
+
}
|
|
1061
|
+
if (dataSource.type === "resource") {
|
|
1062
|
+
const valueName = localScope.getName(dataSource.id, dataSource.name);
|
|
1063
|
+
const resourceName = globalScope.getName(
|
|
1064
|
+
dataSource.resourceId,
|
|
1065
|
+
dataSource.name
|
|
1066
|
+
);
|
|
1067
|
+
generated += ` let ${valueName} = resources.${resourceName}
|
|
1068
|
+
`;
|
|
1069
|
+
continue;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
generated += ` return {
|
|
1073
|
+
`;
|
|
1074
|
+
generated += ` title: ${titleExpression},
|
|
1075
|
+
`;
|
|
1076
|
+
generated += ` description: ${descriptionExpression},
|
|
1077
|
+
`;
|
|
1078
|
+
generated += ` excludePageFromSearch: ${excludePageFromSearchExpression},
|
|
1079
|
+
`;
|
|
1080
|
+
generated += ` language: ${languageExpression},
|
|
1081
|
+
`;
|
|
1082
|
+
generated += ` socialImageAssetId: ${socialImageAssetIdExpression},
|
|
1083
|
+
`;
|
|
1084
|
+
generated += ` socialImageUrl: ${socialImageUrlExpression},
|
|
1085
|
+
`;
|
|
1086
|
+
generated += ` status: ${statusExpression},
|
|
1087
|
+
`;
|
|
1088
|
+
generated += ` redirect: ${redirectExpression},
|
|
1089
|
+
`;
|
|
1090
|
+
generated += ` custom: ${customExpression},
|
|
1091
|
+
`;
|
|
1092
|
+
generated += ` };
|
|
1093
|
+
`;
|
|
1094
|
+
generated += `};
|
|
1095
|
+
`;
|
|
1096
|
+
return generated;
|
|
1097
|
+
};
|
|
582
1098
|
export {
|
|
583
1099
|
Asset,
|
|
584
1100
|
Assets,
|
|
@@ -621,14 +1137,25 @@ export {
|
|
|
621
1137
|
TextChild,
|
|
622
1138
|
WebstudioFragment,
|
|
623
1139
|
createScope,
|
|
1140
|
+
decodeDataSourceVariable,
|
|
1141
|
+
encodeDataSourceVariable,
|
|
1142
|
+
executeExpression,
|
|
624
1143
|
findPageByIdOrPath,
|
|
625
1144
|
findParentFolderByChildId,
|
|
626
1145
|
findTreeInstanceIds,
|
|
627
1146
|
findTreeInstanceIdsExcludingSlotDescendants,
|
|
1147
|
+
generateExpression,
|
|
1148
|
+
generateFormsProperties,
|
|
1149
|
+
generatePageMeta,
|
|
1150
|
+
generateResourcesLoader,
|
|
1151
|
+
getExpressionIdentifiers,
|
|
628
1152
|
getPagePath,
|
|
629
1153
|
getStyleDeclKey,
|
|
630
1154
|
initialBreakpoints,
|
|
1155
|
+
isLiteralExpression,
|
|
631
1156
|
isRoot,
|
|
1157
|
+
lintExpression,
|
|
632
1158
|
loadResource,
|
|
633
|
-
parseComponentName
|
|
1159
|
+
parseComponentName,
|
|
1160
|
+
transpileExpression
|
|
634
1161
|
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { type Identifier } from "acorn";
|
|
2
|
+
import type { DataSources } from "./schema/data-sources";
|
|
3
|
+
import type { Scope } from "./scope";
|
|
4
|
+
export type Diagnostic = {
|
|
5
|
+
from: number;
|
|
6
|
+
to: number;
|
|
7
|
+
severity: "error" | "hint" | "info" | "warning";
|
|
8
|
+
message: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const lintExpression: ({ expression, availableVariables, allowAssignment, }: {
|
|
11
|
+
expression: string;
|
|
12
|
+
availableVariables?: Set<string> | undefined;
|
|
13
|
+
allowAssignment?: boolean | undefined;
|
|
14
|
+
}) => Diagnostic[];
|
|
15
|
+
/**
|
|
16
|
+
* check whether provided expression is a literal value
|
|
17
|
+
* like "", 0 or { param: "value" }
|
|
18
|
+
* which does not depends on any variable
|
|
19
|
+
*/
|
|
20
|
+
export declare const isLiteralExpression: (expression: string) => boolean;
|
|
21
|
+
export declare const getExpressionIdentifiers: (expression: string) => Set<string>;
|
|
22
|
+
/**
|
|
23
|
+
* transpile expression into executable one
|
|
24
|
+
*
|
|
25
|
+
* add optional chaining operator to every member expression
|
|
26
|
+
* to access any field without runtime errors
|
|
27
|
+
*
|
|
28
|
+
* replace variable names if necessary
|
|
29
|
+
*/
|
|
30
|
+
export declare const transpileExpression: ({ expression, executable, replaceVariable, }: {
|
|
31
|
+
expression: string;
|
|
32
|
+
executable?: boolean | undefined;
|
|
33
|
+
replaceVariable?: ((identifier: string, assignee: boolean) => string | undefined | void) | undefined;
|
|
34
|
+
}) => string;
|
|
35
|
+
export declare const encodeDataSourceVariable: (id: string) => string;
|
|
36
|
+
export declare const decodeDataSourceVariable: (name: string) => string | undefined;
|
|
37
|
+
export declare const generateExpression: ({ expression, dataSources, usedDataSources, scope, }: {
|
|
38
|
+
expression: string;
|
|
39
|
+
dataSources: Map<string, {
|
|
40
|
+
value: {
|
|
41
|
+
value: number;
|
|
42
|
+
type: "number";
|
|
43
|
+
} | {
|
|
44
|
+
value: string;
|
|
45
|
+
type: "string";
|
|
46
|
+
} | {
|
|
47
|
+
value: boolean;
|
|
48
|
+
type: "boolean";
|
|
49
|
+
} | {
|
|
50
|
+
value: string[];
|
|
51
|
+
type: "string[]";
|
|
52
|
+
} | {
|
|
53
|
+
type: "json";
|
|
54
|
+
value?: unknown;
|
|
55
|
+
};
|
|
56
|
+
type: "variable";
|
|
57
|
+
id: string;
|
|
58
|
+
name: string;
|
|
59
|
+
scopeInstanceId?: string | undefined;
|
|
60
|
+
} | {
|
|
61
|
+
type: "parameter";
|
|
62
|
+
id: string;
|
|
63
|
+
name: string;
|
|
64
|
+
scopeInstanceId?: string | undefined;
|
|
65
|
+
} | {
|
|
66
|
+
type: "resource";
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
resourceId: string;
|
|
70
|
+
scopeInstanceId?: string | undefined;
|
|
71
|
+
}>;
|
|
72
|
+
usedDataSources: Map<string, {
|
|
73
|
+
value: {
|
|
74
|
+
value: number;
|
|
75
|
+
type: "number";
|
|
76
|
+
} | {
|
|
77
|
+
value: string;
|
|
78
|
+
type: "string";
|
|
79
|
+
} | {
|
|
80
|
+
value: boolean;
|
|
81
|
+
type: "boolean";
|
|
82
|
+
} | {
|
|
83
|
+
value: string[];
|
|
84
|
+
type: "string[]";
|
|
85
|
+
} | {
|
|
86
|
+
type: "json";
|
|
87
|
+
value?: unknown;
|
|
88
|
+
};
|
|
89
|
+
type: "variable";
|
|
90
|
+
id: string;
|
|
91
|
+
name: string;
|
|
92
|
+
scopeInstanceId?: string | undefined;
|
|
93
|
+
} | {
|
|
94
|
+
type: "parameter";
|
|
95
|
+
id: string;
|
|
96
|
+
name: string;
|
|
97
|
+
scopeInstanceId?: string | undefined;
|
|
98
|
+
} | {
|
|
99
|
+
type: "resource";
|
|
100
|
+
id: string;
|
|
101
|
+
name: string;
|
|
102
|
+
resourceId: string;
|
|
103
|
+
scopeInstanceId?: string | undefined;
|
|
104
|
+
}>;
|
|
105
|
+
scope: Scope;
|
|
106
|
+
}) => string;
|
|
107
|
+
export declare const executeExpression: (expression: undefined | string) => any;
|