create-powerapps-project 2.2.4 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/plopActions.js +1 -1
- package/lib/plopfile.js +40 -103
- package/package.json +3 -6
- package/plop-templates/pcf/App.tsx +2 -6
- package/plop-templates/pcf/AppContext.tsx +1 -1
- package/plop-templates/pcf/.eslintrc.json +0 -34
- package/plop-templates/pcf/.gitattributes +0 -3
- package/plop-templates/pcf/AppFluent9.tsx.hbs +0 -21
- package/plop-templates/pcf/index.ts.hbs +0 -58
- package/plop-templates/pcf/tsconfig.json +0 -10
package/lib/plopActions.js
CHANGED
|
@@ -58,7 +58,7 @@ export default (plop) => {
|
|
|
58
58
|
plop.setActionType('runPcf', async (answers) => {
|
|
59
59
|
const args = ['pcf', 'init', '-ns', answers.namespace, '-n', answers.name, '-t', answers.template, '-npm', 'false'];
|
|
60
60
|
// Set framework to React if selected
|
|
61
|
-
if (answers.react
|
|
61
|
+
if (answers.react) {
|
|
62
62
|
args.push('-fw', 'react');
|
|
63
63
|
}
|
|
64
64
|
console.log('running pac pcf command with args');
|
package/lib/plopfile.js
CHANGED
|
@@ -284,16 +284,6 @@ export default async (plop) => {
|
|
|
284
284
|
name: 'react',
|
|
285
285
|
message: 'use react?'
|
|
286
286
|
},
|
|
287
|
-
{
|
|
288
|
-
type: 'list',
|
|
289
|
-
name: 'fluentVersion',
|
|
290
|
-
message: 'select Fluent UI version',
|
|
291
|
-
choices: [
|
|
292
|
-
{ name: 'v8', value: 8 },
|
|
293
|
-
{ name: 'v9', value: 9 }
|
|
294
|
-
],
|
|
295
|
-
when: (answers) => answers.react
|
|
296
|
-
},
|
|
297
287
|
packageQuestion
|
|
298
288
|
],
|
|
299
289
|
actions: (data) => {
|
|
@@ -302,30 +292,12 @@ export default async (plop) => {
|
|
|
302
292
|
{
|
|
303
293
|
type: 'runPcf'
|
|
304
294
|
},
|
|
305
|
-
{
|
|
306
|
-
type: 'add',
|
|
307
|
-
templateFile: '../plop-templates/pcf/tsconfig.json',
|
|
308
|
-
path: path.resolve(process.cwd(), 'tsconfig.json'),
|
|
309
|
-
force: true
|
|
310
|
-
},
|
|
311
295
|
{
|
|
312
296
|
type: 'add',
|
|
313
297
|
templateFile: '../plop-templates/pcf/plopfile.js',
|
|
314
298
|
path: path.resolve(process.cwd(), 'plopfile.js'),
|
|
315
299
|
force: true
|
|
316
300
|
},
|
|
317
|
-
{
|
|
318
|
-
type: 'add',
|
|
319
|
-
templateFile: '../plop-templates/pcf/.eslintrc.json',
|
|
320
|
-
path: path.resolve(process.cwd(), '.eslintrc.json'),
|
|
321
|
-
force: true
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
type: 'add',
|
|
325
|
-
templateFile: '../plop-templates/pcf/.gitattributes',
|
|
326
|
-
path: path.resolve(process.cwd(), '.gitattributes'),
|
|
327
|
-
force: true
|
|
328
|
-
},
|
|
329
301
|
{
|
|
330
302
|
type: 'add',
|
|
331
303
|
templateFile: '../plop-templates/pcf/App.tsx',
|
|
@@ -334,23 +306,6 @@ export default async (plop) => {
|
|
|
334
306
|
if (!answers.react) {
|
|
335
307
|
return 'react not included';
|
|
336
308
|
}
|
|
337
|
-
if (answers.fluentVersion === 9) {
|
|
338
|
-
return 'using fluent v9';
|
|
339
|
-
}
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
},
|
|
343
|
-
{
|
|
344
|
-
type: 'add',
|
|
345
|
-
templateFile: '../plop-templates/pcf/AppFluent9.tsx.hbs',
|
|
346
|
-
path: path.resolve(process.cwd(), '{{name}}', 'App.tsx'),
|
|
347
|
-
skip: (answers) => {
|
|
348
|
-
if (!answers.react) {
|
|
349
|
-
return 'react not included';
|
|
350
|
-
}
|
|
351
|
-
if (answers.fluentVersion === 8) {
|
|
352
|
-
return 'using fluent v8';
|
|
353
|
-
}
|
|
354
309
|
return;
|
|
355
310
|
}
|
|
356
311
|
},
|
|
@@ -365,24 +320,40 @@ export default async (plop) => {
|
|
|
365
320
|
return;
|
|
366
321
|
}
|
|
367
322
|
},
|
|
368
|
-
{
|
|
369
|
-
type: 'add',
|
|
370
|
-
templateFile: '../plop-templates/pcf/index.ts.hbs',
|
|
371
|
-
path: path.resolve(process.cwd(), '{{name}}', 'index.ts'),
|
|
372
|
-
force: true,
|
|
373
|
-
skip: (answers) => {
|
|
374
|
-
if (!answers.react || answers.fluentVersion === 8) {
|
|
375
|
-
return 'not using Fluent UI v9';
|
|
376
|
-
}
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
},
|
|
380
323
|
{
|
|
381
324
|
type: 'modify',
|
|
382
325
|
path: `${process.cwd()}/{{name}}/index.ts`,
|
|
383
326
|
pattern: 'import { HelloWorld, IHelloWorldProps } from "./HelloWorld";',
|
|
384
327
|
template: `import { App } from './App';`
|
|
385
328
|
},
|
|
329
|
+
{
|
|
330
|
+
type: 'append',
|
|
331
|
+
path: `${process.cwd()}/${path.basename(process.cwd())}.pcfproj`,
|
|
332
|
+
pattern: '</PowerAppsTargetsPath>',
|
|
333
|
+
template: `\t\t<PcfEnableAutoNpmInstall Condition=" '$(PcfEnableAutoNpmInstall)' == '' ">false</PcfEnableAutoNpmInstall>\r\n\t\t<PcfAlwaysNpmInstall Condition=" '$(PcfAlwaysNpmInstall)' == '' ">false</PcfAlwaysNpmInstall>`,
|
|
334
|
+
separator: '\n'
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
type: 'append',
|
|
338
|
+
path: `${process.cwd()}/eslint.config.mjs`,
|
|
339
|
+
pattern: 'reactPlugin.configs.flat.recommended,',
|
|
340
|
+
template: '\treactHooks.configs.flat.recommended,',
|
|
341
|
+
separator: '\n'
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
type: 'append',
|
|
345
|
+
path: `${process.cwd()}/eslint.config.mjs`,
|
|
346
|
+
pattern: `import reactPlugin from "eslint-plugin-react";`,
|
|
347
|
+
template: `import reactHooksPlugin from 'eslint-plugin-react-hooks';`,
|
|
348
|
+
separator: '\n'
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
type: 'append',
|
|
352
|
+
path: `${process.cwd()}/${path.basename(process.cwd())}.pcfproj`,
|
|
353
|
+
pattern: '</OutputPath>',
|
|
354
|
+
template: `\t\t<PcfBuildMode>development</PcfBuildMode>`,
|
|
355
|
+
separator: '\n'
|
|
356
|
+
},
|
|
386
357
|
{
|
|
387
358
|
type: 'modify',
|
|
388
359
|
path: `${process.cwd()}/{{name}}/index.ts`,
|
|
@@ -392,9 +363,16 @@ export default async (plop) => {
|
|
|
392
363
|
{
|
|
393
364
|
type: 'modify',
|
|
394
365
|
path: `${process.cwd()}/{{name}}/index.ts`,
|
|
395
|
-
pattern: `const props: IHelloWorldProps = { name: '
|
|
366
|
+
pattern: `const props: IHelloWorldProps = { name: 'Power Apps' };`,
|
|
396
367
|
template: ''
|
|
397
368
|
},
|
|
369
|
+
async (answers) => {
|
|
370
|
+
if (answers.react) {
|
|
371
|
+
await fs.promises.rm(path.resolve(process.cwd(), answers.name, 'HelloWorld.tsx'));
|
|
372
|
+
return 'removed default HelloWorld component';
|
|
373
|
+
}
|
|
374
|
+
return 'react not included';
|
|
375
|
+
},
|
|
398
376
|
{
|
|
399
377
|
type: 'addScript',
|
|
400
378
|
data: {
|
|
@@ -413,14 +391,14 @@ export default async (plop) => {
|
|
|
413
391
|
type: 'addScript',
|
|
414
392
|
data: {
|
|
415
393
|
scriptKey: 'push',
|
|
416
|
-
scriptValue:
|
|
394
|
+
scriptValue: `${data.package} run select-auth && pac pcf push -pp ${data.prefix} -env ${data.server}`
|
|
417
395
|
}
|
|
418
396
|
},
|
|
419
397
|
{
|
|
420
398
|
type: 'addScript',
|
|
421
399
|
data: {
|
|
422
400
|
scriptKey: 'push-inc',
|
|
423
|
-
scriptValue:
|
|
401
|
+
scriptValue: `${data.package} run build && ${data.package} run select-auth && pac pcf push -pp ${data.prefix} -inc -env ${data.server}`
|
|
424
402
|
}
|
|
425
403
|
},
|
|
426
404
|
{
|
|
@@ -430,13 +408,6 @@ export default async (plop) => {
|
|
|
430
408
|
scriptValue: `npx only-allow ${data.package}`
|
|
431
409
|
}
|
|
432
410
|
},
|
|
433
|
-
async (answers) => {
|
|
434
|
-
if (answers.react && answers.fluentVersion === 8) {
|
|
435
|
-
await fs.promises.rm(path.resolve(process.cwd(), answers.name, 'HelloWorld.tsx'));
|
|
436
|
-
return 'removed HelloWorld component';
|
|
437
|
-
}
|
|
438
|
-
return 'react not included';
|
|
439
|
-
},
|
|
440
411
|
{
|
|
441
412
|
type: 'npmInstall'
|
|
442
413
|
},
|
|
@@ -444,48 +415,14 @@ export default async (plop) => {
|
|
|
444
415
|
type: 'npmInstall',
|
|
445
416
|
data: {
|
|
446
417
|
packages: {
|
|
447
|
-
devDependencies: [
|
|
448
|
-
|
|
449
|
-
'@types/react@^16',
|
|
450
|
-
'@types/react-dom@^16',
|
|
451
|
-
'eslint-plugin-react-hooks',
|
|
452
|
-
'@types/xrm'
|
|
453
|
-
],
|
|
454
|
-
dependencies: ['@fluentui/react-hooks']
|
|
418
|
+
devDependencies: ['powerapps-project-pcf', 'eslint-plugin-react-hooks', '@types/xrm'],
|
|
419
|
+
dependencies: ['@fluentui/react-icons']
|
|
455
420
|
}
|
|
456
421
|
},
|
|
457
422
|
skip: (answers) => {
|
|
458
423
|
if (!answers.react) {
|
|
459
424
|
return 'react not included';
|
|
460
425
|
}
|
|
461
|
-
if (answers.fluentVersion === 9) {
|
|
462
|
-
return 'using fluent v9';
|
|
463
|
-
}
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
466
|
-
},
|
|
467
|
-
{
|
|
468
|
-
type: 'npmInstall',
|
|
469
|
-
data: {
|
|
470
|
-
packages: {
|
|
471
|
-
devDependencies: [
|
|
472
|
-
'powerapps-project-pcf',
|
|
473
|
-
'@types/react@^17',
|
|
474
|
-
'@types/react-dom@^17',
|
|
475
|
-
'eslint-plugin-react-hooks',
|
|
476
|
-
'@types/xrm',
|
|
477
|
-
'eslint-plugin-react'
|
|
478
|
-
],
|
|
479
|
-
dependencies: ['@fluentui/react-hooks', '@fluentui/react-components', '@fluentui/react-icons', 'react@^17', 'react-dom@^17']
|
|
480
|
-
}
|
|
481
|
-
},
|
|
482
|
-
skip: (answers) => {
|
|
483
|
-
if (!answers.react) {
|
|
484
|
-
return 'react not included';
|
|
485
|
-
}
|
|
486
|
-
if (answers.fluentVersion === 8) {
|
|
487
|
-
return 'using fluent v8';
|
|
488
|
-
}
|
|
489
426
|
return;
|
|
490
427
|
}
|
|
491
428
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-powerapps-project",
|
|
3
3
|
"description": "💧 plop generator for Dataverse development",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.3.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"exports": "./lib/index.js",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=
|
|
8
|
+
"node": ">=22.0.0"
|
|
9
9
|
},
|
|
10
10
|
"bin": {
|
|
11
11
|
"create-powerapps-project": "lib/index.js"
|
|
@@ -26,9 +26,6 @@
|
|
|
26
26
|
},
|
|
27
27
|
"type": "module",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"plop": "^
|
|
30
|
-
},
|
|
31
|
-
"volta": {
|
|
32
|
-
"extends": "../../package.json"
|
|
29
|
+
"plop": "^4.0.4"
|
|
33
30
|
}
|
|
34
31
|
}
|
|
@@ -2,13 +2,9 @@ import React from 'react';
|
|
|
2
2
|
import { IInputs } from './generated/ManifestTypes';
|
|
3
3
|
import { AppContext } from './contexts/AppContext';
|
|
4
4
|
|
|
5
|
-
export const App = (
|
|
6
|
-
const {
|
|
7
|
-
context
|
|
8
|
-
} = props;
|
|
9
|
-
|
|
5
|
+
export const App = ({ context }: { context: ComponentFramework.Context<IInputs>; }) => {
|
|
10
6
|
return (
|
|
11
|
-
<AppContext.Provider value
|
|
7
|
+
<AppContext.Provider value=\{{ context }}>
|
|
12
8
|
</AppContext.Provider>
|
|
13
9
|
);
|
|
14
10
|
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"browser": true,
|
|
4
|
-
"es2021": true
|
|
5
|
-
},
|
|
6
|
-
"extends": [
|
|
7
|
-
"eslint:recommended",
|
|
8
|
-
"plugin:@typescript-eslint/recommended",
|
|
9
|
-
"plugin:react/recommended",
|
|
10
|
-
"plugin:react-hooks/recommended"
|
|
11
|
-
],
|
|
12
|
-
"globals": {
|
|
13
|
-
"ComponentFramework": true,
|
|
14
|
-
"Xrm": true
|
|
15
|
-
},
|
|
16
|
-
"parser": "@typescript-eslint/parser",
|
|
17
|
-
"parserOptions": {
|
|
18
|
-
"ecmaVersion": 12,
|
|
19
|
-
"sourceType": "module"
|
|
20
|
-
},
|
|
21
|
-
"plugins": [
|
|
22
|
-
"@microsoft/power-apps",
|
|
23
|
-
"@typescript-eslint"
|
|
24
|
-
],
|
|
25
|
-
"rules": {
|
|
26
|
-
"no-unused-vars": "off",
|
|
27
|
-
"@typescript-eslint/no-empty-interface": "off"
|
|
28
|
-
},
|
|
29
|
-
"settings": {
|
|
30
|
-
"react": {
|
|
31
|
-
"version": "detect"
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { IInputs } from './generated/ManifestTypes';
|
|
3
|
-
import { AppContext } from './contexts/AppContext';
|
|
4
|
-
import { FluentProvider, IdPrefixProvider, webLightTheme } from '@fluentui/react-components';
|
|
5
|
-
|
|
6
|
-
export const App = (props: { context: ComponentFramework.Context<IInputs>; }) => {
|
|
7
|
-
const {
|
|
8
|
-
context
|
|
9
|
-
} = props;
|
|
10
|
-
|
|
11
|
-
return (
|
|
12
|
-
<IdPrefixProvider value="{{name}}">
|
|
13
|
-
<FluentProvider theme={webLightTheme}>
|
|
14
|
-
<AppContext.Provider value=\{{ context }}>
|
|
15
|
-
</AppContext.Provider>
|
|
16
|
-
</FluentProvider>
|
|
17
|
-
</IdPrefixProvider>
|
|
18
|
-
);
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
App.displayName = 'App';
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { IInputs, IOutputs } from './generated/ManifestTypes';
|
|
2
|
-
import { App } from './App';
|
|
3
|
-
import ReactDOM from 'react-dom';
|
|
4
|
-
import React from 'react';
|
|
5
|
-
|
|
6
|
-
export class {{name}} implements ComponentFramework.StandardControl<IInputs, IOutputs> {
|
|
7
|
-
container: HTMLDivElement;
|
|
8
|
-
context: ComponentFramework.Context<IInputs>;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Used to initialize the control instance. Controls can kick off remote server calls and other initialization actions here.
|
|
12
|
-
* Data-set values are not initialized here, use updateView.
|
|
13
|
-
* @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to property names defined in the manifest, as well as utility functions.
|
|
14
|
-
* @param notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously.
|
|
15
|
-
* @param state A piece of data that persists in one session for a single user. Can be set at any point in a controls life cycle by calling 'setControlState' in the Mode interface.
|
|
16
|
-
* @param container If a control is marked control-type='standard', it will receive an empty div element within which it can render its content.
|
|
17
|
-
*/
|
|
18
|
-
public init(
|
|
19
|
-
context: ComponentFramework.Context<IInputs>,
|
|
20
|
-
notifyOutputChanged: () => void,
|
|
21
|
-
state: ComponentFramework.Dictionary,
|
|
22
|
-
container: HTMLDivElement
|
|
23
|
-
): void {
|
|
24
|
-
this.context = context;
|
|
25
|
-
this.container = container;
|
|
26
|
-
this.context.mode.trackContainerResize(true);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Called when any value in the property bag has changed. This includes field values, data-sets, global values such as container height and width, offline status, control metadata values such as label, visible, etc.
|
|
31
|
-
* @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to names defined in the manifest, as well as utility functions
|
|
32
|
-
*/
|
|
33
|
-
public updateView(context: ComponentFramework.Context<IInputs>): void {
|
|
34
|
-
ReactDOM.render(
|
|
35
|
-
React.createElement(App, {
|
|
36
|
-
context: context
|
|
37
|
-
}),
|
|
38
|
-
this.container
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* It is called by the framework prior to a control receiving new data.
|
|
44
|
-
* @returns an object based on nomenclature defined in manifest, expecting object[s] for property marked as “bound” or “output”
|
|
45
|
-
*/
|
|
46
|
-
public getOutputs(): IOutputs {
|
|
47
|
-
return {
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Called when the control is to be removed from the DOM tree. Controls should use this call for cleanup.
|
|
53
|
-
* i.e. cancelling any pending remote calls, removing listeners, etc.
|
|
54
|
-
*/
|
|
55
|
-
public destroy(): void {
|
|
56
|
-
// Add code to cleanup control if necessary
|
|
57
|
-
}
|
|
58
|
-
}
|