create-powerapps-project 2.2.4 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/plopfile.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import path from 'node:path';
2
- import fs from 'node:fs';
3
2
  import { getNugetPackageVersions } from './nuget.js';
4
3
  /* eslint-disable @typescript-eslint/no-explicit-any */
5
4
  export default async (plop) => {
@@ -284,16 +283,6 @@ export default async (plop) => {
284
283
  name: 'react',
285
284
  message: 'use react?'
286
285
  },
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
286
  packageQuestion
298
287
  ],
299
288
  actions: (data) => {
@@ -302,30 +291,12 @@ export default async (plop) => {
302
291
  {
303
292
  type: 'runPcf'
304
293
  },
305
- {
306
- type: 'add',
307
- templateFile: '../plop-templates/pcf/tsconfig.json',
308
- path: path.resolve(process.cwd(), 'tsconfig.json'),
309
- force: true
310
- },
311
294
  {
312
295
  type: 'add',
313
296
  templateFile: '../plop-templates/pcf/plopfile.js',
314
297
  path: path.resolve(process.cwd(), 'plopfile.js'),
315
298
  force: true
316
299
  },
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
300
  {
330
301
  type: 'add',
331
302
  templateFile: '../plop-templates/pcf/App.tsx',
@@ -334,23 +305,6 @@ export default async (plop) => {
334
305
  if (!answers.react) {
335
306
  return 'react not included';
336
307
  }
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
308
  return;
355
309
  }
356
310
  },
@@ -365,24 +319,47 @@ export default async (plop) => {
365
319
  return;
366
320
  }
367
321
  },
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
322
  {
381
323
  type: 'modify',
382
324
  path: `${process.cwd()}/{{name}}/index.ts`,
383
325
  pattern: 'import { HelloWorld, IHelloWorldProps } from "./HelloWorld";',
384
326
  template: `import { App } from './App';`
385
327
  },
328
+ {
329
+ type: 'append',
330
+ path: `${process.cwd()}/{{name}}.pcfproj`,
331
+ pattern: "</PowerAppsTargetsPath>",
332
+ template: `<PcfEnableAutoNpmInstall Condition=" '$(PcfEnableAutoNpmInstall)' == '' ">false</PcfEnableAutoNpmInstall>`,
333
+ separator: '\n'
334
+ },
335
+ {
336
+ type: 'append',
337
+ path: `${process.cwd()}/{{name}}.pcfproj`,
338
+ pattern: "</PowerAppsTargetsPath>",
339
+ template: `<PcfAlwaysNpmInstall Condition=" '$(PcfAlwaysNpmInstall)' == '' ">false</PcfAlwaysNpmInstall>`,
340
+ separator: '\n'
341
+ },
342
+ {
343
+ type: 'append',
344
+ path: `${process.cwd()}/eslint.config.mjs`,
345
+ pattern: "reactPlugin.configs.flat.recommended,",
346
+ template: "reactHooks.configs.flat.recommended,",
347
+ separator: '\n'
348
+ },
349
+ {
350
+ type: 'append',
351
+ path: `${process.cwd()}/eslint.config.mjs`,
352
+ pattern: `import reactPlugin from "eslint-plugin-react";`,
353
+ template: `import reactHooksPlugin from 'eslint-plugin-react-hooks';`,
354
+ separator: '\n'
355
+ },
356
+ {
357
+ type: 'append',
358
+ path: `${process.cwd()}/{{name}}.pcfproj`,
359
+ pattern: "</OutputPath>",
360
+ template: `<PcfBuildMode>development</PcfBuildMode>`,
361
+ separator: '\n'
362
+ },
386
363
  {
387
364
  type: 'modify',
388
365
  path: `${process.cwd()}/{{name}}/index.ts`,
@@ -392,7 +369,7 @@ export default async (plop) => {
392
369
  {
393
370
  type: 'modify',
394
371
  path: `${process.cwd()}/{{name}}/index.ts`,
395
- pattern: `const props: IHelloWorldProps = { name: 'Hello, World!' };`,
372
+ pattern: `const props: IHelloWorldProps = { name: 'Power Apps' };`,
396
373
  template: ''
397
374
  },
398
375
  {
@@ -413,14 +390,14 @@ export default async (plop) => {
413
390
  type: 'addScript',
414
391
  data: {
415
392
  scriptKey: 'push',
416
- scriptValue: `npm run select-auth && pac pcf version -s manifest && pac pcf push -pp ${data.prefix} -env ${data.server}`
393
+ scriptValue: `${data.package} run select-auth && pac pcf push -pp ${data.prefix} -env ${data.server}`
417
394
  }
418
395
  },
419
396
  {
420
397
  type: 'addScript',
421
398
  data: {
422
399
  scriptKey: 'push-inc',
423
- scriptValue: `npm run build && npm run select-auth && pac pcf version -s manifest && pac pcf push -pp ${data.prefix} -inc -env ${data.server}`
400
+ scriptValue: `${data.package} run build && ${data.package} run select-auth && pac pcf push -pp ${data.prefix} -inc -env ${data.server}`
424
401
  }
425
402
  },
426
403
  {
@@ -430,13 +407,6 @@ export default async (plop) => {
430
407
  scriptValue: `npx only-allow ${data.package}`
431
408
  }
432
409
  },
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
410
  {
441
411
  type: 'npmInstall'
442
412
  },
@@ -446,46 +416,16 @@ export default async (plop) => {
446
416
  packages: {
447
417
  devDependencies: [
448
418
  'powerapps-project-pcf',
449
- '@types/react@^16',
450
- '@types/react-dom@^16',
451
419
  'eslint-plugin-react-hooks',
452
420
  '@types/xrm'
453
421
  ],
454
- dependencies: ['@fluentui/react-hooks']
455
- }
456
- },
457
- skip: (answers) => {
458
- if (!answers.react) {
459
- return 'react not included';
460
- }
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']
422
+ dependencies: ['@fluentui/react-icons']
480
423
  }
481
424
  },
482
425
  skip: (answers) => {
483
426
  if (!answers.react) {
484
427
  return 'react not included';
485
428
  }
486
- if (answers.fluentVersion === 8) {
487
- return 'using fluent v8';
488
- }
489
429
  return;
490
430
  }
491
431
  }
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.2.4",
4
+ "version": "2.3.0",
5
5
  "license": "MIT",
6
6
  "exports": "./lib/index.js",
7
7
  "engines": {
8
- "node": ">=20.0.0"
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": "^3.1.2"
30
- },
31
- "volta": {
32
- "extends": "../../package.json"
29
+ "plop": "^4.0.4"
33
30
  }
34
31
  }
@@ -2,11 +2,7 @@ import React from 'react';
2
2
  import { IInputs } from './generated/ManifestTypes';
3
3
  import { AppContext } from './contexts/AppContext';
4
4
 
5
- export const App = (props: { context: ComponentFramework.Context<IInputs>; }) => {
6
- const {
7
- context
8
- } = props;
9
-
5
+ export const App = ({ context }: { context: ComponentFramework.Context<IInputs>; }) => {
10
6
  return (
11
7
  <AppContext.Provider value={{{ context }}}>
12
8
  </AppContext.Provider>
@@ -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,3 +0,0 @@
1
- * text=auto eol=lf
2
- *.{cmd,[cC][mM][dD]} text eol=crlf
3
- *.{bat,[bB][aA][tT]} text eol=crlf
@@ -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
- }
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "./node_modules/pcf-scripts/tsconfig_base.json",
3
- "compilerOptions": {
4
- "typeRoots": ["node_modules/@types"],
5
- "esModuleInterop": true,
6
- "target": "ES6",
7
- "module": "es2015",
8
- "moduleResolution": "node"
9
- }
10
- }