@examplary/cli 1.12.0 → 1.14.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/dist/commands/upload.js +13 -0
- package/dist/lib/bundle.d.ts +6 -0
- package/dist/lib/bundle.js +28 -1
- package/dist/lib/response-processing.js +4 -1
- package/dist/lib/validate.d.ts +2 -0
- package/dist/lib/validate.js +30 -2
- package/dist/preview-ui/assets/icon-nodes-CxaTPv-R.js +2 -0
- package/dist/preview-ui/assets/icon-nodes-CxaTPv-R.js.map +1 -0
- package/dist/preview-ui/assets/index-b38eDKFI.js +3663 -0
- package/dist/preview-ui/assets/{index-DGC5S2UY.js.map → index-b38eDKFI.js.map} +1 -1
- package/dist/preview-ui/assets/index-boullcXq.css +1 -0
- package/dist/preview-ui/assets/tags-BUvo71XG.js +2 -0
- package/dist/preview-ui/assets/tags-BUvo71XG.js.map +1 -0
- package/dist/preview-ui/index.html +2 -2
- package/package.json +11 -11
- package/dist/preview-ui/assets/icon-nodes-DWBwwVXR.js +0 -2
- package/dist/preview-ui/assets/icon-nodes-DWBwwVXR.js.map +0 -1
- package/dist/preview-ui/assets/index-C7khl3ZD.css +0 -1
- package/dist/preview-ui/assets/index-DGC5S2UY.js +0 -3637
- package/dist/preview-ui/assets/tags-DkzE0dXT.js +0 -2
- package/dist/preview-ui/assets/tags-DkzE0dXT.js.map +0 -1
package/dist/commands/upload.js
CHANGED
|
@@ -38,6 +38,19 @@ export const uploadCommand = async (argv) => {
|
|
|
38
38
|
console.log(`• Uploaded component ${componentType}`);
|
|
39
39
|
}
|
|
40
40
|
definition.components = components;
|
|
41
|
+
// Upload the bundled functions
|
|
42
|
+
const functions = {};
|
|
43
|
+
for (const [functionName, output] of Object.entries(result.functions)) {
|
|
44
|
+
// Upload source map first if it exists
|
|
45
|
+
let sourceMapStatement = "";
|
|
46
|
+
if (output.sourcemap) {
|
|
47
|
+
const url = await uploadFile(`function-${functionName}.js.map`, output.sourcemap, "application/json");
|
|
48
|
+
sourceMapStatement = `\n//# sourceMappingURL=${url}`;
|
|
49
|
+
}
|
|
50
|
+
functions[functionName] = await uploadFile(`function-${functionName}.js`, output.js + sourceMapStatement, "application/javascript");
|
|
51
|
+
console.log(`• Uploaded function ${functionName}`);
|
|
52
|
+
}
|
|
53
|
+
definition.functions = functions;
|
|
41
54
|
// Upload styles if present
|
|
42
55
|
if (result.styles) {
|
|
43
56
|
definition.stylesheet = await uploadFile("styles.css", result.styles, "text/css");
|
package/dist/lib/bundle.d.ts
CHANGED
package/dist/lib/bundle.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { createHash } from "crypto";
|
|
1
2
|
import { build } from "esbuild";
|
|
3
|
+
const calculateHash = (compiled) => {
|
|
4
|
+
return createHash("sha256").update(compiled).digest("hex");
|
|
5
|
+
};
|
|
2
6
|
export const buildComponent = async (file) => {
|
|
3
7
|
const res = await build({
|
|
4
8
|
entryPoints: [file],
|
|
@@ -23,5 +27,28 @@ export const buildComponent = async (file) => {
|
|
|
23
27
|
sourcemap = Buffer.from(js.split(sourceMapStatement)[1].trim(), "base64").toString("utf-8");
|
|
24
28
|
js = js.split(sourceMapStatement)[0].trim();
|
|
25
29
|
}
|
|
26
|
-
|
|
30
|
+
const sha256 = calculateHash(js);
|
|
31
|
+
return { js, sourcemap, sha256 };
|
|
32
|
+
};
|
|
33
|
+
export const buildFunction = async (file) => {
|
|
34
|
+
const res = await build({
|
|
35
|
+
entryPoints: [file],
|
|
36
|
+
bundle: true,
|
|
37
|
+
write: false,
|
|
38
|
+
minify: true,
|
|
39
|
+
sourcemap: "inline",
|
|
40
|
+
platform: "neutral",
|
|
41
|
+
mainFields: ["module", "main"],
|
|
42
|
+
format: "iife",
|
|
43
|
+
globalName: "userFunction",
|
|
44
|
+
});
|
|
45
|
+
let js = res.outputFiles[0].text;
|
|
46
|
+
let sourcemap = "";
|
|
47
|
+
const sourceMapStatement = "\n//# sourceMappingURL=data:application/json;base64,";
|
|
48
|
+
if (js.includes(sourceMapStatement)) {
|
|
49
|
+
sourcemap = Buffer.from(js.split(sourceMapStatement)[1].trim(), "base64").toString("utf-8");
|
|
50
|
+
js = js.split(sourceMapStatement)[0].trim();
|
|
51
|
+
}
|
|
52
|
+
const sha256 = calculateHash(js);
|
|
53
|
+
return { js, sourcemap, sha256 };
|
|
27
54
|
};
|
|
@@ -9,7 +9,10 @@ const evaluateCondition = async (condition, data) => {
|
|
|
9
9
|
throw new Error("Invalid response processing condition: must start with '='");
|
|
10
10
|
}
|
|
11
11
|
const outcome = await jsonata(condition.substring(1)).evaluate(data);
|
|
12
|
-
|
|
12
|
+
if (typeof outcome !== "boolean") {
|
|
13
|
+
throw new Error(`Response processing condition must evaluate to a boolean, got ${typeof outcome}`);
|
|
14
|
+
}
|
|
15
|
+
return outcome;
|
|
13
16
|
};
|
|
14
17
|
/**
|
|
15
18
|
* Runs every `responseProcessing.testCases` through the `condition` and checks
|
package/dist/lib/validate.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ export type ValidationResult = {
|
|
|
18
18
|
styles?: string;
|
|
19
19
|
/** Raw icon file contents, present only when an icon is configured. */
|
|
20
20
|
iconContents?: string;
|
|
21
|
+
/** Bundled function output, keyed by function name, ready to upload. */
|
|
22
|
+
functions: Record<string, BuiltComponent>;
|
|
21
23
|
};
|
|
22
24
|
/**
|
|
23
25
|
* Runs every check the `upload` command performs, short of actually uploading:
|
package/dist/lib/validate.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFile } from "fs/promises";
|
|
2
2
|
import { resolve } from "path";
|
|
3
|
-
import { buildComponent } from "./bundle.js";
|
|
3
|
+
import { buildComponent, buildFunction } from "./bundle.js";
|
|
4
4
|
import { deepCompileJsonata } from "./jsonata.js";
|
|
5
5
|
import { runResponseProcessingTestCases, } from "./response-processing.js";
|
|
6
6
|
import { buildStyles } from "./styles.js";
|
|
@@ -20,6 +20,7 @@ export const validateDefinition = async (definition, dir) => {
|
|
|
20
20
|
const errors = [];
|
|
21
21
|
const warnings = [];
|
|
22
22
|
const bundles = {};
|
|
23
|
+
const functions = {};
|
|
23
24
|
let styles;
|
|
24
25
|
let iconContents;
|
|
25
26
|
if (!definition.id)
|
|
@@ -89,6 +90,21 @@ export const validateDefinition = async (definition, dir) => {
|
|
|
89
90
|
errors.push(`Error bundling component ${componentType} from ${componentPath}: ${error.message}`);
|
|
90
91
|
}
|
|
91
92
|
}
|
|
93
|
+
// Bundle functions to confirm they build and to capture their output
|
|
94
|
+
for (const [functionName, functionPath] of Object.entries(definition.functions || {})) {
|
|
95
|
+
const realPath = resolve(dir, functionPath);
|
|
96
|
+
try {
|
|
97
|
+
const output = await buildFunction(realPath);
|
|
98
|
+
functions[functionName] = output;
|
|
99
|
+
const sizeInKb = output.js.length / 1000;
|
|
100
|
+
if (sizeInKb > 100) {
|
|
101
|
+
errors.push(`Function ${functionName} is larger than the 100 kB limit (${sizeInKb.toFixed(2)} kB)`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
errors.push(`Error bundling function ${functionName} from ${functionPath}: ${error.message}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
92
108
|
// Build styles if any components are present
|
|
93
109
|
if (Object.keys(bundles).length) {
|
|
94
110
|
styles = (await buildStyles()) ?? undefined;
|
|
@@ -106,7 +122,15 @@ export const validateDefinition = async (definition, dir) => {
|
|
|
106
122
|
errors.push(`Icon file is empty: ${iconPath}`);
|
|
107
123
|
}
|
|
108
124
|
}
|
|
109
|
-
return {
|
|
125
|
+
return {
|
|
126
|
+
errors,
|
|
127
|
+
warnings,
|
|
128
|
+
testCaseResults,
|
|
129
|
+
bundles,
|
|
130
|
+
functions,
|
|
131
|
+
styles,
|
|
132
|
+
iconContents,
|
|
133
|
+
};
|
|
110
134
|
};
|
|
111
135
|
/** Whether the definition is safe to upload. */
|
|
112
136
|
export const isValid = (result) => result.errors.length === 0 && result.testCaseResults.every((r) => r.passed);
|
|
@@ -116,6 +140,10 @@ export const printValidationResult = (result) => {
|
|
|
116
140
|
const sizeInKb = (output.js.length / 1000).toFixed(2);
|
|
117
141
|
console.log(`• Bundled component ${componentType} (${sizeInKb} kB)`);
|
|
118
142
|
}
|
|
143
|
+
for (const [functionName, output] of Object.entries(result.functions)) {
|
|
144
|
+
const sizeInKb = (output.js.length / 1000).toFixed(2);
|
|
145
|
+
console.log(`• Bundled function ${functionName} (${sizeInKb} kB)`);
|
|
146
|
+
}
|
|
119
147
|
for (const warning of result.warnings) {
|
|
120
148
|
console.warn(` ⚠️ ${warning.message}`);
|
|
121
149
|
if (warning.file && process.env.GITHUB_ACTIONS) {
|