diff --git a/docs/docs/cmd/pp/website/website-webfile-get.mdx b/docs/docs/cmd/pp/website/website-webfile-get.mdx new file mode 100644 index 00000000000..e59dff74874 --- /dev/null +++ b/docs/docs/cmd/pp/website/website-webfile-get.mdx @@ -0,0 +1,188 @@ +import Global from "/docs/cmd/_global.mdx"; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +# pp website webfile get + +Gets information about the specified web file + +## Usage + +```sh +m365 pp website webfile get [options] +``` + +## Options + +```md definition-list +`-e, --environmentName ` +: The name of the environment. + +`-i, --id [id]` +: The id of the web file to retrieve details for. + +`--websiteId [websiteId]` +: ID of the Power Pages website. Specify either `websiteId` or `websiteName` but not both. + +`--websiteName [websiteName]` +: The unique name (not the display name) of the Power Pages website. Specify either `websiteId` or `websiteName but not both. + +`--asAdmin` +: Run the command as admin for environments you do not have explicitly assigned permissions to. +``` + + + +## Examples + +Retrieve web file for the site Contoso in a specific environment. + +```sh +m365 pp website webfile get --environmentName "Default-d87a7535-dd31-4437-bfe1-95340acd55c5" --websiteName "CLI 365 Website" --id 3a081d91-5ea8-40a7-8ac9-abbaa3fcb893 +``` + +Get a specific website webfile in a specific environment based on name as admin. + +```sh +m365 pp website webfile get --environmentName "Default-d87a7535-dd31-4437-bfe1-95340acd55c5" --websiteName "CLI 365 Website" --id 3a081d91-5ea8-40a7-8ac9-abbaa3fcb893 --asAdmin +``` + +Get a specific website webfile in a specific environment based on id. + +```sh +m365 pp website webfile get --environmentName "Default-d87a7535-dd31-4437-bfe1-95340acd55c5" --websiteId 3bbc8102-8ee7-4dac-afbb-807cc5b6f9c2 --id 3a081d91-5ea8-40a7-8ac9-abbaa3fcb893 +``` + +Get a specific website webfile in a specific environment based on id as admin. + +```sh +m365 pp website webfile get --environmentName "Default-d87a7535-dd31-4437-bfe1-95340acd55c5" --websiteId 3bbc8102-8ee7-4dac-afbb-807cc5b6f9c2 --id 3a081d91-5ea8-40a7-8ac9-abbaa3fcb893 --asAdmin +``` + +## Response + + + + +```json +{ + "mspp_webfileid": "3a081d91-5ea8-40a7-8ac9-abbaa3fcb893", + "mspp_name": "theme.css", + "mspp_contentdisposition@OData.Community.Display.V1.FormattedValue": "inline", + "mspp_contentdisposition": 756150000, + "mspp_displayorder@OData.Community.Display.V1.FormattedValue": "9", + "mspp_displayorder": 9, + "mspp_excludefromsearch@OData.Community.Display.V1.FormattedValue": "Yes", + "mspp_excludefromsearch": true, + "mspp_hiddenfromsitemap@OData.Community.Display.V1.FormattedValue": "No", + "mspp_hiddenfromsitemap": false, + "_mspp_parentpageid_value@Microsoft.Dynamics.CRM.associatednavigationproperty": "mspp_parentpageid", + "_mspp_parentpageid_value@Microsoft.Dynamics.CRM.lookuplogicalname": "mspp_webpage", + "_mspp_parentpageid_value@OData.Community.Display.V1.FormattedValue": "Home", + "_mspp_parentpageid_value": "a3d84663-6409-4cce-a269-604a78287ecb", + "mspp_partialurl": "theme.css", + "_mspp_publishingstateid_value@Microsoft.Dynamics.CRM.associatednavigationproperty": "mspp_publishingstateid", + "_mspp_publishingstateid_value@Microsoft.Dynamics.CRM.lookuplogicalname": "mspp_publishingstate", + "_mspp_publishingstateid_value@OData.Community.Display.V1.FormattedValue": "Published", + "_mspp_publishingstateid_value": "ffefd269-446e-46aa-9379-92d1b2d323b8", + "_mspp_websiteid_value@Microsoft.Dynamics.CRM.associatednavigationproperty": "mspp_websiteid", + "_mspp_websiteid_value@Microsoft.Dynamics.CRM.lookuplogicalname": "mspp_website", + "_mspp_websiteid_value@OData.Community.Display.V1.FormattedValue": "CLI 365 Website", + "_mspp_websiteid_value": "5a9c900e-8d0e-422d-970f-cd3cf28252ed", + "_mspp_createdby_value@Microsoft.Dynamics.CRM.lookuplogicalname": "systemuser", + "_mspp_createdby_value@OData.Community.Display.V1.FormattedValue": "Shantha Kumar Thambidurai", + "_mspp_createdby_value": "5364ffa6-d185-ee11-8179-6045bd0027e0", + "_mspp_modifiedby_value@Microsoft.Dynamics.CRM.lookuplogicalname": "systemuser", + "_mspp_modifiedby_value@OData.Community.Display.V1.FormattedValue": "Shantha Kumar Thambidurai", + "_mspp_modifiedby_value": "5364ffa6-d185-ee11-8179-6045bd0027e0", + "mspp_modifiedon@OData.Community.Display.V1.FormattedValue": "4/12/2024 11:16 AM", + "mspp_modifiedon": "2024-04-12T05:46:36Z", + "mspp_createdon@OData.Community.Display.V1.FormattedValue": "4/12/2024 11:16 AM", + "mspp_createdon": "2024-04-12T05:46:19Z", + "statecode: 0, + "statuscode@OData.Community.Display.V1.FormattedValue": "Active", + "statuscode: 1, + "mspp_title: null, + "mspp_displaydate: null, + "mspp_summary: null, + "mspp_cloudblobaddress: null, + "mspp_modifiedbyusername: null, + "mspp_alloworigin: null, + "mspp_expirationdate: null, + "mspp_createdbyipaddress: null, + "mspp_createdbyusername: null, + "mspp_modifiedbyipaddress: null, + "mspp_releasedate: null, + "_mspp_masterwebfileid_value: null +} +``` + + + + +```text +_mspp_publishingstateid_value@OData.Community.Display.V1.FormattedValue: Published +mspp_name : theme.css +mspp_summary : null +mspp_webfileid : 3a081d91-5ea8-40a7-8ac9-abbaa3fcb893 +``` + + + + +```csv +mspp_webfileid,mspp_name,mspp_contentdisposition@OData.Community.Display.V1.FormattedValue,mspp_contentdisposition,mspp_displayorder@OData.Community.Display.V1.FormattedValue,mspp_displayorder,mspp_excludefromsearch@OData.Community.Display.V1.FormattedValue,mspp_excludefromsearch,mspp_hiddenfromsitemap@OData.Community.Display.V1.FormattedValue,mspp_hiddenfromsitemap,_mspp_parentpageid_value@Microsoft.Dynamics.CRM.associatednavigationproperty,_mspp_parentpageid_value@Microsoft.Dynamics.CRM.lookuplogicalname,_mspp_parentpageid_value@OData.Community.Display.V1.FormattedValue,_mspp_parentpageid_value,mspp_partialurl,_mspp_publishingstateid_value@Microsoft.Dynamics.CRM.associatednavigationproperty,_mspp_publishingstateid_value@Microsoft.Dynamics.CRM.lookuplogicalname,_mspp_publishingstateid_value@OData.Community.Display.V1.FormattedValue,_mspp_publishingstateid_value,_mspp_websiteid_value@Microsoft.Dynamics.CRM.associatednavigationproperty,_mspp_websiteid_value@Microsoft.Dynamics.CRM.lookuplogicalname,_mspp_websiteid_value@OData.Community.Display.V1.FormattedValue,_mspp_websiteid_value,_mspp_createdby_value@Microsoft.Dynamics.CRM.lookuplogicalname,_mspp_createdby_value@OData.Community.Display.V1.FormattedValue,_mspp_createdby_value,_mspp_modifiedby_value@Microsoft.Dynamics.CRM.lookuplogicalname,_mspp_modifiedby_value@OData.Community.Display.V1.FormattedValue,_mspp_modifiedby_value,mspp_modifiedon@OData.Community.Display.V1.FormattedValue,mspp_modifiedon,mspp_createdon@OData.Community.Display.V1.FormattedValue,mspp_createdon,statecode,statuscode@OData.Community.Display.V1.FormattedValue,statuscode,mspp_title,mspp_displaydate,mspp_summary,mspp_cloudblobaddress,mspp_modifiedbyusername,mspp_alloworigin,mspp_expirationdate,mspp_createdbyipaddress,mspp_createdbyusername,mspp_modifiedbyipaddress,mspp_releasedate,_mspp_masterwebfileid_value +3a081d91-5ea8-40a7-8ac9-abbaa3fcb893,theme.css,inline,756150000,9,9,Yes,1,No,0,mspp_parentpageid,mspp_webpage,Home,a3d84663-6409-4cce-a269-604a78287ecb,theme.css,mspp_publishingstateid,mspp_publishingstate,Published,ffefd269-446e-46aa-9379-92d1b2d323b8,mspp_websiteid,mspp_website,CLI 365 Website,5a9c900e-8d0e-422d-970f-cd3cf28252ed,systemuser,Shantha Kumar Thambidurai,5364ffa6-d185-ee11-8179-6045bd0027e0,systemuser,Shantha Kumar Thambidurai,5364ffa6-d185-ee11-8179-6045bd0027e0,4/12/2024 11:16 AM,2024-04-12T05:46:36Z,4/12/2024 11:16 AM,2024-04-12T05:46:19Z,0,Active,1,,,,,,,,,,,, +``` + + + + +```md +# pp website webfile get --environmentName "Default-d87a7535-dd31-4437-bfe1-95340acd55c5" --websiteId 3bbc8102-8ee7-4dac-afbb-807cc5b6f9c2 --id "3a081d91-5ea8-40a7-8ac9-abbaa3fcb893" --output md + + +| Property | Value | +| ------------------------------------------------------------------------------------ | ------------------------------------ | +| mspp\_webfileid | 3a081d91-5ea8-40a7-8ac9-abbaa3fcb893 | +| mspp\_name | theme.css | +| mspp\_contentdisposition@OData.Community.Display.V1.FormattedValue | inline | +| mspp\_contentdisposition | 756150000 | +| mspp\_displayorder@OData.Community.Display.V1.FormattedValue | 9 | +| mspp\_displayorder | 9 | +| mspp\_excludefromsearch@OData.Community.Display.V1.FormattedValue | Yes | +| mspp\_excludefromsearch | true | +| mspp\_hiddenfromsitemap@OData.Community.Display.V1.FormattedValue | No | +| mspp\_hiddenfromsitemap | false | +| \_mspp\_parentpageid\_value@Microsoft.Dynamics.CRM.associatednavigationproperty | mspp\_parentpageid | +| \_mspp\_parentpageid\_value@Microsoft.Dynamics.CRM.lookuplogicalname | mspp\_webpage | +| \_mspp\_parentpageid\_value@OData.Community.Display.V1.FormattedValue | Home | +| \_mspp\_parentpageid\_value | a3d84663-6409-4cce-a269-604a78287ecb | +| mspp\_partialurl | theme.css | +| \_mspp\_publishingstateid\_value@Microsoft.Dynamics.CRM.associatednavigationproperty | mspp\_publishingstateid | +| \_mspp\_publishingstateid\_value@Microsoft.Dynamics.CRM.lookuplogicalname | mspp\_publishingstate | +| \_mspp\_publishingstateid\_value@OData.Community.Display.V1.FormattedValue | Published | +| \_mspp\_publishingstateid\_value | ffefd269-446e-46aa-9379-92d1b2d323b8 | +| \_mspp\_websiteid\_value@Microsoft.Dynamics.CRM.associatednavigationproperty | mspp\_websiteid | +| \_mspp\_websiteid\_value@Microsoft.Dynamics.CRM.lookuplogicalname | mspp\_website | +| \_mspp\_websiteid\_value@OData.Community.Display.V1.FormattedValue | CLI 365 Website | +| \_mspp\_websiteid\_value | 3bbc8102-8ee7-4dac-afbb-807cc5b6f9c2 | +| \_mspp\_createdby\_value@Microsoft.Dynamics.CRM.lookuplogicalname | systemuser | +| \_mspp\_createdby\_value@OData.Community.Display.V1.FormattedValue | Shantha Kumar Thambidurai | +| \_mspp\_createdby\_value | 5364ffa6-d185-ee11-8179-6045bd0027e0 | +| \_mspp\_modifiedby\_value@Microsoft.Dynamics.CRM.lookuplogicalname | systemuser | +| \_mspp\_modifiedby\_value@OData.Community.Display.V1.FormattedValue | Shantha Kumar Thambidurai | +| \_mspp\_modifiedby\_value | 5364ffa6-d185-ee11-8179-6045bd0027e0 | +| mspp\_modifiedon@OData.Community.Display.V1.FormattedValue | 4/12/2024 11:16 AM | +| mspp\_modifiedon | 2024-04-12T05:46:36Z | +| mspp\_createdon@OData.Community.Display.V1.FormattedValue | 4/12/2024 11:16 AM | +| mspp\_createdon | 2024-04-12T05:46:19Z | +| statecode | 0 | +| statuscode@OData.Community.Display.V1.FormattedValue | Active | +| statuscode | 1 | + + +``` + + + diff --git a/docs/src/config/sidebars.ts b/docs/src/config/sidebars.ts index 0370e28df09..e36ab03f076 100644 --- a/docs/src/config/sidebars.ts +++ b/docs/src/config/sidebars.ts @@ -1799,6 +1799,15 @@ const sidebars: SidebarsConfig = { id: 'cmd/pp/tenant/tenant-settings-set' } ] + }, + { + website: [ + { + type: 'doc', + label: 'website webfile get', + id: 'cmd/pp/website/website-webfile-get' + }, + ] } ] }, diff --git a/src/m365/pp/commands.ts b/src/m365/pp/commands.ts index dae86ad2616..98b830b759f 100644 --- a/src/m365/pp/commands.ts +++ b/src/m365/pp/commands.ts @@ -31,5 +31,6 @@ export default { SOLUTION_PUBLISHER_LIST: `${prefix} solution publisher list`, SOLUTION_PUBLISHER_REMOVE: `${prefix} solution publisher remove`, TENANT_SETTINGS_LIST: `${prefix} tenant settings list`, - TENANT_SETTINGS_SET: `${prefix} tenant settings set` + TENANT_SETTINGS_SET: `${prefix} tenant settings set`, + WEBSITE_WEBFILE_GET: `${prefix} website webfile get` }; \ No newline at end of file diff --git a/src/m365/pp/commands/Website.ts b/src/m365/pp/commands/Website.ts new file mode 100644 index 00000000000..bf6aeb82401 --- /dev/null +++ b/src/m365/pp/commands/Website.ts @@ -0,0 +1,8 @@ +import GlobalOptions from "../../../GlobalOptions"; +export interface PpWebSiteOptions extends GlobalOptions { + environmentName: string; + id?: string; + name?: string; + url?: string; + asAdmin?: boolean; +} \ No newline at end of file diff --git a/src/m365/pp/commands/website/website-webfile-get.spec.ts b/src/m365/pp/commands/website/website-webfile-get.spec.ts new file mode 100644 index 00000000000..26bef3213c2 --- /dev/null +++ b/src/m365/pp/commands/website/website-webfile-get.spec.ts @@ -0,0 +1,302 @@ +import assert from 'assert'; +import sinon from 'sinon'; +import auth from '../../../../Auth.js'; +import { cli } from '../../../../cli/cli.js'; +import { CommandInfo } from '../../../../cli/CommandInfo.js'; +import { Logger } from '../../../../cli/Logger.js'; +import { CommandError } from '../../../../Command.js'; +import request from '../../../../request.js'; +import { telemetry } from '../../../../telemetry.js'; +import { pid } from '../../../../utils/pid.js'; +import { session } from '../../../../utils/session.js'; +import { powerPlatform } from '../../../../utils/powerPlatform.js'; +import { sinonUtil } from '../../../../utils/sinonUtil.js'; +import commands from '../../commands.js'; +import command from './website-webfile-get.js'; +import { accessToken } from '../../../../utils/accessToken.js'; + +describe(commands.WEBSITE_WEBFILE_GET, () => { + let commandInfo: CommandInfo; + //#region Mocked Responses + const validEnvironment = '4be50206-9576-4237-8b17-38d8aadfaa36'; + const validId = '3a081d91-5ea8-40a7-8ac9-abbaa3fcb893'; + const validWebsiteId = '3bbc8102-8ee7-4dac-afbb-807cc5b6f9c2'; + const validWebsiteName = 'CLI 365 PowerPageSite'; + const envUrl = "https://contoso-dev.api.crm4.dynamics.com"; + const envResponse: any = { "properties": { "linkedEnvironmentMetadata": { "instanceApiUrl": "https://contoso-dev.api.crm4.dynamics.com" } } }; + const webfileResponse: any = { + "value": [ + { + "mspp_webfileid": "3a081d91-5ea8-40a7-8ac9-abbaa3fcb893", + "mspp_name": "Site-mockup-1.png", + "mspp_contentdisposition@OData.Community.Display.V1.FormattedValue": "inline", + "mspp_contentdisposition": 756150000, + "mspp_excludefromsearch@OData.Community.Display.V1.FormattedValue": "No", + "mspp_excludefromsearch": false, + "mspp_hiddenfromsitemap@OData.Community.Display.V1.FormattedValue": "No", + "mspp_hiddenfromsitemap": false, + "_mspp_parentpageid_value@Microsoft.Dynamics.CRM.associatednavigationproperty": "mspp_parentpageid", + "_mspp_parentpageid_value@Microsoft.Dynamics.CRM.lookuplogicalname": "mspp_webpage", + "_mspp_parentpageid_value@OData.Community.Display.V1.FormattedValue": "Home", + "_mspp_parentpageid_value": "a3efb062-0691-4d3e-a9e6-43bfd2daeed6", + "mspp_partialurl": "Site-mockup-1.png", + "_mspp_publishingstateid_value@Microsoft.Dynamics.CRM.associatednavigationproperty": "mspp_publishingstateid", + "_mspp_publishingstateid_value@Microsoft.Dynamics.CRM.lookuplogicalname": "mspp_publishingstate", + "_mspp_publishingstateid_value@OData.Community.Display.V1.FormattedValue": "Published", + "_mspp_publishingstateid_value": "0d0fa682-7ed7-419b-bc7a-25e8bc64b6e2", + "_mspp_websiteid_value@Microsoft.Dynamics.CRM.associatednavigationproperty": "mspp_websiteid", + "_mspp_websiteid_value@Microsoft.Dynamics.CRM.lookuplogicalname": "mspp_website", + "_mspp_websiteid_value@OData.Community.Display.V1.FormattedValue": "Website", + "_mspp_websiteid_value": "3bbc8102-8ee7-4dac-afbb-807cc5b6f9c2", + "_mspp_createdby_value@Microsoft.Dynamics.CRM.lookuplogicalname": "systemuser", + "_mspp_createdby_value@OData.Community.Display.V1.FormattedValue": "Shanthakumar", + "_mspp_createdby_value": "66ece047-0e90-ee11-8179-000d3a37640e", + "_mspp_modifiedby_value@Microsoft.Dynamics.CRM.lookuplogicalname": "systemuser", + "_mspp_modifiedby_value@OData.Community.Display.V1.FormattedValue": "Shanthakumar", + "_mspp_modifiedby_value": "66ece047-0e90-ee11-8179-000d3a37640e", + "mspp_modifiedon@OData.Community.Display.V1.FormattedValue": "8/27/2024 2:37 PM", + "mspp_modifiedon": "2024-08-27T09:07:22Z", + "mspp_createdon@OData.Community.Display.V1.FormattedValue": "8/27/2024 2:37 PM", + "mspp_createdon": "2024-08-27T09:07:16Z", + "statecode": 0, + "statuscode@OData.Community.Display.V1.FormattedValue": "Active", + "statuscode": 1, + "mspp_title": null, + "mspp_displaydate": null, + "mspp_displayorder": null, + "mspp_summary": null, + "mspp_cloudblobaddress": null, + "mspp_modifiedbyusername": null, + "mspp_alloworigin": null, + "mspp_expirationdate": null, + "mspp_createdbyipaddress": null, + "mspp_createdbyusername": null, + "mspp_modifiedbyipaddress": null, + "mspp_releasedate": null, + "_mspp_masterwebfileid_value": null + } + ] + }; + //#endregion + + let log: string[]; + let logger: Logger; + let loggerLogSpy: sinon.SinonSpy; + + before(() => { + sinon.stub(auth, 'restoreAuth').resolves(); + sinon.stub(telemetry, 'trackEvent').returns(); + sinon.stub(pid, 'getProcessName').returns(''); + sinon.stub(session, 'getId').returns(''); + sinon.stub(accessToken, 'assertDelegatedAccessToken').returns(); + auth.connection.active = true; + commandInfo = cli.getCommandInfo(command); + sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName: string, defaultValue: any) => { + if (settingName === 'prompt') { + return false; + } + return defaultValue; + }); + }); + + beforeEach(() => { + log = []; + logger = { + log: async (msg: string) => { + log.push(msg); + }, + logRaw: async (msg: string) => { + log.push(msg); + }, + logToStderr: async (msg: string) => { + log.push(msg); + } + }; + loggerLogSpy = sinon.spy(logger, 'log'); + }); + + afterEach(() => { + sinonUtil.restore([ + request.get, + powerPlatform.getDynamicsInstanceApiUrl, + cli.getSettingWithDefaultValue + ]); + }); + + after(() => { + sinon.restore(); + auth.connection.active = false; + }); + + it('has correct name', () => { + assert.strictEqual(command.name, commands.WEBSITE_WEBFILE_GET); + }); + + it('has a description', () => { + assert.notStrictEqual(command.description, null); + }); + + it('defines correct properties for the default output', () => { + assert.deepStrictEqual(command.defaultProperties(), ['mspp_name', 'mspp_webfileid', 'mspp_summary', '_mspp_publishingstateid_value@OData.Community.Display.V1.FormattedValue']); + }); + + it('fails validation if id is not a valid guid.', async () => { + const actual = await command.validate({ + options: { + environmentName: validEnvironment, + id: 'Invalid GUID', + websiteId: validWebsiteId + } + }, commandInfo); + assert.notStrictEqual(actual, true); + }); + + it('fails validation if websiteId is not a valid guid.', async () => { + const actual = await command.validate({ + options: { + environmentName: validEnvironment, + id: validId, + websiteId: 'Invalid GUID' + } + }, commandInfo); + assert.notStrictEqual(actual, true); + }); + + it('passes validation if required options specified (id)', async () => { + const actual = await command.validate({ options: { environmentName: validEnvironment, id: validId, websiteId: validWebsiteId } }, commandInfo); + assert.strictEqual(actual, true); + }); + + it('passes validation if required options specified (websiteName)', async () => { + const actual = await command.validate({ options: { environmentName: validEnvironment, id: validId, websiteName: validWebsiteName } }, commandInfo); + assert.strictEqual(actual, true); + }); + + it('fails validation on unable to find website based on websiteName', async () => { + const EmptyWebsiteResponse = { + value: [ + ] + }; + + sinon.stub(powerPlatform, 'getDynamicsInstanceApiUrl').callsFake(async () => envUrl); + + sinon.stub(request, 'get').callsFake(async (opts) => { + + if ((opts.url === `https://contoso-dev.api.crm4.dynamics.com/api/data/v9.2/powerpagesites?$filter=name eq 'Invalid website'&$select=powerpagesiteid`)) { + return EmptyWebsiteResponse; + } + throw `Invalid request`; + }); + + await assert.rejects(command.action(logger, { + options: { + debug: true, + environmentName: `${validEnvironment}`, + websiteName: 'Invalid website', + id: validId + } + }), new CommandError(`The specified website 'Invalid website' does not exist.`)); + }); + + + it('return webfile based on websiteName and webfileId', async () => { + + sinon.stub(powerPlatform, 'getDynamicsInstanceApiUrl').callsFake(async () => envUrl); + + sinon.stub(request, 'get').callsFake(async opts => { + + if (opts.url === `https://contoso-dev.api.crm4.dynamics.com/api/data/v9.2/powerpagesites?$filter=name eq '${validWebsiteName}'&$select=powerpagesiteid`) { + return { + "value": [ + { + "powerpagesiteid": validWebsiteId + } + ] + }; + } + + if ((opts.url === `https://contoso-dev.api.crm4.dynamics.com/api/data/v9.2/mspp_webfiles?$filter=mspp_webfileid eq '${validId}' and _mspp_websiteid_value eq '${validWebsiteId}'`)) { + if (opts.headers && + opts.headers.accept && + (opts.headers.accept as string).indexOf('application/json') === 0) { + return webfileResponse; + } + } + + throw 'Invalid request'; + }); + + await command.action(logger, { + options: { + debug: true, + environmentName: validEnvironment, + websiteName: validWebsiteName, + id: validId + } + }); + assert(loggerLogSpy.calledWith(webfileResponse.value[0])); + }); + + it('retrieves webfile based on id and websiteId', async () => { + + sinon.stub(request, 'get').callsFake(async opts => { + + if ((opts.url === `https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/environments/${validEnvironment}?api-version=2020-10-01&$select=properties.linkedEnvironmentMetadata.instanceApiUrl`)) { + if (opts.headers && + opts.headers.accept && + (opts.headers.accept as string).indexOf('application/json') === 0) { + return envResponse; + } + } + + if ((opts.url === `https://contoso-dev.api.crm4.dynamics.com/api/data/v9.2/mspp_webfiles?$filter=mspp_webfileid eq '${validId}' and _mspp_websiteid_value eq '${validWebsiteId}'`)) { + if (opts.headers && + opts.headers.accept && + (opts.headers.accept as string).indexOf('application/json') === 0) { + return webfileResponse; + } + } + + throw 'Invalid request'; + }); + + await command.action(logger, { options: { debug: true, environmentName: `${validEnvironment}`, websiteId: `${validWebsiteId}`, id: `${validId}` } }); + assert(loggerLogSpy.calledWith(webfileResponse.value[0])); + + }); + + it('fails validation on unable to find webfile based on webfileId and websiteId as admin', async () => { + + sinon.stub(request, 'get').callsFake(async opts => { + + if ((opts.url === `https://api.bap.microsoft.com/providers/Microsoft.BusinessAppPlatform/environments/${validEnvironment}?api-version=2020-10-01&$select=properties.linkedEnvironmentMetadata.instanceApiUrl`)) { + if (opts.headers && + opts.headers.accept && + (opts.headers.accept as string).indexOf('application/json') === 0) { + return envResponse; + } + } + + if ((opts.url === `https://contoso-dev.api.crm4.dynamics.com/api/data/v9.2/mspp_webfiles?$filter=mspp_webfileid eq 'Invalid id' and _mspp_websiteid_value eq '${validWebsiteId}'`)) { + if (opts.headers && + opts.headers.accept && + (opts.headers.accept as string).indexOf('application/json') === 0) { + return { "value": [] }; + } + } + + throw 'Invalid request'; + }); + + await assert.rejects(command.action(logger, { + options: { + debug: true, + environmentName: `${validEnvironment}`, + websiteId: `${validWebsiteId}`, + id: 'Invalid id' + } + }), new CommandError(`The specified webfile 'Invalid id' does not exist.`)); + + }); + +}); \ No newline at end of file diff --git a/src/m365/pp/commands/website/website-webfile-get.ts b/src/m365/pp/commands/website/website-webfile-get.ts new file mode 100644 index 00000000000..c1a81021ee4 --- /dev/null +++ b/src/m365/pp/commands/website/website-webfile-get.ts @@ -0,0 +1,196 @@ +import { Logger } from '../../../../cli/Logger.js'; +import GlobalOptions from '../../../../GlobalOptions.js'; +import request, { CliRequestOptions } from '../../../../request.js'; +import { powerPlatform } from '../../../../utils/powerPlatform.js'; +import { validation } from '../../../../utils/validation.js'; +import PowerPlatformCommand from '../../../base/PowerPlatformCommand.js'; +import commands from '../../commands.js'; +import { PpWebSiteOptions } from '../Website.js'; + +interface CommandArgs { + options: Options; +} + +export interface Options extends GlobalOptions { + environmentName: string; + id?: string; + websiteId?: string; + websiteName?: string; + asAdmin?: boolean; +} + +class PpWebSiteWebFileGetCommand extends PowerPlatformCommand { + + public get name(): string { + return commands.WEBSITE_WEBFILE_GET; + } + + public get description(): string { + return 'Gets information about the specified web file'; + } + + public defaultProperties(): string[] | undefined { + return ['mspp_name', 'mspp_webfileid', 'mspp_summary', '_mspp_publishingstateid_value@OData.Community.Display.V1.FormattedValue']; + } + + constructor() { + super(); + + this.#initTelemetry(); + this.#initOptions(); + this.#initValidators(); + this.#initOptionSets(); + } + + #initTelemetry(): void { + this.telemetry.push((args: CommandArgs) => { + Object.assign(this.telemetryProperties, { + id: typeof args.options.id !== 'undefined', + websiteId: typeof args.options.websiteId !== 'undefined', + websiteName: typeof args.options.name !== 'undefined', + asAdmin: !!args.options.asAdmin + }); + }); + } + + #initOptions(): void { + this.options.unshift( + { + option: '-e, --environmentName ' + }, + { + option: '-i, --id [id]' + }, + { + option: '--websiteId [websiteId]' + }, + { + option: '--websiteName [websiteName]' + }, + { + option: '--asAdmin' + } + ); + } + + #initOptionSets(): void { + this.optionSets.push( + { options: ['websiteId', 'websiteName'] } + ); + } + + #initValidators(): void { + this.validators.push( + async (args: CommandArgs) => { + if (args.options.id && !validation.isValidGuid(args.options.id as string)) { + return `${args.options.id} is not a valid GUID`; + } + if (args.options.websiteId && !validation.isValidGuid(args.options.websiteId)) { + return `${args.options.websiteId} is not a valid GUID`; + } + + return true; + } + ); + } + + private async getWebSiteId(dynamicsApiUrl: string, args: CommandArgs): Promise { + if (args.options.websiteId) { + return args.options.websiteId; + } + const options: PpWebSiteOptions = { + environmentName: args.options.environmentName, + id: args.options.websiteId, + name: args.options.websiteName, + output: 'json' + }; + + const requestOptions: CliRequestOptions = { + headers: { + accept: 'applciation/json;odata.metadata=none' + }, + responseType: 'json' + }; + + if (options.name) { + requestOptions.url = `${dynamicsApiUrl}/api/data/v9.2/powerpagesites?$filter=name eq '${options.name}'&$select=powerpagesiteid`; + const result = await request.get<{ value: any[] }>(requestOptions); + + if (result.value.length === 0) { + throw `The specified website '${args.options.websiteName}' does not exist.`; + } + return result.value[0].powerpagesiteid; + } + } + + public async commandAction(logger: Logger, args: CommandArgs): Promise { + if (this.verbose) { + await logger.logToStderr(`Retrieving a website webfile '${args.options.websiteId || args.options.websiteName}'...`); + } + + try { + const dynamicsApiUrl = await powerPlatform.getDynamicsInstanceApiUrl(args.options.environmentName, args.options.asAdmin); + + const websiteId = await this.getWebSiteId(dynamicsApiUrl, args); + + const res = await this.getWebSiteWebFile(dynamicsApiUrl, websiteId, args.options); + await logger.log(res); + } + catch (err: any) { + this.handleRejectedODataJsonPromise(err); + } + } + + private async getWebSiteWebFile(dynamicsApiUrl: string, websiteId: string, options: Options): Promise { + + const requestOptions: CliRequestOptions = { + headers: { + accept: 'application/json;odata.metadata=none', + 'odata-version': '4.0', + prefer: 'odata.include-annotations="*"' + }, + responseType: 'json' + }; + + // let webfileitem: any | null = null; + // requestOptions.url = `${dynamicsApiUrl}/api/data/v9.2/mspp_webfiles(${options.id})`; + // const result = await request.get(requestOptions); + // webfileitem = result; + + // if (!webfileitem || webfileitem["_mspp_websiteid_value"] !== websiteId) { + // throw `The specified webfile '${options.id}' does not exist on website.`; + // } + + // return webfileitem; + + + requestOptions.url = `${dynamicsApiUrl}/api/data/v9.2/mspp_webfiles?$filter=mspp_webfileid eq '${options.id}' and _mspp_websiteid_value eq '${websiteId}'`; + const result = await request.get<{ value: any[] }>(requestOptions); + + if (result.value.length === 0) { + throw `The specified webfile '${options.id}' does not exist.`; + } + + return result.value[0]; + + + + + // requestOptions.url = `${dynamicsApiUrl}/api/data/v9.1/websitewebfiles?$filter=name eq '${options.name}'`; + // const result = await request.get<{ value: any[] }>(requestOptions); + + // if (result.value.length === 0) { + // throw `The specified websitewebfile '${options.name}' does not exist.`; + // } + + // if (result.value.length > 1) { + // const resultAsKeyValuePair = formatting.convertArrayToHashTable('websitewebfileid', result.value); + // return cli.handleMultipleResultsFound(`Multiple websitewebfiles with name '${options.name}' found`, resultAsKeyValuePair); + // } + + // return result.value[0]; + + } +} + +export default new PpWebSiteWebFileGetCommand(); \ No newline at end of file