create-powerapps-project 1.2.3 → 1.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.
@@ -8,7 +8,11 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
8
8
  const didSucceed = (code) => `${code}` === '0';
9
9
  export default (plop) => {
10
10
  plop.setDefaultInclude({ actionTypes: true });
11
- plop.setActionType('addSolution', async (answers) => {
11
+ plop.setActionType('addDirectory', async (answers) => {
12
+ await fs.promises.mkdir(path.resolve(process.cwd(), answers.folder));
13
+ return `added directory ${answers.folder}`;
14
+ });
15
+ plop.setActionType('addSolution', (answers) => {
12
16
  // Add solution
13
17
  spawnSync('dotnet', ['new', 'sln', '-n', answers.name], { cwd: process.cwd(), stdio: 'inherit' });
14
18
  spawnSync('dotnet', ['sln', 'add', `${answers.name}.csproj`], { cwd: process.cwd(), stdio: 'inherit' });
package/lib/plopfile.js CHANGED
@@ -255,6 +255,23 @@ export default async (plop) => {
255
255
  name: 'prefix',
256
256
  message: 'publisher prefix'
257
257
  },
258
+ {
259
+ type: 'input',
260
+ name: 'server',
261
+ message: 'enter dataverse url (https://org.crm.dynamics.com):',
262
+ validate: (answer) => {
263
+ try {
264
+ const url = new URL(answer);
265
+ if (url.protocol !== 'https:') {
266
+ return 'server should begin with https';
267
+ }
268
+ return true;
269
+ }
270
+ catch (ex) {
271
+ return 'enter a valid URL';
272
+ }
273
+ }
274
+ },
258
275
  {
259
276
  type: 'confirm',
260
277
  name: 'react',
@@ -263,6 +280,7 @@ export default async (plop) => {
263
280
  packageQuestion
264
281
  ],
265
282
  actions: (data) => {
283
+ data.org = new URL(data.server).hostname.split('.')[0];
266
284
  return [
267
285
  {
268
286
  type: 'runPcf'
@@ -279,6 +297,12 @@ export default async (plop) => {
279
297
  path: path.resolve(process.cwd(), 'plopfile.js'),
280
298
  force: true
281
299
  },
300
+ {
301
+ type: 'add',
302
+ templateFile: '../plop-templates/pcf/.eslintrc.json',
303
+ path: path.resolve(process.cwd(), '.eslintrc.json'),
304
+ force: true
305
+ },
282
306
  {
283
307
  type: 'add',
284
308
  templateFile: '../plop-templates/pcf/.gitattributes',
@@ -286,14 +310,20 @@ export default async (plop) => {
286
310
  force: true
287
311
  },
288
312
  {
289
- type: 'addMany',
290
- templateFiles: [
291
- '../plop-templates/pcf/App.tsx.hbs',
292
- '../plop-templates/pcf/AppContext.tsx',
293
- '../plop-templates/webresource/.gitattributes'
294
- ],
295
- base: '../plop-templates/pcf',
296
- destination: `${process.cwd()}/{{name}}`,
313
+ type: 'add',
314
+ templateFile: '../plop-templates/pcf/App.tsx.hbs',
315
+ path: path.resolve(process.cwd(), 'App.tsx'),
316
+ skip: (answers) => {
317
+ if (!answers.react) {
318
+ return 'react not included';
319
+ }
320
+ return;
321
+ }
322
+ },
323
+ {
324
+ type: 'add',
325
+ templateFile: '../plop-templates/pcf/AppContext.tsx.hbs',
326
+ path: path.resolve(process.cwd(), 'contexts', 'AppContext.tsx'),
297
327
  skip: (answers) => {
298
328
  if (!answers.react) {
299
329
  return 'react not included';
@@ -305,32 +335,32 @@ export default async (plop) => {
305
335
  type: 'modify',
306
336
  path: `${process.cwd()}/{{name}}/index.ts`,
307
337
  pattern: 'import { HelloWorld, IHelloWorldProps } from "./HelloWorld";',
308
- template: `import { App, IAppProps } from './App';`
338
+ template: `import { App } from './App';`
309
339
  },
310
340
  {
311
341
  type: 'modify',
312
342
  path: `${process.cwd()}/{{name}}/index.ts`,
313
343
  pattern: 'HelloWorld, props',
314
- template: 'App, props'
344
+ template: 'App, { context: context }'
315
345
  },
316
346
  {
317
347
  type: 'modify',
318
348
  path: `${process.cwd()}/{{name}}/index.ts`,
319
349
  pattern: `const props: IHelloWorldProps = { name: 'Hello, World!' };`,
320
- template: `const props: IAppProps = { context: context };`
350
+ template: ''
321
351
  },
322
352
  {
323
353
  type: 'addScript',
324
354
  data: {
325
- scriptKey: 'build:prod',
326
- scriptValue: 'pcf-scripts build --buildMode production'
355
+ scriptKey: 'authenticate',
356
+ scriptValue: `pac auth create --url ${data.server} --name ${data.org} --deviceCode`
327
357
  }
328
358
  },
329
359
  {
330
360
  type: 'addScript',
331
361
  data: {
332
362
  scriptKey: 'push',
333
- scriptValue: `pac pcf version --strategy manifest && pac pcf push -pp ${data.prefix}`
363
+ scriptValue: `pac auth select --name ${data.org} && pac pcf version --strategy manifest && pac pcf push -pp ${data.prefix}`
334
364
  }
335
365
  },
336
366
  {
@@ -354,7 +384,14 @@ export default async (plop) => {
354
384
  type: 'npmInstall',
355
385
  data: {
356
386
  packages: {
357
- devDependencies: ['powerapps-project-pcf', '@types/react@16', '@types/react-dom@16', 'eslint-plugin-react-hooks']
387
+ devDependencies: [
388
+ 'powerapps-project-pcf',
389
+ '@types/react@16',
390
+ '@types/react-dom@16',
391
+ 'eslint-plugin-react-hooks',
392
+ '@types/xrm'
393
+ ],
394
+ dependencies: ['@fluentui/react-hooks']
358
395
  }
359
396
  },
360
397
  skip: (answers) => {
@@ -363,6 +400,24 @@ export default async (plop) => {
363
400
  }
364
401
  return;
365
402
  }
403
+ },
404
+ {
405
+ type: 'addDirectory',
406
+ data: {
407
+ folder: 'components'
408
+ }
409
+ },
410
+ {
411
+ type: 'addDirectory',
412
+ data: {
413
+ folder: 'services'
414
+ }
415
+ },
416
+ {
417
+ type: 'addDirectory',
418
+ data: {
419
+ folder: 'hooks'
420
+ }
366
421
  }
367
422
  ];
368
423
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-powerapps-project",
3
3
  "description": "💧 plop generator for Dataverse development",
4
- "version": "1.2.3",
4
+ "version": "1.3.0",
5
5
  "license": "MIT",
6
6
  "exports": "./lib/index.js",
7
7
  "engines": {
@@ -7,7 +7,7 @@
7
7
  "gen": "plop",
8
8
  "deploy": "dataverse-utils deploy assembly",
9
9
  "modelbuilder": "pac auth select --name {{org}} && pac modelbuilder build -stf builderSettings.json -o Model",
10
- "authenticate": "pac auth create --url {{server}} --name {{org}}",
10
+ "authenticate": "pac auth create --url {{server}} --name {{org}} --deviceCode",
11
11
  "prt": "pac tool prt"
12
12
  }
13
13
  }
@@ -0,0 +1,34 @@
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
+ }
@@ -2,18 +2,14 @@ import React from 'react';
2
2
  import { IInputs } from './generated/ManifestTypes';
3
3
  import { AppContextProvider } from './AppContext';
4
4
 
5
- export interface IAppProps {
6
- context: ComponentFramework.Context<IInputs>;
7
- }
8
-
9
- export const App = (props: IAppProps) => {
5
+ export const App = (props: { context: ComponentFramework.Context<IInputs>; }) => {
10
6
  const {
11
7
  context
12
8
  } = props;
13
9
 
14
10
  return (
15
- <AppContextProvider context={context}>
16
- </AppContextProvider>
11
+ <AppContext.Provider value="{{ context }}">
12
+ </AppContext.Provider>
17
13
  );
18
14
  };
19
15
 
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { IInputs } from './generated/ManifestTypes';
3
+
4
+ interface IAppContext {
5
+ context: ComponentFramework.Context<IInputs>;
6
+ }
7
+
8
+ const AppContext = React.createContext<IAppContext>({} as IAppContext);
9
+
10
+ export const useAppContext = (): IAppContext => React.useContext(AppContext);
@@ -1,21 +0,0 @@
1
- import React from 'react';
2
- import { IInputs } from './generated/ManifestTypes';
3
-
4
- interface IAppContext {
5
- context: ComponentFramework.Context<IInputs>;
6
- theme?: Record<string, string>;
7
- }
8
-
9
- const AppContext = React.createContext<IAppContext>({} as IAppContext);
10
-
11
- interface IAppContextProviderProps extends IAppContext {
12
- children?: React.ReactNode;
13
- }
14
-
15
- export const AppContextProvider = (props: IAppContextProviderProps): JSX.Element => {
16
- const { context, children } = props;
17
-
18
- return <AppContext.Provider value={{ context }}>{children}</AppContext.Provider>;
19
- };
20
-
21
- export const useAppContext = (): IAppContext => React.useContext(AppContext);