create-ec-app 1.0.0 → 1.2.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/index.js +228 -56
- package/dist/index.js.map +1 -1
- package/dist/libFunctions.js +1 -1
- package/dist/libFunctions.js.map +1 -1
- package/dist/pcf.d.ts +20 -0
- package/dist/pcf.d.ts.map +1 -0
- package/dist/pcf.js +130 -0
- package/dist/pcf.js.map +1 -0
- package/package.json +1 -1
- package/templates/pcf/base/ControlHost.pcfproj +15 -0
- package/templates/pcf/base/README.md +23 -0
- package/templates/pcf/base/control/ControlManifest.Input.xml +26 -0
- package/templates/pcf/base/featureconfig.json +3 -0
- package/templates/pcf/base/global.d.ts +1 -0
- package/templates/pcf/base/index.ts +152 -0
- package/templates/pcf/base/package.json +20 -0
- package/templates/pcf/base/strings/control.1033.resx +27 -0
- package/templates/pcf/base/tsconfig.json +31 -0
- package/templates/pcf/base/webpack.config.js +11 -0
- package/templates/targets/webresource/AGENTS.md +123 -0
- package/templates/targets/webresource/CLAUDE.md +1 -0
- package/templates/targets/webresource/README.md +70 -0
package/dist/index.js
CHANGED
|
@@ -4,31 +4,110 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
import { cancel, intro, isCancel, log, outro, select, spinner, text, } from "@clack/prompts";
|
|
5
5
|
import fs from "fs-extra";
|
|
6
6
|
import { applyLayer, replaceTokensRecursively } from "./libFunctions.js";
|
|
7
|
+
import { generatePcfFromExistingWebresource } from "./pcf.js";
|
|
7
8
|
const { execSync } = await import("node:child_process");
|
|
8
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
10
|
const __dirname = dirname(__filename);
|
|
10
11
|
async function main() {
|
|
12
|
+
const cliArgs = parseCliArgs(process.argv.slice(2));
|
|
13
|
+
if (cliArgs.pcfDir) {
|
|
14
|
+
const { pcfDir, ...rest } = cliArgs;
|
|
15
|
+
const result = await generatePcfFromExistingWebresource({
|
|
16
|
+
pcfDir,
|
|
17
|
+
...stripUndefined(rest),
|
|
18
|
+
});
|
|
19
|
+
outro(`Generated PCF control at ${result.outputDir} using template ${result.templateDir}`);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
11
22
|
intro("Create EC App");
|
|
23
|
+
const options = await resolveScaffoldOptions(cliArgs);
|
|
24
|
+
log.step(`Creating project: ${options.projectName}`);
|
|
25
|
+
log.step(`Selected target: ${options.target}`);
|
|
26
|
+
await scaffoldProject(options);
|
|
27
|
+
outro(`Scaffolded ${options.projectName} as ${options.target} with ${options.uiType}. Next steps: 'git remote origin add <url>'`);
|
|
28
|
+
}
|
|
29
|
+
async function resolveScaffoldOptions(cliArgs) {
|
|
30
|
+
const projectName = (cliArgs.projectName ?? (await promptProjectName())).trim();
|
|
31
|
+
const projectNameError = validateProjectName(projectName);
|
|
32
|
+
if (projectNameError) {
|
|
33
|
+
throw new Error(projectNameError);
|
|
34
|
+
}
|
|
35
|
+
const target = cliArgs.target ?? (await promptTarget());
|
|
36
|
+
const uiType = cliArgs.uiType ?? (await promptUiType());
|
|
37
|
+
const shouldPromptForInstall = cliArgs.install === undefined &&
|
|
38
|
+
(!cliArgs.projectName || !cliArgs.target || !cliArgs.uiType);
|
|
39
|
+
const install = shouldPromptForInstall
|
|
40
|
+
? await promptInstallDependencies()
|
|
41
|
+
: cliArgs.install ?? false;
|
|
42
|
+
return {
|
|
43
|
+
install,
|
|
44
|
+
projectName: projectName.trim(),
|
|
45
|
+
target,
|
|
46
|
+
uiType,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async function scaffoldProject({ install, projectName, target, uiType, }) {
|
|
50
|
+
const projectDir = path.join(process.cwd(), projectName);
|
|
51
|
+
const templatesRoot = path.join(__dirname, "..", "templates");
|
|
52
|
+
const baseDir = path.join(templatesRoot, "base");
|
|
53
|
+
const targetDir = path.join(templatesRoot, "targets", target);
|
|
54
|
+
const uiDir = path.join(templatesRoot, "ui", uiType);
|
|
55
|
+
await fs.copy(baseDir, projectDir);
|
|
56
|
+
if (fs.existsSync(targetDir)) {
|
|
57
|
+
await applyLayer(targetDir, projectDir);
|
|
58
|
+
}
|
|
59
|
+
if (fs.existsSync(uiDir)) {
|
|
60
|
+
await applyLayer(uiDir, projectDir);
|
|
61
|
+
}
|
|
62
|
+
await replaceTokensRecursively(projectDir, {
|
|
63
|
+
APP_NAME: projectName,
|
|
64
|
+
TARGET: target,
|
|
65
|
+
UI: uiType,
|
|
66
|
+
});
|
|
67
|
+
//WARN: This is a special case fix for having AuthContext in Kendo for Power Pages
|
|
68
|
+
if (target === "power-pages" && uiType === "kendo") {
|
|
69
|
+
const mainTsxPath = path.join(projectDir, "src", "main.tsx");
|
|
70
|
+
await fs.writeFile(mainTsxPath, POWER_PAGES_KENDO_MAIN_TSX, "utf-8");
|
|
71
|
+
}
|
|
72
|
+
if (install) {
|
|
73
|
+
const s = spinner();
|
|
74
|
+
s.start("Running npm install...");
|
|
75
|
+
const { execSync } = await import("node:child_process");
|
|
76
|
+
execSync("npm install", { cwd: projectDir, stdio: "inherit" });
|
|
77
|
+
s.stop("Dependencies installed.");
|
|
78
|
+
}
|
|
79
|
+
//INFO: npx on Windows can cause issues, so checking and creating a new gitignore
|
|
80
|
+
const gitignorePath = path.join(projectDir, ".gitignore");
|
|
81
|
+
if (!fs.existsSync(gitignorePath)) {
|
|
82
|
+
await fs.writeFile(gitignorePath, GIT_IGNORE, "utf-8");
|
|
83
|
+
}
|
|
84
|
+
const sGit = spinner();
|
|
85
|
+
sGit.start("Initializing git repository...");
|
|
86
|
+
execSync("git init", { cwd: projectDir, stdio: "ignore" });
|
|
87
|
+
execSync("git add .", { cwd: projectDir, stdio: "ignore" });
|
|
88
|
+
execSync('git commit -m "Initial commit"', {
|
|
89
|
+
cwd: projectDir,
|
|
90
|
+
stdio: "ignore",
|
|
91
|
+
});
|
|
92
|
+
sGit.stop("Git repository initialized.");
|
|
93
|
+
}
|
|
94
|
+
main().catch((err) => {
|
|
95
|
+
console.error(err);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
});
|
|
98
|
+
async function promptProjectName() {
|
|
12
99
|
const name = await text({
|
|
13
100
|
message: "Project name",
|
|
14
101
|
placeholder: "my-app",
|
|
15
|
-
validate
|
|
16
|
-
if (value.length === 0)
|
|
17
|
-
return "Project name cannot be empty";
|
|
18
|
-
if (value.toLocaleLowerCase() !== value)
|
|
19
|
-
return "Project name must be lowercase";
|
|
20
|
-
if (/\s/.test(value))
|
|
21
|
-
return "Project name cannot contain spaces";
|
|
22
|
-
if (/[^a-z0-9-_]/.test(value))
|
|
23
|
-
return "Project name can only contain letters, numbers, hyphens, and underscores";
|
|
24
|
-
},
|
|
102
|
+
validate: validateProjectName,
|
|
25
103
|
});
|
|
26
104
|
if (isCancel(name)) {
|
|
27
105
|
cancel("Operation cancelled.");
|
|
28
106
|
process.exit(0);
|
|
29
107
|
}
|
|
30
|
-
|
|
31
|
-
|
|
108
|
+
return String(name).trim();
|
|
109
|
+
}
|
|
110
|
+
async function promptTarget() {
|
|
32
111
|
const target = await select({
|
|
33
112
|
message: "What are you building?",
|
|
34
113
|
options: [
|
|
@@ -42,7 +121,9 @@ async function main() {
|
|
|
42
121
|
cancel("Operation cancelled.");
|
|
43
122
|
process.exit(0);
|
|
44
123
|
}
|
|
45
|
-
|
|
124
|
+
return target;
|
|
125
|
+
}
|
|
126
|
+
async function promptUiType() {
|
|
46
127
|
const uiType = await select({
|
|
47
128
|
message: "What UI library do you want to use?",
|
|
48
129
|
options: [
|
|
@@ -54,6 +135,9 @@ async function main() {
|
|
|
54
135
|
cancel("Operation cancelled.");
|
|
55
136
|
process.exit(0);
|
|
56
137
|
}
|
|
138
|
+
return uiType;
|
|
139
|
+
}
|
|
140
|
+
async function promptInstallDependencies() {
|
|
57
141
|
const shouldRunNpmInstall = await select({
|
|
58
142
|
message: "Do you want to install dependencies?",
|
|
59
143
|
options: [
|
|
@@ -65,55 +149,143 @@ async function main() {
|
|
|
65
149
|
cancel("Operation cancelled.");
|
|
66
150
|
process.exit(0);
|
|
67
151
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
152
|
+
return shouldRunNpmInstall.run;
|
|
153
|
+
}
|
|
154
|
+
function validateProjectName(value) {
|
|
155
|
+
if (value.length === 0)
|
|
156
|
+
return "Project name cannot be empty";
|
|
157
|
+
if (value.toLocaleLowerCase() !== value)
|
|
158
|
+
return "Project name must be lowercase";
|
|
159
|
+
if (/\s/.test(value))
|
|
160
|
+
return "Project name cannot contain spaces";
|
|
161
|
+
if (/[^a-z0-9-_]/.test(value))
|
|
162
|
+
return "Project name can only contain letters, numbers, hyphens, and underscores";
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
function parseCliArgs(argv) {
|
|
166
|
+
const read = (name) => {
|
|
167
|
+
const equalsPrefix = `${name}=`;
|
|
168
|
+
const equalsValue = argv.find((arg) => arg.startsWith(equalsPrefix));
|
|
169
|
+
if (equalsValue) {
|
|
170
|
+
return equalsValue.slice(equalsPrefix.length);
|
|
171
|
+
}
|
|
172
|
+
const index = argv.indexOf(name);
|
|
173
|
+
const value = index >= 0 ? argv[index + 1] : undefined;
|
|
174
|
+
return value && !value.startsWith("--") ? value : undefined;
|
|
175
|
+
};
|
|
176
|
+
const readAll = (name) => {
|
|
177
|
+
const values = [];
|
|
178
|
+
const equalsPrefix = `${name}=`;
|
|
179
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
180
|
+
const arg = argv[index];
|
|
181
|
+
if (arg?.startsWith(equalsPrefix)) {
|
|
182
|
+
values.push(arg.slice(equalsPrefix.length));
|
|
183
|
+
}
|
|
184
|
+
if (arg === name &&
|
|
185
|
+
argv[index + 1] &&
|
|
186
|
+
!argv[index + 1]?.startsWith("--")) {
|
|
187
|
+
values.push(argv[index + 1]);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return values;
|
|
191
|
+
};
|
|
192
|
+
const has = (name) => argv.includes(name);
|
|
193
|
+
const target = readTarget(argv);
|
|
194
|
+
const uiType = readUiType(argv);
|
|
195
|
+
const layers = readAll("--layer");
|
|
196
|
+
if (has("--install") && has("--no-install")) {
|
|
197
|
+
throw new Error("Use only one dependency option: --install or --no-install.");
|
|
76
198
|
}
|
|
77
|
-
|
|
78
|
-
|
|
199
|
+
const install = has("--install") ? true : has("--no-install") ? false : undefined;
|
|
200
|
+
return {
|
|
201
|
+
...defined("pcfDir", read("--pcf-dir")),
|
|
202
|
+
...defined("controlConstructor", read("--constructor")),
|
|
203
|
+
...defined("description", read("--description")),
|
|
204
|
+
...defined("displayName", read("--display-name")),
|
|
205
|
+
...defined("dist", read("--dist")),
|
|
206
|
+
...(layers.length > 0 ? { layers } : {}),
|
|
207
|
+
...defined("namespace", read("--namespace")),
|
|
208
|
+
...defined("output", read("--output")),
|
|
209
|
+
...defined("packageName", read("--package-name")),
|
|
210
|
+
...defined("template", read("--template")),
|
|
211
|
+
...defined("version", read("--version")),
|
|
212
|
+
...defined("projectName", read("--project-name") ?? read("--name")),
|
|
213
|
+
...defined("target", target),
|
|
214
|
+
...defined("uiType", uiType),
|
|
215
|
+
...defined("install", install),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function defined(key, value) {
|
|
219
|
+
return value === undefined ? {} : { [key]: value };
|
|
220
|
+
}
|
|
221
|
+
function readTarget(argv) {
|
|
222
|
+
const targetFlags = [
|
|
223
|
+
["--webresource", "webresource"],
|
|
224
|
+
["--portal", "portal"],
|
|
225
|
+
["--power-pages", "power-pages"],
|
|
226
|
+
["--swa", "swa"],
|
|
227
|
+
];
|
|
228
|
+
const selected = targetFlags.filter(([flag]) => argv.includes(flag));
|
|
229
|
+
const targetValue = readStringOption(argv, "--target");
|
|
230
|
+
if (selected.length > 1 || (selected.length === 1 && targetValue)) {
|
|
231
|
+
throw new Error("Use only one target option: --webresource, --portal, --power-pages, --swa, or --target.");
|
|
79
232
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
TARGET: target,
|
|
83
|
-
UI: uiType,
|
|
84
|
-
});
|
|
85
|
-
//WARN: This is a special case fix for having AuthContext in Kendo for Power Pages
|
|
86
|
-
if (target === "power-pages" && uiType === "kendo") {
|
|
87
|
-
const mainTsxPath = path.join(projectDir, "src", "main.tsx");
|
|
88
|
-
await fs.writeFile(mainTsxPath, POWER_PAGES_KENDO_MAIN_TSX, "utf-8");
|
|
233
|
+
if (selected.length === 1) {
|
|
234
|
+
return selected[0]?.[1];
|
|
89
235
|
}
|
|
90
|
-
if (
|
|
91
|
-
|
|
92
|
-
s.start("Running npm install...");
|
|
93
|
-
const { execSync } = await import("node:child_process");
|
|
94
|
-
execSync("npm install", { cwd: projectDir, stdio: "inherit" });
|
|
95
|
-
s.stop("Dependencies installed.");
|
|
236
|
+
if (!targetValue) {
|
|
237
|
+
return undefined;
|
|
96
238
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (!fs.existsSync(gitignorePath)) {
|
|
100
|
-
await fs.writeFile(gitignorePath, GIT_IGNORE, "utf-8");
|
|
239
|
+
if (isAppTarget(targetValue)) {
|
|
240
|
+
return targetValue;
|
|
101
241
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
242
|
+
throw new Error(`Unsupported target "${targetValue}". Use webresource, portal, power-pages, or swa.`);
|
|
243
|
+
}
|
|
244
|
+
function readUiType(argv) {
|
|
245
|
+
const uiFlags = [
|
|
246
|
+
["--kendo", "kendo"],
|
|
247
|
+
["--shadcn", "shadcn-ui"],
|
|
248
|
+
["--shadcn-ui", "shadcn-ui"],
|
|
249
|
+
];
|
|
250
|
+
const selected = uiFlags.filter(([flag]) => argv.includes(flag));
|
|
251
|
+
const uiValue = readStringOption(argv, "--ui");
|
|
252
|
+
if (selected.length > 1 || (selected.length === 1 && uiValue)) {
|
|
253
|
+
throw new Error("Use only one UI option: --kendo, --shadcn, --shadcn-ui, or --ui.");
|
|
254
|
+
}
|
|
255
|
+
if (selected.length === 1) {
|
|
256
|
+
return selected[0]?.[1];
|
|
257
|
+
}
|
|
258
|
+
if (!uiValue) {
|
|
259
|
+
return undefined;
|
|
260
|
+
}
|
|
261
|
+
if (isUiTarget(uiValue)) {
|
|
262
|
+
return uiValue;
|
|
263
|
+
}
|
|
264
|
+
if (uiValue === "shadcn") {
|
|
265
|
+
return "shadcn-ui";
|
|
266
|
+
}
|
|
267
|
+
throw new Error(`Unsupported UI "${uiValue}". Use kendo, shadcn, or shadcn-ui.`);
|
|
268
|
+
}
|
|
269
|
+
function readStringOption(argv, name) {
|
|
270
|
+
const equalsPrefix = `${name}=`;
|
|
271
|
+
const equalsValue = argv.find((arg) => arg.startsWith(equalsPrefix));
|
|
272
|
+
if (equalsValue) {
|
|
273
|
+
return equalsValue.slice(equalsPrefix.length);
|
|
274
|
+
}
|
|
275
|
+
const index = argv.indexOf(name);
|
|
276
|
+
const value = index >= 0 ? argv[index + 1] : undefined;
|
|
277
|
+
return value && !value.startsWith("--") ? value : undefined;
|
|
278
|
+
}
|
|
279
|
+
function isAppTarget(value) {
|
|
280
|
+
return ["webresource", "portal", "power-pages", "swa"].includes(value);
|
|
281
|
+
}
|
|
282
|
+
function isUiTarget(value) {
|
|
283
|
+
return ["kendo", "shadcn-ui"].includes(value);
|
|
284
|
+
}
|
|
285
|
+
function stripUndefined(value) {
|
|
286
|
+
const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== undefined);
|
|
287
|
+
return Object.fromEntries(entries);
|
|
112
288
|
}
|
|
113
|
-
main().catch((err) => {
|
|
114
|
-
console.error(err);
|
|
115
|
-
process.exit(1);
|
|
116
|
-
});
|
|
117
289
|
// NOTE: Constants
|
|
118
290
|
const POWER_PAGES_KENDO_MAIN_TSX = `import { StrictMode } from "react";
|
|
119
291
|
import { createRoot } from "react-dom/client";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/libFunctions.js
CHANGED
|
@@ -24,7 +24,7 @@ export async function applyLayer(layerDir, projectDir) {
|
|
|
24
24
|
await fs.writeJson(targetPath, merged, { spaces: 2 });
|
|
25
25
|
continue;
|
|
26
26
|
}
|
|
27
|
-
if (/\.(patch\.ts|patch\.tsx|patch\.js|patch\.jsx|patch\.css)$/.test(entry.name)) {
|
|
27
|
+
if (/\.(patch\.ts|patch\.tsx|patch\.js|patch\.jsx|patch\.css|patch\.xml|patch\.md)$/.test(entry.name)) {
|
|
28
28
|
const targetRel = relPath.replace(".patch.", ".");
|
|
29
29
|
const targetPath = path.join(projectDir, targetRel);
|
|
30
30
|
await fs.ensureDir(path.dirname(targetPath));
|
package/dist/libFunctions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libFunctions.js","sourceRoot":"","sources":["../src/libFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,UAAU,CAAC;AAE1B;;;;KAIK;AACL,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB,EAAE,UAAkB;IACpE,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAEnD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,MAAM,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/D,SAAS;QACV,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YACxC,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;YAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YAEpD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;YAE7C,MAAM,QAAQ,GAAG,CAAC,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5D,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAE/C,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;YAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;YAEtD,SAAS;QACV,CAAC;QAED,IACC,
|
|
1
|
+
{"version":3,"file":"libFunctions.js","sourceRoot":"","sources":["../src/libFunctions.ts"],"names":[],"mappings":"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"}
|
package/dist/pcf.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface PcfCliOptions {
|
|
2
|
+
pcfDir: string;
|
|
3
|
+
controlConstructor?: string | undefined;
|
|
4
|
+
description?: string | undefined;
|
|
5
|
+
displayName?: string | undefined;
|
|
6
|
+
dist?: string | undefined;
|
|
7
|
+
layers?: string[] | undefined;
|
|
8
|
+
namespace?: string | undefined;
|
|
9
|
+
output?: string | undefined;
|
|
10
|
+
packageName?: string | undefined;
|
|
11
|
+
template?: string | undefined;
|
|
12
|
+
version?: string | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare function generatePcfFromExistingWebresource(options: PcfCliOptions): Promise<{
|
|
15
|
+
constructorName: string;
|
|
16
|
+
namespace: string;
|
|
17
|
+
outputDir: string;
|
|
18
|
+
templateDir: string;
|
|
19
|
+
}>;
|
|
20
|
+
//# sourceMappingURL=pcf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pcf.d.ts","sourceRoot":"","sources":["../src/pcf.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,wBAAsB,kCAAkC,CACvD,OAAO,EAAE,aAAa,GACpB,OAAO,CAAC;IACV,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACpB,CAAC,CA0FD"}
|
package/dist/pcf.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import path, { dirname } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import fs from "fs-extra";
|
|
4
|
+
import { applyLayer, replaceTokensRecursively } from "./libFunctions.js";
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = dirname(__filename);
|
|
7
|
+
const RUNTIME_TYPES_TEMPLATE = `export interface PcfWebApi {
|
|
8
|
+
\tretrieve<T = Record<string, unknown>>(entitySet: string, id: string, query?: string): Promise<T>;
|
|
9
|
+
\tretrieveMultiple<T = Record<string, unknown>>(entitySet: string, query?: string): Promise<T[]>;
|
|
10
|
+
\tcreate<T = unknown>(entitySet: string, data: unknown): Promise<T>;
|
|
11
|
+
\tupdate(entitySet: string, id: string, data: unknown): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface PcfRuntimeContext {
|
|
15
|
+
\thost: "pcf";
|
|
16
|
+
\trecordId: string | null;
|
|
17
|
+
\tentityName: string | null;
|
|
18
|
+
\tclientUrl: string | null;
|
|
19
|
+
\tuserId: string | null;
|
|
20
|
+
\twebApi: PcfWebApi;
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
export async function generatePcfFromExistingWebresource(options) {
|
|
24
|
+
const projectDir = path.resolve(process.cwd(), options.pcfDir);
|
|
25
|
+
const packageJson = await readJson(path.join(projectDir, "package.json"));
|
|
26
|
+
const folderName = path.basename(projectDir);
|
|
27
|
+
const packageName = typeof packageJson?.name === "string" ? packageJson.name : folderName;
|
|
28
|
+
const displayName = toDisplayName(folderName);
|
|
29
|
+
const constructorName = options.controlConstructor ??
|
|
30
|
+
`${toPascalCase(packageName.replace(/[^a-z0-9]+/gi, " "))}Host`;
|
|
31
|
+
const namespace = options.namespace ?? "EC";
|
|
32
|
+
const version = options.version ?? "1.0.0";
|
|
33
|
+
const distDirName = options.dist ?? "dist";
|
|
34
|
+
const outputDir = path.resolve(projectDir, options.output ?? path.join("pcf", constructorName));
|
|
35
|
+
const templateDir = path.resolve(options.template ?? path.join(__dirname, "..", "templates", "pcf", "base"));
|
|
36
|
+
const layerDirs = (options.layers ?? []).map((layerDir) => path.resolve(projectDir, layerDir));
|
|
37
|
+
const controlDisplayName = options.displayName ?? `${displayName} Host`;
|
|
38
|
+
const controlDescription = options.description ??
|
|
39
|
+
`PCF wrapper that renders the ${displayName} React app directly inside a PCF control.`;
|
|
40
|
+
const packageNameToken = options.packageName ?? toKebabCase(constructorName);
|
|
41
|
+
const relToProject = toPosixPath(path.relative(outputDir, projectDir) || ".");
|
|
42
|
+
const appImportPath = ensureRelativeImport(toPosixPath(path.relative(outputDir, path.join(projectDir, "src", "App"))));
|
|
43
|
+
const runtimeTypesImportPath = ensureRelativeImport(toPosixPath(path.relative(outputDir, path.join(projectDir, "src", "runtime", "types"))));
|
|
44
|
+
const cssImportPath = ensureRelativeImport(toPosixPath(path.relative(outputDir, path.join(projectDir, distDirName, "main.css"))));
|
|
45
|
+
await assertFileExists(path.join(projectDir, "src", "App.tsx"), `Could not find src/App.tsx in ${projectDir}.`);
|
|
46
|
+
await assertFileExists(path.join(projectDir, distDirName, "main.css"), `Could not find ${distDirName}/main.css in ${projectDir}. Run the webresource build first.`);
|
|
47
|
+
await ensureRuntimeTypes(projectDir);
|
|
48
|
+
await fs.remove(outputDir);
|
|
49
|
+
await applyLayer(templateDir, outputDir);
|
|
50
|
+
for (const layerDir of layerDirs) {
|
|
51
|
+
await applyLayer(layerDir, outputDir);
|
|
52
|
+
}
|
|
53
|
+
await replaceTokensRecursively(outputDir, {
|
|
54
|
+
CONTROL_DESCRIPTION: controlDescription,
|
|
55
|
+
CONTROL_DISPLAY_NAME: controlDisplayName,
|
|
56
|
+
PCF_CONSTRUCTOR: constructorName,
|
|
57
|
+
PCF_NAMESPACE: namespace,
|
|
58
|
+
PCF_PACKAGE_NAME: packageNameToken,
|
|
59
|
+
PCF_VERSION: version,
|
|
60
|
+
PROJECT_APP_IMPORT: appImportPath,
|
|
61
|
+
PROJECT_CSS_IMPORT: cssImportPath,
|
|
62
|
+
PROJECT_NODE_MODULES_TYPES_ROOT: `${relToProject}/node_modules/@types`,
|
|
63
|
+
PROJECT_REACT_ALIAS: `${relToProject}/node_modules/react`,
|
|
64
|
+
PROJECT_REACT_DOM_ALIAS: `${relToProject}/node_modules/react-dom`,
|
|
65
|
+
PROJECT_ROOT_REL: relToProject,
|
|
66
|
+
PROJECT_RUNTIME_TYPES_IMPORT: runtimeTypesImportPath,
|
|
67
|
+
PROJECT_SRC_ALIAS: `${relToProject}/src`,
|
|
68
|
+
});
|
|
69
|
+
await renameIfExists(path.join(outputDir, "ControlHost.pcfproj"), path.join(outputDir, `${constructorName}.pcfproj`));
|
|
70
|
+
return {
|
|
71
|
+
constructorName,
|
|
72
|
+
namespace,
|
|
73
|
+
outputDir,
|
|
74
|
+
templateDir,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async function ensureRuntimeTypes(projectDir) {
|
|
78
|
+
const runtimeTypesPath = path.join(projectDir, "src", "runtime", "types.ts");
|
|
79
|
+
if (await fs.pathExists(runtimeTypesPath)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
await fs.ensureDir(path.dirname(runtimeTypesPath));
|
|
83
|
+
await fs.writeFile(runtimeTypesPath, RUNTIME_TYPES_TEMPLATE, "utf8");
|
|
84
|
+
}
|
|
85
|
+
async function readJson(filePath) {
|
|
86
|
+
try {
|
|
87
|
+
return await fs.readJson(filePath);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function renameIfExists(fromPath, toPath) {
|
|
94
|
+
if (!(await fs.pathExists(fromPath))) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
await fs.move(fromPath, toPath, { overwrite: true });
|
|
98
|
+
}
|
|
99
|
+
async function assertFileExists(filePath, message) {
|
|
100
|
+
if (!(await fs.pathExists(filePath))) {
|
|
101
|
+
throw new Error(message);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function toPascalCase(value) {
|
|
105
|
+
return value
|
|
106
|
+
.split(/[^a-z0-9]+/i)
|
|
107
|
+
.filter(Boolean)
|
|
108
|
+
.map((part) => part[0]?.toUpperCase() + part.slice(1).toLowerCase())
|
|
109
|
+
.join("");
|
|
110
|
+
}
|
|
111
|
+
function toKebabCase(value) {
|
|
112
|
+
return value
|
|
113
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1-$2")
|
|
114
|
+
.replace(/[^a-z0-9]+/gi, "-")
|
|
115
|
+
.replace(/^-+|-+$/g, "")
|
|
116
|
+
.toLowerCase();
|
|
117
|
+
}
|
|
118
|
+
function toDisplayName(value) {
|
|
119
|
+
return value.replace(/[._-]+/g, " ").replace(/\s+/g, " ").trim();
|
|
120
|
+
}
|
|
121
|
+
function toPosixPath(value) {
|
|
122
|
+
return value.split(path.sep).join("/");
|
|
123
|
+
}
|
|
124
|
+
function ensureRelativeImport(value) {
|
|
125
|
+
if (value.startsWith(".")) {
|
|
126
|
+
return value;
|
|
127
|
+
}
|
|
128
|
+
return `./${value}`;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=pcf.js.map
|
package/dist/pcf.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pcf.js","sourceRoot":"","sources":["../src/pcf.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
|
2
|
+
<PropertyGroup>
|
|
3
|
+
<TargetFramework>net462</TargetFramework>
|
|
4
|
+
<PowerAppsToolsVersion>1.38.3</PowerAppsToolsVersion>
|
|
5
|
+
<ControlManifestInputFile>control\ControlManifest.Input.xml</ControlManifestInputFile>
|
|
6
|
+
<OutputPath>$(MSBuildThisFileDirectory)out\controls\</OutputPath>
|
|
7
|
+
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
|
8
|
+
<RootNamespace>{{PCF_NAMESPACE}}.{{PCF_CONSTRUCTOR}}</RootNamespace>
|
|
9
|
+
<Name>{{PCF_CONSTRUCTOR}}</Name>
|
|
10
|
+
</PropertyGroup>
|
|
11
|
+
|
|
12
|
+
<ItemGroup>
|
|
13
|
+
<PackageReference Include="Microsoft.PowerApps.MSBuild.Pcf" Version="1.38.3" />
|
|
14
|
+
</ItemGroup>
|
|
15
|
+
</Project>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# {{CONTROL_DISPLAY_NAME}}
|
|
2
|
+
|
|
3
|
+
This folder was generated from the webresource source using the checked-in PCF base template.
|
|
4
|
+
|
|
5
|
+
## Build
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
npm run build
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Control Info
|
|
13
|
+
|
|
14
|
+
- Namespace: `{{PCF_NAMESPACE}}`
|
|
15
|
+
- Constructor: `{{PCF_CONSTRUCTOR}}`
|
|
16
|
+
- React app import: `{{PROJECT_APP_IMPORT}}`
|
|
17
|
+
- CSS import: `{{PROJECT_CSS_IMPORT}}`
|
|
18
|
+
|
|
19
|
+
## Notes
|
|
20
|
+
|
|
21
|
+
- The wrapper imports `src/App` directly and reuses the built `dist/main.css`.
|
|
22
|
+
- Regenerate this folder after rebuilding the webresource whenever the app changes.
|
|
23
|
+
- The project includes both `pcf-scripts` build support and a `.pcfproj` for Dataverse solution packaging flows.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
|
2
|
+
<manifest>
|
|
3
|
+
<control
|
|
4
|
+
namespace="{{PCF_NAMESPACE}}"
|
|
5
|
+
constructor="{{PCF_CONSTRUCTOR}}"
|
|
6
|
+
version="{{PCF_VERSION}}"
|
|
7
|
+
display-name-key="Control_Display_Name"
|
|
8
|
+
description-key="Control_Description"
|
|
9
|
+
control-type="standard">
|
|
10
|
+
<external-service-usage enabled="false" />
|
|
11
|
+
<property
|
|
12
|
+
name="hostField"
|
|
13
|
+
display-name-key="HostField_Display_Name"
|
|
14
|
+
description-key="HostField_Description"
|
|
15
|
+
of-type="SingleLine.Text"
|
|
16
|
+
usage="bound"
|
|
17
|
+
required="false" />
|
|
18
|
+
<feature-usage>
|
|
19
|
+
<uses-feature name="WebAPI" required="true" />
|
|
20
|
+
</feature-usage>
|
|
21
|
+
<resources>
|
|
22
|
+
<code path="../index.ts" order="1" />
|
|
23
|
+
<resx path="../strings/control.1033.resx" version="1.0.0" />
|
|
24
|
+
</resources>
|
|
25
|
+
</control>
|
|
26
|
+
</manifest>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module "*.css";
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import React, { StrictMode } from "react";
|
|
2
|
+
import { createRoot, type Root } from "react-dom/client";
|
|
3
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
4
|
+
|
|
5
|
+
import App from "{{PROJECT_APP_IMPORT}}";
|
|
6
|
+
import "{{PROJECT_CSS_IMPORT}}";
|
|
7
|
+
import type { IInputs, IOutputs } from "./control/generated/ManifestTypes";
|
|
8
|
+
import type {
|
|
9
|
+
PcfRuntimeContext,
|
|
10
|
+
PcfWebApi,
|
|
11
|
+
} from "{{PROJECT_RUNTIME_TYPES_IMPORT}}";
|
|
12
|
+
|
|
13
|
+
function sanitizeGuid(value: string | null | undefined): string | null {
|
|
14
|
+
if (!value) return null;
|
|
15
|
+
return value.replace(/[{}]/g, "");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function getContextInfo(context: ComponentFramework.Context<IInputs>) {
|
|
19
|
+
const pageContext = (
|
|
20
|
+
context as ComponentFramework.Context<IInputs> & {
|
|
21
|
+
page?: {
|
|
22
|
+
entityId?: string;
|
|
23
|
+
entityTypeName?: string;
|
|
24
|
+
getClientUrl?: () => string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
).page;
|
|
28
|
+
|
|
29
|
+
const modeContextInfo = (
|
|
30
|
+
context.mode as ComponentFramework.Mode & {
|
|
31
|
+
contextInfo?: { entityId?: string; entityTypeName?: string };
|
|
32
|
+
}
|
|
33
|
+
).contextInfo;
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
recordId: sanitizeGuid(
|
|
37
|
+
modeContextInfo?.entityId ?? pageContext?.entityId ?? null,
|
|
38
|
+
),
|
|
39
|
+
entityName:
|
|
40
|
+
modeContextInfo?.entityTypeName ?? pageContext?.entityTypeName ?? null,
|
|
41
|
+
clientUrl: pageContext?.getClientUrl?.() ?? null,
|
|
42
|
+
userId: sanitizeGuid(context.userSettings.userId),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function createPcfWebApi(
|
|
47
|
+
context: ComponentFramework.Context<IInputs>,
|
|
48
|
+
): PcfWebApi {
|
|
49
|
+
return {
|
|
50
|
+
async retrieve<T>(entitySet: string, id: string, query = ""): Promise<T> {
|
|
51
|
+
return (await context.webAPI.retrieveRecord(
|
|
52
|
+
entitySet,
|
|
53
|
+
id,
|
|
54
|
+
query,
|
|
55
|
+
)) as T;
|
|
56
|
+
},
|
|
57
|
+
async retrieveMultiple<T>(entitySet: string, query = ""): Promise<T[]> {
|
|
58
|
+
const response = await context.webAPI.retrieveMultipleRecords(
|
|
59
|
+
entitySet,
|
|
60
|
+
query,
|
|
61
|
+
);
|
|
62
|
+
return response.entities as T[];
|
|
63
|
+
},
|
|
64
|
+
async create<T>(entitySet: string, data: unknown): Promise<T> {
|
|
65
|
+
return (await context.webAPI.createRecord(
|
|
66
|
+
entitySet,
|
|
67
|
+
data as ComponentFramework.WebApi.Entity,
|
|
68
|
+
)) as T;
|
|
69
|
+
},
|
|
70
|
+
async update(entitySet: string, id: string, data: unknown): Promise<void> {
|
|
71
|
+
await context.webAPI.updateRecord(
|
|
72
|
+
entitySet,
|
|
73
|
+
id,
|
|
74
|
+
data as ComponentFramework.WebApi.Entity,
|
|
75
|
+
);
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function createRuntime(
|
|
81
|
+
context: ComponentFramework.Context<IInputs>,
|
|
82
|
+
): PcfRuntimeContext {
|
|
83
|
+
return {
|
|
84
|
+
host: "pcf",
|
|
85
|
+
...getContextInfo(context),
|
|
86
|
+
webApi: createPcfWebApi(context),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export class {{PCF_CONSTRUCTOR}}
|
|
91
|
+
implements ComponentFramework.StandardControl<IInputs, IOutputs>
|
|
92
|
+
{
|
|
93
|
+
private root: Root | null = null;
|
|
94
|
+
private runtime!: PcfRuntimeContext;
|
|
95
|
+
private readonly queryClient = new QueryClient({
|
|
96
|
+
defaultOptions: {
|
|
97
|
+
queries: {
|
|
98
|
+
refetchOnWindowFocus: false,
|
|
99
|
+
retry: 3,
|
|
100
|
+
staleTime: 5 * 60 * 1000,
|
|
101
|
+
},
|
|
102
|
+
mutations: {
|
|
103
|
+
retry: 1,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
public init(
|
|
109
|
+
context: ComponentFramework.Context<IInputs>,
|
|
110
|
+
_notifyOutputChanged: () => void,
|
|
111
|
+
_state: ComponentFramework.Dictionary,
|
|
112
|
+
container: HTMLDivElement,
|
|
113
|
+
): void {
|
|
114
|
+
container.classList.add("ec-pcf-shell-control");
|
|
115
|
+
this.runtime = createRuntime(context);
|
|
116
|
+
this.root = createRoot(container);
|
|
117
|
+
this.render();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public updateView(context: ComponentFramework.Context<IInputs>): void {
|
|
121
|
+
this.runtime = {
|
|
122
|
+
...this.runtime,
|
|
123
|
+
...getContextInfo(context),
|
|
124
|
+
};
|
|
125
|
+
this.render();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public getOutputs(): IOutputs {
|
|
129
|
+
return {
|
|
130
|
+
hostField: this.runtime.recordId ?? undefined,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public destroy(): void {
|
|
135
|
+
this.root?.unmount();
|
|
136
|
+
this.root = null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private render(): void {
|
|
140
|
+
this.root?.render(
|
|
141
|
+
React.createElement(
|
|
142
|
+
StrictMode,
|
|
143
|
+
null,
|
|
144
|
+
React.createElement(
|
|
145
|
+
QueryClientProvider,
|
|
146
|
+
{ client: this.queryClient },
|
|
147
|
+
React.createElement(App, { runtime: this.runtime }),
|
|
148
|
+
),
|
|
149
|
+
),
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PCF_PACKAGE_NAME}}",
|
|
3
|
+
"version": "{{PCF_VERSION}}",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "{{CONTROL_DESCRIPTION}}",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "pcf-scripts build",
|
|
8
|
+
"clean": "pcf-scripts clean",
|
|
9
|
+
"lint": "pcf-scripts lint",
|
|
10
|
+
"rebuild": "npm run clean && npm run build",
|
|
11
|
+
"start": "pcf-scripts start",
|
|
12
|
+
"push": "pcf-scripts push"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@types/powerapps-component-framework": "^1.3.14",
|
|
16
|
+
"pcf-start": "^1.48.2",
|
|
17
|
+
"pcf-scripts": "^1.48.2",
|
|
18
|
+
"typescript": "^5.9.3"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<root>
|
|
3
|
+
<resheader name="resmimetype">
|
|
4
|
+
<value>text/microsoft-resx</value>
|
|
5
|
+
</resheader>
|
|
6
|
+
<resheader name="version">
|
|
7
|
+
<value>2.0</value>
|
|
8
|
+
</resheader>
|
|
9
|
+
<resheader name="reader">
|
|
10
|
+
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
11
|
+
</resheader>
|
|
12
|
+
<resheader name="writer">
|
|
13
|
+
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
14
|
+
</resheader>
|
|
15
|
+
<data name="Control_Display_Name" xml:space="preserve">
|
|
16
|
+
<value>{{CONTROL_DISPLAY_NAME}}</value>
|
|
17
|
+
</data>
|
|
18
|
+
<data name="Control_Description" xml:space="preserve">
|
|
19
|
+
<value>{{CONTROL_DESCRIPTION}}</value>
|
|
20
|
+
</data>
|
|
21
|
+
<data name="HostField_Display_Name" xml:space="preserve">
|
|
22
|
+
<value>Host field</value>
|
|
23
|
+
</data>
|
|
24
|
+
<data name="HostField_Description" xml:space="preserve">
|
|
25
|
+
<value>Optional bound field used to surface the current record id.</value>
|
|
26
|
+
</data>
|
|
27
|
+
</root>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
6
|
+
"jsx": "react-jsx",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"types": ["react", "react-dom", "powerapps-component-framework"],
|
|
11
|
+
"typeRoots": ["./node_modules/@types", "{{PROJECT_NODE_MODULES_TYPES_ROOT}}"],
|
|
12
|
+
"baseUrl": "{{PROJECT_ROOT_REL}}",
|
|
13
|
+
"paths": {
|
|
14
|
+
"@/*": ["src/*"],
|
|
15
|
+
"react": ["node_modules/@types/react"],
|
|
16
|
+
"react/jsx-runtime": ["node_modules/@types/react/jsx-runtime"],
|
|
17
|
+
"react-dom": ["node_modules/@types/react-dom"],
|
|
18
|
+
"react-dom/client": ["node_modules/@types/react-dom/client"]
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"include": [
|
|
22
|
+
"./**/*.ts",
|
|
23
|
+
"./**/*.tsx",
|
|
24
|
+
"{{PROJECT_ROOT_REL}}/src/**/*.ts",
|
|
25
|
+
"{{PROJECT_ROOT_REL}}/src/**/*.tsx"
|
|
26
|
+
],
|
|
27
|
+
"exclude": [
|
|
28
|
+
"{{PROJECT_ROOT_REL}}/src/main.tsx",
|
|
29
|
+
"{{PROJECT_ROOT_REL}}/src/services/AuthService.ts"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
resolve: {
|
|
5
|
+
alias: {
|
|
6
|
+
"@": path.resolve(__dirname, "{{PROJECT_SRC_ALIAS}}"),
|
|
7
|
+
react: path.resolve(__dirname, "{{PROJECT_REACT_ALIAS}}"),
|
|
8
|
+
"react-dom": path.resolve(__dirname, "{{PROJECT_REACT_DOM_ALIAS}}"),
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
## Purpose
|
|
2
|
+
|
|
3
|
+
This is a Dynamics 365 / Dataverse web resource template using React + TypeScript + Vite.
|
|
4
|
+
Treat it as a **Dynamics-hosted frontend** — not a generic SPA. Do not modernise it into something else unless explicitly asked.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Hard Constraints
|
|
9
|
+
|
|
10
|
+
1. **Dynamics runtime must keep working** — preserve `window.parent.Xrm`/`window.top.Xrm` detection and `ClientGlobalContext.js.aspx` where present.
|
|
11
|
+
2. **Local dev must keep working** — `token.json` drives local auth; never bundle it into output or commit real values.
|
|
12
|
+
3. **Build output must stay web-resource-friendly** — predictable filenames, no uncontrolled chunking, deployable via Webresource Manager or pipeline upload.
|
|
13
|
+
4. **Keep it client-side** — no SSR, no Next.js, no backend coupling unless explicitly requested.
|
|
14
|
+
5. **Make surgical changes** — extend existing patterns before inventing new ones; don't refactor unrelated areas.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Runtime Modes
|
|
19
|
+
|
|
20
|
+
**Dynamics-hosted:** detect via `window.parent.Xrm`, derive base URL from `getGlobalContext().getClientUrl()`, no bearer token needed.
|
|
21
|
+
|
|
22
|
+
**Local dev:** load `token.json` dynamically, use bearer token, call Dataverse directly.
|
|
23
|
+
|
|
24
|
+
Never mix the two modes or duplicate their logic — reuse `authService.ts`.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Critical Files — Don't Break These
|
|
29
|
+
|
|
30
|
+
| File | Why it matters |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `src/services/authService.ts` | Single source of truth for env detection, base URL, and auth headers |
|
|
33
|
+
| `src/main.tsx` | App bootstrap — preserve providers and theme imports |
|
|
34
|
+
| `vite.config.ts` | Controls deployment shape: `base: "./"`, predictable output names, `main.css` |
|
|
35
|
+
| `index.html` | Dynamics integration boundary — may inject `ClientGlobalContext.js.aspx` |
|
|
36
|
+
| `token.json` | Local dev only — never commit real values, never bundle |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## API / Data Access
|
|
41
|
+
|
|
42
|
+
- Put reusable API logic in `src/services`
|
|
43
|
+
- Always reuse `getApiUrl()` and `getAuthHeaders()` — never duplicate them
|
|
44
|
+
- Use narrow `$select` queries; throw on non-OK responses
|
|
45
|
+
- No raw fetch calls scattered across UI components
|
|
46
|
+
|
|
47
|
+
**Preferred pattern:**
|
|
48
|
+
```ts
|
|
49
|
+
// service.ts — fetch function + TanStack Query hook
|
|
50
|
+
// invalidate relevant queryKey on mutation success
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
See the example at the bottom of this file.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## State Management
|
|
58
|
+
|
|
59
|
+
- **TanStack Query** → server state
|
|
60
|
+
- **Zustand** → shared client state
|
|
61
|
+
- **Local component state** → local UI behaviour
|
|
62
|
+
- No Redux unless explicitly requested; don't store server state in Zustand
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## UI & Styling
|
|
67
|
+
|
|
68
|
+
- Kendo UI or Shadcn/ui — stay consistent with whichever the project uses; don't mix
|
|
69
|
+
- Tailwind is the default styling approach; preserve `main.css` output
|
|
70
|
+
- Reuse existing components and utilities before building new ones
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Planning Rule
|
|
75
|
+
|
|
76
|
+
For changes touching multiple files, auth, build config, or new service patterns — write a short plan first:
|
|
77
|
+
- current state
|
|
78
|
+
- intended change
|
|
79
|
+
- files to touch
|
|
80
|
+
- risks / compatibility concerns
|
|
81
|
+
|
|
82
|
+
For large or risky changes, write an `ExecPlan` in `PLANS.md` before implementing.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## What To Avoid
|
|
87
|
+
|
|
88
|
+
Unless explicitly asked: don't replace Vite, don't add SSR, don't remove Dynamics runtime logic, don't remove the local token flow, don't hardcode org-specific values, don't rename output files in ways that complicate deployment.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Example Service Pattern
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { getApiUrl, getAuthHeaders } from "@/services/authService";
|
|
96
|
+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
97
|
+
|
|
98
|
+
export interface Account {
|
|
99
|
+
accountid: string;
|
|
100
|
+
name?: string | null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const listAccounts = async (): Promise<Account[]> => {
|
|
104
|
+
const res = await fetch(
|
|
105
|
+
`${getApiUrl()}/accounts?$select=accountid,name&$top=50`,
|
|
106
|
+
{ headers: await getAuthHeaders() },
|
|
107
|
+
);
|
|
108
|
+
if (!res.ok) throw new Error(`Failed to fetch accounts: ${res.status}`);
|
|
109
|
+
return (await res.json()).value as Account[];
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const useAccounts = () =>
|
|
113
|
+
useQuery({ queryKey: ["accounts"], queryFn: listAccounts });
|
|
114
|
+
|
|
115
|
+
export const useUpdateAccount = () => {
|
|
116
|
+
const queryClient = useQueryClient();
|
|
117
|
+
return useMutation({
|
|
118
|
+
mutationFn: ({ id, data }: { id: string; data: Partial<Account> }) =>
|
|
119
|
+
patchAccount(id, data),
|
|
120
|
+
onSuccess: () => queryClient.invalidateQueries({ queryKey: ["accounts"] }),
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[AGENTS.md](AGENTS.md)
|
|
@@ -258,6 +258,76 @@ export function AccountsList() {
|
|
|
258
258
|
- Upload your index.html, index.js and main.css to your folder.
|
|
259
259
|
- This will now allow you to use auto publisher to bind to your deployed resources.
|
|
260
260
|
|
|
261
|
+
## Generate a PCF Wrapper
|
|
262
|
+
|
|
263
|
+
If you want to host the React webresource inside a PCF control instead of loading the HTML webresource directly in an iframe, use `create-ec-app` itself to generate the wrapper for an existing webresource project.
|
|
264
|
+
|
|
265
|
+
Basic flow:
|
|
266
|
+
|
|
267
|
+
1. Build the webresource:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
npm run build
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
2. Run the generator against the current project directory:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
npx create-ec-app --pcf-dir . --namespace EC --constructor FusionNotebookHost
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
If you are not inside the webresource folder, point `--pcf-dir` at that folder explicitly:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
npx create-ec-app --pcf-dir /path/to/my-webresource --namespace EC --constructor FusionNotebookHost
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
This writes a standalone PCF project to `pcf/FusionNotebookHost` by default. The generated control:
|
|
286
|
+
|
|
287
|
+
- imports `src/App.tsx` directly instead of wrapping built HTML in an iframe
|
|
288
|
+
- reuses the built stylesheet from `dist/main.css`
|
|
289
|
+
- creates `src/runtime/types.ts` only if that file does not already exist
|
|
290
|
+
- provides a runtime object with record context and `context.webAPI` access inside the generated PCF shell, following the `PcfBase` pattern
|
|
291
|
+
- mounts your React app directly into the PCF container
|
|
292
|
+
|
|
293
|
+
Typical conversion flow from inside a generated webresource project:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
npm install
|
|
297
|
+
npm run build
|
|
298
|
+
npx create-ec-app --pcf-dir . --namespace EC --constructor FusionNotebookHost --display-name "Fusion Notebook Host"
|
|
299
|
+
cd pcf/FusionNotebookHost
|
|
300
|
+
npm install
|
|
301
|
+
npm run build
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Useful options:
|
|
305
|
+
|
|
306
|
+
- `--dist dist` to point at a different build folder
|
|
307
|
+
- `--output pcf/MyControl` to choose the target folder
|
|
308
|
+
- `--template /path/to/create-ec-app/templates/pcf/base` to swap the base shell
|
|
309
|
+
- `--layer path/to/layer` to apply one or more patch layers after the base copy
|
|
310
|
+
|
|
311
|
+
Build the generated PCF project from inside the generated folder:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
cd pcf/FusionNotebookHost
|
|
315
|
+
npm install
|
|
316
|
+
npm run build
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
What gets generated:
|
|
320
|
+
|
|
321
|
+
- a minimal PCF wrapper project under `pcf/<ConstructorName>`
|
|
322
|
+
- a checked-in PCF shell stamped out from `create-ec-app/templates/pcf/base`
|
|
323
|
+
- direct imports back to your webresource source and built CSS
|
|
324
|
+
|
|
325
|
+
What does not happen:
|
|
326
|
+
|
|
327
|
+
- your existing webresource project is not converted in place
|
|
328
|
+
- your React source is not moved into the PCF project
|
|
329
|
+
- the generated PCF project does not automatically get added to a Dataverse solution
|
|
330
|
+
|
|
261
331
|
## Notes
|
|
262
332
|
|
|
263
333
|
- If you change the build, ensure code splitting stays disabled and asset names remain predictable to simplify web resource updates.
|