@osdk/widget.vite-plugin 3.2.0-beta.1 → 3.2.0-beta.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/CHANGELOG.md +20 -0
- package/build/esm/common/__tests__/extractWidgetConfig.test.js +22 -0
- package/build/esm/common/__tests__/extractWidgetConfig.test.js.map +1 -1
- package/build/esm/common/__tests__/validateWidgetConfig.test.js +109 -0
- package/build/esm/common/__tests__/validateWidgetConfig.test.js.map +1 -0
- package/build/esm/common/extractWidgetConfig.js +2 -0
- package/build/esm/common/extractWidgetConfig.js.map +1 -1
- package/build/esm/common/validateWidgetConfig.js +60 -0
- package/build/esm/common/validateWidgetConfig.js.map +1 -0
- package/build/esm/dev-plugin/__tests__/getWidgetIdOverrideMap.test.js +5 -1
- package/build/esm/dev-plugin/__tests__/getWidgetIdOverrideMap.test.js.map +1 -1
- package/build/types/common/__tests__/validateWidgetConfig.test.d.ts +1 -0
- package/build/types/common/__tests__/validateWidgetConfig.test.d.ts.map +1 -0
- package/build/types/common/extractWidgetConfig.d.ts.map +1 -1
- package/build/types/common/validateWidgetConfig.d.ts +6 -0
- package/build/types/common/validateWidgetConfig.d.ts.map +1 -0
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @osdk/widget.vite-plugin
|
|
2
2
|
|
|
3
|
+
## 3.2.0-beta.3
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 71fc408: Validate camelCase for widget/parameter IDs
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- @osdk/widget.api@3.2.0-beta.3
|
|
12
|
+
|
|
13
|
+
## 3.2.0-beta.2
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- 2b73c3c: Fix @osdk/widget.vite-plugin dependency on resolve-package-path in devDependencies rather than dependencies
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- @osdk/widget.api@3.2.0-beta.2
|
|
22
|
+
|
|
3
23
|
## 3.1.0-beta.5
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { beforeEach, describe, expect, test, vi } from "vitest";
|
|
18
18
|
import { extractWidgetConfig } from "../extractWidgetConfig.js";
|
|
19
|
+
import * as validateWidgetConfigModule from "../validateWidgetConfig.js";
|
|
19
20
|
const MOCK_SERVER = {
|
|
20
21
|
ssrLoadModule: vi.fn()
|
|
21
22
|
};
|
|
@@ -27,8 +28,29 @@ describe("extractWidgetConfig", () => {
|
|
|
27
28
|
vi.mocked(MOCK_SERVER.ssrLoadModule).mockResolvedValue({
|
|
28
29
|
default: MOCK_CONFIG
|
|
29
30
|
});
|
|
31
|
+
const validateSpy = vi.spyOn(validateWidgetConfigModule, "validateWidgetConfig");
|
|
30
32
|
const result = await extractWidgetConfig("/path/to/config.ts", MOCK_SERVER);
|
|
31
33
|
expect(result).toEqual(MOCK_CONFIG);
|
|
34
|
+
expect(validateSpy).toHaveBeenCalledWith(MOCK_CONFIG);
|
|
35
|
+
});
|
|
36
|
+
test("throws for invalid widget configuration", async () => {
|
|
37
|
+
vi.mocked(MOCK_SERVER.ssrLoadModule).mockResolvedValue({
|
|
38
|
+
default: {
|
|
39
|
+
id: "Invalid-Id",
|
|
40
|
+
name: "Test Widget",
|
|
41
|
+
type: "workshop",
|
|
42
|
+
parameters: {}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
vi.spyOn(validateWidgetConfigModule, "validateWidgetConfig").mockImplementation(config => {
|
|
46
|
+
throw new Error(`Widget id "${config.id}" does not match allowed pattern (must be camelCase)`);
|
|
47
|
+
});
|
|
48
|
+
await expect(extractWidgetConfig("/path/to/config.ts", MOCK_SERVER)).rejects.toThrow(expect.objectContaining({
|
|
49
|
+
message: "Failed to load widget config from /path/to/config.ts",
|
|
50
|
+
cause: expect.objectContaining({
|
|
51
|
+
message: `Widget id "Invalid-Id" does not match allowed pattern (must be camelCase)`
|
|
52
|
+
})
|
|
53
|
+
}));
|
|
32
54
|
});
|
|
33
55
|
test("throws for missing default export", async () => {
|
|
34
56
|
vi.mocked(MOCK_SERVER.ssrLoadModule).mockResolvedValue({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractWidgetConfig.test.js","names":["beforeEach","describe","expect","test","vi","extractWidgetConfig","MOCK_SERVER","ssrLoadModule","fn","restoreAllMocks","mocked","mockResolvedValue","default","MOCK_CONFIG","result","toEqual","
|
|
1
|
+
{"version":3,"file":"extractWidgetConfig.test.js","names":["beforeEach","describe","expect","test","vi","extractWidgetConfig","validateWidgetConfigModule","MOCK_SERVER","ssrLoadModule","fn","restoreAllMocks","mocked","mockResolvedValue","default","MOCK_CONFIG","validateSpy","spyOn","result","toEqual","toHaveBeenCalledWith","id","name","type","parameters","mockImplementation","config","Error","rejects","toThrow","objectContaining","message","cause","notDefault","mockRejectedValue","description","paramOne","displayName","paramTwo","events","updateParameters","parameterUpdateIds"],"sources":["extractWidgetConfig.test.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ViteDevServer } from \"vite\";\nimport { beforeEach, describe, expect, test, vi } from \"vitest\";\nimport { extractWidgetConfig } from \"../extractWidgetConfig.js\";\nimport * as validateWidgetConfigModule from \"../validateWidgetConfig.js\";\n\nconst MOCK_SERVER = {\n ssrLoadModule: vi.fn(),\n} as unknown as ViteDevServer;\n\ndescribe(\"extractWidgetConfig\", () => {\n beforeEach(() => {\n vi.restoreAllMocks();\n });\n\n test(\"extracts valid widget configuration\", async () => {\n vi.mocked(MOCK_SERVER.ssrLoadModule).mockResolvedValue({\n default: MOCK_CONFIG,\n });\n\n const validateSpy = vi.spyOn(\n validateWidgetConfigModule,\n \"validateWidgetConfig\",\n );\n\n const result = await extractWidgetConfig(\"/path/to/config.ts\", MOCK_SERVER);\n expect(result).toEqual(MOCK_CONFIG);\n expect(validateSpy).toHaveBeenCalledWith(MOCK_CONFIG);\n });\n\n test(\"throws for invalid widget configuration\", async () => {\n const INVALID_CONFIG = {\n id: \"Invalid-Id\",\n name: \"Test Widget\",\n type: \"workshop\",\n parameters: {},\n };\n\n vi.mocked(MOCK_SERVER.ssrLoadModule).mockResolvedValue({\n default: INVALID_CONFIG,\n });\n\n vi.spyOn(validateWidgetConfigModule, \"validateWidgetConfig\")\n .mockImplementation(config => {\n throw new Error(\n `Widget id \"${config.id}\" does not match allowed pattern (must be camelCase)`,\n );\n });\n\n await expect(extractWidgetConfig(\"/path/to/config.ts\", MOCK_SERVER))\n .rejects.toThrow(\n expect.objectContaining({\n message: \"Failed to load widget config from /path/to/config.ts\",\n cause: expect.objectContaining({\n message:\n `Widget id \"Invalid-Id\" does not match allowed pattern (must be camelCase)`,\n }),\n }),\n );\n });\n\n test(\"throws for missing default export\", async () => {\n vi.mocked(MOCK_SERVER.ssrLoadModule).mockResolvedValue({\n notDefault: { id: \"test\" },\n });\n\n await expect(extractWidgetConfig(\"/path/to/config.ts\", MOCK_SERVER))\n .rejects.toThrow(\n expect.objectContaining({\n message: \"Failed to load widget config from /path/to/config.ts\",\n cause: expect.objectContaining({\n message: \"No default export found in /path/to/config.ts\",\n }),\n }),\n );\n });\n\n test(\"throws for invalid module path\", async () => {\n vi.mocked(MOCK_SERVER.ssrLoadModule).mockRejectedValue(\n new Error(\"Module loading failed\"),\n );\n\n await expect(extractWidgetConfig(\"/invalid/path/config.ts\", MOCK_SERVER))\n .rejects.toThrow(\"Failed to load widget config\");\n });\n});\n\nconst MOCK_CONFIG = {\n id: \"testWidget\",\n name: \"Test Widget\",\n description: \"A test widget\",\n type: \"workshop\",\n parameters: {\n paramOne: {\n displayName: \"Parameter One\",\n type: \"string\",\n },\n paramTwo: {\n displayName: \"Parameter Two\",\n type: \"string\",\n },\n },\n events: {\n updateParameters: {\n displayName: \"Update Parameters\",\n parameterUpdateIds: [\"paramOne\", \"paramTwo\"],\n },\n },\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { describe, expect, test } from "vitest";
|
|
18
|
+
import { validateWidgetConfig } from "../validateWidgetConfig.js";
|
|
19
|
+
describe("validateWidgetConfig", () => {
|
|
20
|
+
test("accepts valid widget configuration", () => {
|
|
21
|
+
const validConfig = getValidConfig();
|
|
22
|
+
expect(() => validateWidgetConfig(validConfig)).not.toThrow();
|
|
23
|
+
});
|
|
24
|
+
test("throws for widget id that exceeds max length", () => {
|
|
25
|
+
const invalidConfig = getValidConfig();
|
|
26
|
+
invalidConfig.id = "a".repeat(101);
|
|
27
|
+
expect(() => validateWidgetConfig(invalidConfig)).toThrow("Widget id length can be at most 100 characters");
|
|
28
|
+
});
|
|
29
|
+
test("throws for widget id that is not camelCase", () => {
|
|
30
|
+
const testCases = [{
|
|
31
|
+
id: "TestWidget",
|
|
32
|
+
message: "does not match allowed pattern"
|
|
33
|
+
}, {
|
|
34
|
+
id: "test-widget",
|
|
35
|
+
message: "does not match allowed pattern"
|
|
36
|
+
}, {
|
|
37
|
+
id: "test_widget",
|
|
38
|
+
message: "does not match allowed pattern"
|
|
39
|
+
}, {
|
|
40
|
+
id: "1testWidget",
|
|
41
|
+
message: "does not match allowed pattern"
|
|
42
|
+
}];
|
|
43
|
+
for (const {
|
|
44
|
+
id,
|
|
45
|
+
message
|
|
46
|
+
} of testCases) {
|
|
47
|
+
const invalidConfig = getValidConfig();
|
|
48
|
+
invalidConfig.id = id;
|
|
49
|
+
expect(() => validateWidgetConfig(invalidConfig)).toThrow(message);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
test("throws for widget name that exceeds max length", () => {
|
|
53
|
+
const invalidConfig = getValidConfig();
|
|
54
|
+
invalidConfig.name = "A".repeat(101);
|
|
55
|
+
expect(() => validateWidgetConfig(invalidConfig)).toThrow("Widget name length can be at most 100 characters");
|
|
56
|
+
});
|
|
57
|
+
test("throws for widget description that exceeds max length", () => {
|
|
58
|
+
const invalidConfig = getValidConfig();
|
|
59
|
+
invalidConfig.description = "A".repeat(251);
|
|
60
|
+
expect(() => validateWidgetConfig(invalidConfig)).toThrow("Widget description length can be at most 250 characters");
|
|
61
|
+
});
|
|
62
|
+
test("accepts undefined widget description", () => {
|
|
63
|
+
const validConfig = getValidConfig();
|
|
64
|
+
delete validConfig.description;
|
|
65
|
+
expect(() => validateWidgetConfig(validConfig)).not.toThrow();
|
|
66
|
+
});
|
|
67
|
+
test("throws for parameter id that is not camelCase", () => {
|
|
68
|
+
const invalidConfig = getValidConfig();
|
|
69
|
+
invalidConfig.parameters = {
|
|
70
|
+
"Invalid-Param": {
|
|
71
|
+
displayName: "Invalid Parameter",
|
|
72
|
+
type: "string"
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
expect(() => validateWidgetConfig(invalidConfig)).toThrow("Parameter id \"Invalid-Param\" does not match allowed pattern (must be camelCase)");
|
|
76
|
+
});
|
|
77
|
+
test("throws for parameter id that exceeds max length", () => {
|
|
78
|
+
const invalidConfig = getValidConfig();
|
|
79
|
+
const longParamId = "param" + "a".repeat(96); // 101 chars total
|
|
80
|
+
invalidConfig.parameters = {
|
|
81
|
+
[longParamId]: {
|
|
82
|
+
displayName: "Long Parameter",
|
|
83
|
+
type: "string"
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
expect(() => validateWidgetConfig(invalidConfig)).toThrow("Parameter id length can be at most 100 characters");
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
function getValidConfig() {
|
|
90
|
+
return {
|
|
91
|
+
id: "testWidget",
|
|
92
|
+
name: "Test Widget",
|
|
93
|
+
description: "A test widget",
|
|
94
|
+
type: "workshop",
|
|
95
|
+
parameters: {
|
|
96
|
+
paramOne: {
|
|
97
|
+
displayName: "Parameter One",
|
|
98
|
+
type: "string"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
events: {
|
|
102
|
+
updateParameters: {
|
|
103
|
+
displayName: "Update Parameters",
|
|
104
|
+
parameterUpdateIds: ["paramOne"]
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=validateWidgetConfig.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateWidgetConfig.test.js","names":["describe","expect","test","validateWidgetConfig","validConfig","getValidConfig","not","toThrow","invalidConfig","id","repeat","testCases","message","name","description","parameters","displayName","type","longParamId","paramOne","events","updateParameters","parameterUpdateIds"],"sources":["validateWidgetConfig.test.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ParameterConfig, WidgetConfig } from \"@osdk/widget.api\";\nimport { describe, expect, test } from \"vitest\";\nimport { validateWidgetConfig } from \"../validateWidgetConfig.js\";\n\ndescribe(\"validateWidgetConfig\", () => {\n test(\"accepts valid widget configuration\", () => {\n const validConfig = getValidConfig();\n expect(() => validateWidgetConfig(validConfig)).not.toThrow();\n });\n\n test(\"throws for widget id that exceeds max length\", () => {\n const invalidConfig = getValidConfig();\n invalidConfig.id = \"a\".repeat(101);\n\n expect(() => validateWidgetConfig(invalidConfig)).toThrow(\n \"Widget id length can be at most 100 characters\",\n );\n });\n\n test(\"throws for widget id that is not camelCase\", () => {\n const testCases = [\n { id: \"TestWidget\", message: \"does not match allowed pattern\" },\n { id: \"test-widget\", message: \"does not match allowed pattern\" },\n { id: \"test_widget\", message: \"does not match allowed pattern\" },\n { id: \"1testWidget\", message: \"does not match allowed pattern\" },\n ];\n\n for (const { id, message } of testCases) {\n const invalidConfig = getValidConfig();\n invalidConfig.id = id;\n expect(() => validateWidgetConfig(invalidConfig)).toThrow(message);\n }\n });\n\n test(\"throws for widget name that exceeds max length\", () => {\n const invalidConfig = getValidConfig();\n invalidConfig.name = \"A\".repeat(101);\n\n expect(() => validateWidgetConfig(invalidConfig)).toThrow(\n \"Widget name length can be at most 100 characters\",\n );\n });\n\n test(\"throws for widget description that exceeds max length\", () => {\n const invalidConfig = getValidConfig();\n invalidConfig.description = \"A\".repeat(251);\n\n expect(() => validateWidgetConfig(invalidConfig)).toThrow(\n \"Widget description length can be at most 250 characters\",\n );\n });\n\n test(\"accepts undefined widget description\", () => {\n const validConfig = getValidConfig();\n delete validConfig.description;\n\n expect(() => validateWidgetConfig(validConfig)).not.toThrow();\n });\n\n test(\"throws for parameter id that is not camelCase\", () => {\n const invalidConfig = getValidConfig();\n invalidConfig.parameters = {\n \"Invalid-Param\": {\n displayName: \"Invalid Parameter\",\n type: \"string\",\n },\n };\n\n expect(() => validateWidgetConfig(invalidConfig)).toThrow(\n \"Parameter id \\\"Invalid-Param\\\" does not match allowed pattern (must be camelCase)\",\n );\n });\n\n test(\"throws for parameter id that exceeds max length\", () => {\n const invalidConfig = getValidConfig();\n const longParamId = \"param\" + \"a\".repeat(96); // 101 chars total\n invalidConfig.parameters = {\n [longParamId]: {\n displayName: \"Long Parameter\",\n type: \"string\",\n },\n };\n\n expect(() => validateWidgetConfig(invalidConfig)).toThrow(\n \"Parameter id length can be at most 100 characters\",\n );\n });\n});\n\nfunction getValidConfig(): WidgetConfig<ParameterConfig> {\n return {\n id: \"testWidget\",\n name: \"Test Widget\",\n description: \"A test widget\",\n type: \"workshop\",\n parameters: {\n paramOne: {\n displayName: \"Parameter One\",\n type: \"string\",\n },\n },\n events: {\n updateParameters: {\n displayName: \"Update Parameters\",\n parameterUpdateIds: [\"paramOne\"],\n },\n },\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { validateWidgetConfig } from "./validateWidgetConfig.js";
|
|
17
18
|
export async function extractWidgetConfig(moduleId, server) {
|
|
18
19
|
try {
|
|
19
20
|
const configModule = await server.ssrLoadModule(moduleId);
|
|
@@ -21,6 +22,7 @@ export async function extractWidgetConfig(moduleId, server) {
|
|
|
21
22
|
if (config == null) {
|
|
22
23
|
throw new Error(`No default export found in ${moduleId}`);
|
|
23
24
|
}
|
|
25
|
+
validateWidgetConfig(config);
|
|
24
26
|
return config;
|
|
25
27
|
} catch (error) {
|
|
26
28
|
throw new Error(`Failed to load widget config from ${moduleId}`, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractWidgetConfig.js","names":["extractWidgetConfig","moduleId","server","configModule","ssrLoadModule","config","default","Error","error","cause"],"sources":["extractWidgetConfig.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ParameterConfig, WidgetConfig } from \"@osdk/widget.api\";\nimport type { ViteDevServer } from \"vite\";\n\nexport async function extractWidgetConfig(\n moduleId: string,\n server: ViteDevServer,\n): Promise<WidgetConfig<ParameterConfig>> {\n try {\n const configModule = await server.ssrLoadModule(moduleId);\n const config = configModule.default;\n\n if (config == null) {\n throw new Error(`No default export found in ${moduleId}`);\n }\n\n return config as WidgetConfig<ParameterConfig>;\n } catch (error) {\n throw new Error(`Failed to load widget config from ${moduleId}`, {\n cause: error,\n });\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;
|
|
1
|
+
{"version":3,"file":"extractWidgetConfig.js","names":["validateWidgetConfig","extractWidgetConfig","moduleId","server","configModule","ssrLoadModule","config","default","Error","error","cause"],"sources":["extractWidgetConfig.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ParameterConfig, WidgetConfig } from \"@osdk/widget.api\";\nimport type { ViteDevServer } from \"vite\";\nimport { validateWidgetConfig } from \"./validateWidgetConfig.js\";\n\nexport async function extractWidgetConfig(\n moduleId: string,\n server: ViteDevServer,\n): Promise<WidgetConfig<ParameterConfig>> {\n try {\n const configModule = await server.ssrLoadModule(moduleId);\n const config = configModule.default;\n\n if (config == null) {\n throw new Error(`No default export found in ${moduleId}`);\n }\n\n validateWidgetConfig(config);\n return config as WidgetConfig<ParameterConfig>;\n } catch (error) {\n throw new Error(`Failed to load widget config from ${moduleId}`, {\n cause: error,\n });\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA,SAASA,oBAAoB,QAAQ,2BAA2B;AAEhE,OAAO,eAAeC,mBAAmBA,CACvCC,QAAgB,EAChBC,MAAqB,EACmB;EACxC,IAAI;IACF,MAAMC,YAAY,GAAG,MAAMD,MAAM,CAACE,aAAa,CAACH,QAAQ,CAAC;IACzD,MAAMI,MAAM,GAAGF,YAAY,CAACG,OAAO;IAEnC,IAAID,MAAM,IAAI,IAAI,EAAE;MAClB,MAAM,IAAIE,KAAK,CAAC,8BAA8BN,QAAQ,EAAE,CAAC;IAC3D;IAEAF,oBAAoB,CAACM,MAAM,CAAC;IAC5B,OAAOA,MAAM;EACf,CAAC,CAAC,OAAOG,KAAK,EAAE;IACd,MAAM,IAAID,KAAK,CAAC,qCAAqCN,QAAQ,EAAE,EAAE;MAC/DQ,KAAK,EAAED;IACT,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const ID_PATTERN = /^([a-z][a-z0-9]*)([A-Z][a-z0-9]*)*$/;
|
|
18
|
+
const ID_MAX_LENGTH = 100;
|
|
19
|
+
const NAME_MAX_LENGTH = 100;
|
|
20
|
+
const DESCRIPTION_MAX_LENGTH = 250;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Validates the requirements that can't be expressed via TypeScript type-checking
|
|
24
|
+
* for a widget config (e.g. that widget IDs and parameter IDs are camelCase.)
|
|
25
|
+
*/
|
|
26
|
+
export function validateWidgetConfig(config) {
|
|
27
|
+
validateWidgetId(config.id);
|
|
28
|
+
validateWidgetName(config.name);
|
|
29
|
+
validateWidgetDescription(config.description);
|
|
30
|
+
validateWidgetParameters(config.parameters);
|
|
31
|
+
}
|
|
32
|
+
function validateWidgetId(id) {
|
|
33
|
+
if (id.length > ID_MAX_LENGTH) {
|
|
34
|
+
throw new Error(`Widget id length can be at most ${ID_MAX_LENGTH} characters`);
|
|
35
|
+
}
|
|
36
|
+
if (!ID_PATTERN.test(id)) {
|
|
37
|
+
throw new Error(`Widget id "${id}" does not match allowed pattern (must be camelCase)`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function validateWidgetName(name) {
|
|
41
|
+
if (name.length > NAME_MAX_LENGTH) {
|
|
42
|
+
throw new Error(`Widget name length can be at most ${NAME_MAX_LENGTH} characters`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function validateWidgetDescription(description) {
|
|
46
|
+
if (description != null && description.length > DESCRIPTION_MAX_LENGTH) {
|
|
47
|
+
throw new Error(`Widget description length can be at most ${DESCRIPTION_MAX_LENGTH} characters`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function validateWidgetParameters(parameters) {
|
|
51
|
+
for (const parameterId of Object.keys(parameters)) {
|
|
52
|
+
if (parameterId.length > ID_MAX_LENGTH) {
|
|
53
|
+
throw new Error(`Parameter id length can be at most ${ID_MAX_LENGTH} characters`);
|
|
54
|
+
}
|
|
55
|
+
if (!ID_PATTERN.test(parameterId)) {
|
|
56
|
+
throw new Error(`Parameter id "${parameterId}" does not match allowed pattern (must be camelCase)`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=validateWidgetConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateWidgetConfig.js","names":["ID_PATTERN","ID_MAX_LENGTH","NAME_MAX_LENGTH","DESCRIPTION_MAX_LENGTH","validateWidgetConfig","config","validateWidgetId","id","validateWidgetName","name","validateWidgetDescription","description","validateWidgetParameters","parameters","length","Error","test","parameterId","Object","keys"],"sources":["validateWidgetConfig.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ParameterConfig, WidgetConfig } from \"@osdk/widget.api\";\n\nconst ID_PATTERN = /^([a-z][a-z0-9]*)([A-Z][a-z0-9]*)*$/;\nconst ID_MAX_LENGTH = 100;\nconst NAME_MAX_LENGTH = 100;\nconst DESCRIPTION_MAX_LENGTH = 250;\n\n/**\n * Validates the requirements that can't be expressed via TypeScript type-checking\n * for a widget config (e.g. that widget IDs and parameter IDs are camelCase.)\n */\nexport function validateWidgetConfig(\n config: WidgetConfig<ParameterConfig>,\n): void {\n validateWidgetId(config.id);\n validateWidgetName(config.name);\n validateWidgetDescription(config.description);\n validateWidgetParameters(config.parameters);\n}\n\nfunction validateWidgetId(id: string): void {\n if (id.length > ID_MAX_LENGTH) {\n throw new Error(\n `Widget id length can be at most ${ID_MAX_LENGTH} characters`,\n );\n }\n if (!ID_PATTERN.test(id)) {\n throw new Error(\n `Widget id \"${id}\" does not match allowed pattern (must be camelCase)`,\n );\n }\n}\n\nfunction validateWidgetName(name: string): void {\n if (name.length > NAME_MAX_LENGTH) {\n throw new Error(\n `Widget name length can be at most ${NAME_MAX_LENGTH} characters`,\n );\n }\n}\n\nfunction validateWidgetDescription(description?: string): void {\n if (description != null && description.length > DESCRIPTION_MAX_LENGTH) {\n throw new Error(\n `Widget description length can be at most ${DESCRIPTION_MAX_LENGTH} characters`,\n );\n }\n}\n\nfunction validateWidgetParameters(parameters: ParameterConfig): void {\n for (const parameterId of Object.keys(parameters)) {\n if (parameterId.length > ID_MAX_LENGTH) {\n throw new Error(\n `Parameter id length can be at most ${ID_MAX_LENGTH} characters`,\n );\n }\n if (!ID_PATTERN.test(parameterId)) {\n throw new Error(\n `Parameter id \"${parameterId}\" does not match allowed pattern (must be camelCase)`,\n );\n }\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA,MAAMA,UAAU,GAAG,qCAAqC;AACxD,MAAMC,aAAa,GAAG,GAAG;AACzB,MAAMC,eAAe,GAAG,GAAG;AAC3B,MAAMC,sBAAsB,GAAG,GAAG;;AAElC;AACA;AACA;AACA;AACA,OAAO,SAASC,oBAAoBA,CAClCC,MAAqC,EAC/B;EACNC,gBAAgB,CAACD,MAAM,CAACE,EAAE,CAAC;EAC3BC,kBAAkB,CAACH,MAAM,CAACI,IAAI,CAAC;EAC/BC,yBAAyB,CAACL,MAAM,CAACM,WAAW,CAAC;EAC7CC,wBAAwB,CAACP,MAAM,CAACQ,UAAU,CAAC;AAC7C;AAEA,SAASP,gBAAgBA,CAACC,EAAU,EAAQ;EAC1C,IAAIA,EAAE,CAACO,MAAM,GAAGb,aAAa,EAAE;IAC7B,MAAM,IAAIc,KAAK,CACb,mCAAmCd,aAAa,aAClD,CAAC;EACH;EACA,IAAI,CAACD,UAAU,CAACgB,IAAI,CAACT,EAAE,CAAC,EAAE;IACxB,MAAM,IAAIQ,KAAK,CACb,cAAcR,EAAE,sDAClB,CAAC;EACH;AACF;AAEA,SAASC,kBAAkBA,CAACC,IAAY,EAAQ;EAC9C,IAAIA,IAAI,CAACK,MAAM,GAAGZ,eAAe,EAAE;IACjC,MAAM,IAAIa,KAAK,CACb,qCAAqCb,eAAe,aACtD,CAAC;EACH;AACF;AAEA,SAASQ,yBAAyBA,CAACC,WAAoB,EAAQ;EAC7D,IAAIA,WAAW,IAAI,IAAI,IAAIA,WAAW,CAACG,MAAM,GAAGX,sBAAsB,EAAE;IACtE,MAAM,IAAIY,KAAK,CACb,4CAA4CZ,sBAAsB,aACpE,CAAC;EACH;AACF;AAEA,SAASS,wBAAwBA,CAACC,UAA2B,EAAQ;EACnE,KAAK,MAAMI,WAAW,IAAIC,MAAM,CAACC,IAAI,CAACN,UAAU,CAAC,EAAE;IACjD,IAAII,WAAW,CAACH,MAAM,GAAGb,aAAa,EAAE;MACtC,MAAM,IAAIc,KAAK,CACb,sCAAsCd,aAAa,aACrD,CAAC;IACH;IACA,IAAI,CAACD,UAAU,CAACgB,IAAI,CAACC,WAAW,CAAC,EAAE;MACjC,MAAM,IAAIF,KAAK,CACb,iBAAiBE,WAAW,sDAC9B,CAAC;IACH;EACF;AACF","ignoreList":[]}
|
|
@@ -18,7 +18,11 @@ import { beforeEach, describe, expect, test, vi } from "vitest";
|
|
|
18
18
|
import * as extractInjectedScriptsModule from "../extractInjectedScripts.js";
|
|
19
19
|
import { getWidgetIdOverrideMap } from "../getWidgetIdOverrideMap.js";
|
|
20
20
|
const MOCK_WIDGET_CONFIG = {
|
|
21
|
-
id: "widgetId"
|
|
21
|
+
id: "widgetId",
|
|
22
|
+
name: "Widget Name",
|
|
23
|
+
type: "workshop",
|
|
24
|
+
parameters: {},
|
|
25
|
+
events: {}
|
|
22
26
|
};
|
|
23
27
|
const MOCK_SERVER = {
|
|
24
28
|
ssrLoadModule: vi.fn().mockResolvedValue({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getWidgetIdOverrideMap.test.js","names":["beforeEach","describe","expect","test","vi","extractInjectedScriptsModule","getWidgetIdOverrideMap","MOCK_WIDGET_CONFIG","id","MOCK_SERVER","ssrLoadModule","fn","mockResolvedValue","default","MOCK_CODE_ENTRYPOINTS","MOCK_CONFIG_FILE_TO_ENTRYPOINT","restoreAllMocks","mocked","spyOn","scriptSources","inlineScripts","baseHref","result","toEqual"],"sources":["getWidgetIdOverrideMap.test.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ParameterConfig, WidgetConfig } from \"@osdk/widget.api\";\nimport type { ViteDevServer } from \"vite\";\nimport { beforeEach, describe, expect, test, vi } from \"vitest\";\nimport * as extractInjectedScriptsModule from \"../extractInjectedScripts.js\";\nimport { getWidgetIdOverrideMap } from \"../getWidgetIdOverrideMap.js\";\n\nconst MOCK_WIDGET_CONFIG = {
|
|
1
|
+
{"version":3,"file":"getWidgetIdOverrideMap.test.js","names":["beforeEach","describe","expect","test","vi","extractInjectedScriptsModule","getWidgetIdOverrideMap","MOCK_WIDGET_CONFIG","id","name","type","parameters","events","MOCK_SERVER","ssrLoadModule","fn","mockResolvedValue","default","MOCK_CODE_ENTRYPOINTS","MOCK_CONFIG_FILE_TO_ENTRYPOINT","restoreAllMocks","mocked","spyOn","scriptSources","inlineScripts","baseHref","result","toEqual"],"sources":["getWidgetIdOverrideMap.test.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ParameterConfig, WidgetConfig } from \"@osdk/widget.api\";\nimport type { ViteDevServer } from \"vite\";\nimport { beforeEach, describe, expect, test, vi } from \"vitest\";\nimport * as extractInjectedScriptsModule from \"../extractInjectedScripts.js\";\nimport { getWidgetIdOverrideMap } from \"../getWidgetIdOverrideMap.js\";\n\nconst MOCK_WIDGET_CONFIG = {\n id: \"widgetId\",\n name: \"Widget Name\",\n type: \"workshop\",\n parameters: {},\n events: {},\n} as WidgetConfig<ParameterConfig>;\nconst MOCK_SERVER = {\n ssrLoadModule: vi.fn().mockResolvedValue({ default: MOCK_WIDGET_CONFIG }),\n} as unknown as ViteDevServer;\nconst MOCK_CODE_ENTRYPOINTS = { \"entry.ts\": `/entry.js` };\nconst MOCK_CONFIG_FILE_TO_ENTRYPOINT = { \"widget.config.ts\": \"entry.ts\" };\n\ndescribe(\"getWidgetIdOverrideMap\", () => {\n beforeEach(() => {\n vi.restoreAllMocks();\n vi.mocked(MOCK_SERVER.ssrLoadModule).mockResolvedValue({\n default: MOCK_WIDGET_CONFIG,\n });\n });\n\n test(\"localhost dev server URLs\", async () => {\n vi.spyOn(extractInjectedScriptsModule, \"extractInjectedScripts\")\n .mockResolvedValue({\n // Extracted scripts sources start with the base path\n scriptSources: [\"/@vite/client\"],\n inlineScripts: [],\n });\n const baseHref = `http://localhost:5173/`;\n\n const result = await getWidgetIdOverrideMap(\n MOCK_SERVER,\n MOCK_CODE_ENTRYPOINTS,\n MOCK_CONFIG_FILE_TO_ENTRYPOINT,\n baseHref,\n );\n\n expect(result).toEqual({\n \"widgetId\": [\n `${baseHref}.palantir/vite-injections.js`,\n `${baseHref}@vite/client`,\n `${baseHref}entry.js`,\n ],\n });\n });\n\n test(\"remote server URLs\", async () => {\n // Representative values when running dev mode in Code Workspaces mode\n vi.spyOn(extractInjectedScriptsModule, \"extractInjectedScripts\")\n .mockResolvedValue({\n // Extracted scripts sources start with the base path\n scriptSources: [`/proxy/path/@vite/client`],\n inlineScripts: [],\n });\n const baseHref = `https://worksapce.stack.com/proxy/path/`;\n\n const result = await getWidgetIdOverrideMap(\n MOCK_SERVER,\n MOCK_CODE_ENTRYPOINTS,\n MOCK_CONFIG_FILE_TO_ENTRYPOINT,\n baseHref,\n );\n\n expect(result).toEqual({\n \"widgetId\": [\n `${baseHref}.palantir/vite-injections.js`,\n `${baseHref}@vite/client`,\n `${baseHref}entry.js`,\n ],\n });\n });\n});\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA,SAASA,UAAU,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,IAAI,EAAEC,EAAE,QAAQ,QAAQ;AAC/D,OAAO,KAAKC,4BAA4B,MAAM,8BAA8B;AAC5E,SAASC,sBAAsB,QAAQ,8BAA8B;AAErE,MAAMC,kBAAkB,GAAG;EACzBC,EAAE,EAAE,UAAU;EACdC,IAAI,EAAE,aAAa;EACnBC,IAAI,EAAE,UAAU;EAChBC,UAAU,EAAE,CAAC,CAAC;EACdC,MAAM,EAAE,CAAC;AACX,CAAkC;AAClC,MAAMC,WAAW,GAAG;EAClBC,aAAa,EAAEV,EAAE,CAACW,EAAE,CAAC,CAAC,CAACC,iBAAiB,CAAC;IAAEC,OAAO,EAAEV;EAAmB,CAAC;AAC1E,CAA6B;AAC7B,MAAMW,qBAAqB,GAAG;EAAE,UAAU,EAAE;AAAY,CAAC;AACzD,MAAMC,8BAA8B,GAAG;EAAE,kBAAkB,EAAE;AAAW,CAAC;AAEzElB,QAAQ,CAAC,wBAAwB,EAAE,MAAM;EACvCD,UAAU,CAAC,MAAM;IACfI,EAAE,CAACgB,eAAe,CAAC,CAAC;IACpBhB,EAAE,CAACiB,MAAM,CAACR,WAAW,CAACC,aAAa,CAAC,CAACE,iBAAiB,CAAC;MACrDC,OAAO,EAAEV;IACX,CAAC,CAAC;EACJ,CAAC,CAAC;EAEFJ,IAAI,CAAC,2BAA2B,EAAE,YAAY;IAC5CC,EAAE,CAACkB,KAAK,CAACjB,4BAA4B,EAAE,wBAAwB,CAAC,CAC7DW,iBAAiB,CAAC;MACjB;MACAO,aAAa,EAAE,CAAC,eAAe,CAAC;MAChCC,aAAa,EAAE;IACjB,CAAC,CAAC;IACJ,MAAMC,QAAQ,GAAG,wBAAwB;IAEzC,MAAMC,MAAM,GAAG,MAAMpB,sBAAsB,CACzCO,WAAW,EACXK,qBAAqB,EACrBC,8BAA8B,EAC9BM,QACF,CAAC;IAEDvB,MAAM,CAACwB,MAAM,CAAC,CAACC,OAAO,CAAC;MACrB,UAAU,EAAE,CACV,GAAGF,QAAQ,8BAA8B,EACzC,GAAGA,QAAQ,cAAc,EACzB,GAAGA,QAAQ,UAAU;IAEzB,CAAC,CAAC;EACJ,CAAC,CAAC;EAEFtB,IAAI,CAAC,oBAAoB,EAAE,YAAY;IACrC;IACAC,EAAE,CAACkB,KAAK,CAACjB,4BAA4B,EAAE,wBAAwB,CAAC,CAC7DW,iBAAiB,CAAC;MACjB;MACAO,aAAa,EAAE,CAAC,0BAA0B,CAAC;MAC3CC,aAAa,EAAE;IACjB,CAAC,CAAC;IACJ,MAAMC,QAAQ,GAAG,yCAAyC;IAE1D,MAAMC,MAAM,GAAG,MAAMpB,sBAAsB,CACzCO,WAAW,EACXK,qBAAqB,EACrBC,8BAA8B,EAC9BM,QACF,CAAC;IAEDvB,MAAM,CAACwB,MAAM,CAAC,CAACC,OAAO,CAAC;MACrB,UAAU,EAAE,CACV,GAAGF,QAAQ,8BAA8B,EACzC,GAAGA,QAAQ,cAAc,EACzB,GAAGA,QAAQ,UAAU;IAEzB,CAAC,CAAC;EACJ,CAAC,CAAC;AACJ,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"","names":[],"sources":["../../../../src/common/__tests__/validateWidgetConfig.test.ts"],"version":3,"file":"validateWidgetConfig.test.d.ts"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAgBA,cAAc,iBAAiB,oBAAoB,kBAAmB;AACtE,cAAc,qBAAqB,MAAO;
|
|
1
|
+
{"mappings":"AAgBA,cAAc,iBAAiB,oBAAoB,kBAAmB;AACtE,cAAc,qBAAqB,MAAO;AAG1C,OAAO,iBAAe,oBACpBA,kBACAC,QAAQ,gBACP,QAAQ,aAAa","names":["moduleId: string","server: ViteDevServer"],"sources":["../../../src/common/extractWidgetConfig.ts"],"version":3,"file":"extractWidgetConfig.d.ts"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ParameterConfig, WidgetConfig } from "@osdk/widget.api";
|
|
2
|
+
/**
|
|
3
|
+
* Validates the requirements that can't be expressed via TypeScript type-checking
|
|
4
|
+
* for a widget config (e.g. that widget IDs and parameter IDs are camelCase.)
|
|
5
|
+
*/
|
|
6
|
+
export declare function validateWidgetConfig(config: WidgetConfig<ParameterConfig>): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"AAgBA,cAAc,iBAAiB,oBAAoB,kBAAmB;;;;;AAWtE,OAAO,iBAAS,qBACdA,QAAQ,aAAa","names":["config: WidgetConfig<ParameterConfig>"],"sources":["../../../src/common/validateWidgetConfig.ts"],"version":3,"file":"validateWidgetConfig.d.ts"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@osdk/widget.vite-plugin",
|
|
3
|
-
"version": "3.2.0-beta.
|
|
3
|
+
"version": "3.2.0-beta.3",
|
|
4
4
|
"description": "A vite plugin that will extract parameter definitions from TS/JS files + entrypoint info into a manifest file to be uploaded to Foundry ",
|
|
5
5
|
"access": "public",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,9 +28,10 @@
|
|
|
28
28
|
"fs-extra": "^11.3.0",
|
|
29
29
|
"parse5": "^7.2.1",
|
|
30
30
|
"picocolors": "^1.1.1",
|
|
31
|
+
"resolve-package-path": "^4.0.3",
|
|
31
32
|
"sirv": "^3.0.0",
|
|
32
33
|
"@osdk/foundry-config-json": "~1.4.0-beta.1",
|
|
33
|
-
"@osdk/widget.api": "~3.2.0-beta.
|
|
34
|
+
"@osdk/widget.api": "~3.2.0-beta.3"
|
|
34
35
|
},
|
|
35
36
|
"peerDependencies": {
|
|
36
37
|
"vite": "^6.3.5"
|
|
@@ -44,13 +45,12 @@
|
|
|
44
45
|
"@vitejs/plugin-react": "^4.2.0",
|
|
45
46
|
"react": "^18",
|
|
46
47
|
"react-dom": "^18",
|
|
47
|
-
"resolve-package-path": "^4.0.3",
|
|
48
48
|
"ts-expect": "^1.3.0",
|
|
49
49
|
"typescript": "~5.5.4",
|
|
50
50
|
"vite": "^6.3.5",
|
|
51
51
|
"vitest": "^3.0.5",
|
|
52
|
-
"@osdk/monorepo.
|
|
53
|
-
"@osdk/monorepo.
|
|
52
|
+
"@osdk/monorepo.tsconfig": "~0.4.0-beta.1",
|
|
53
|
+
"@osdk/monorepo.api-extractor": "~0.4.0-beta.1"
|
|
54
54
|
},
|
|
55
55
|
"publishConfig": {
|
|
56
56
|
"access": "public"
|