Skip to content

Commit

Permalink
WIP graph pages, graph site open extenions and DebugHeaders
Browse files Browse the repository at this point in the history
  • Loading branch information
patrick-rodgers committed Oct 15, 2024
1 parent e2e12b0 commit 17daee5
Show file tree
Hide file tree
Showing 15 changed files with 332 additions and 26 deletions.
30 changes: 17 additions & 13 deletions debug/launch/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import { SPDefault, GraphDefault } from "@pnp/nodejs";
import { spfi, SPFI } from "@pnp/sp";
import { GraphFI, graphfi } from "@pnp/graph";
import { LogLevel, PnPLogging } from "@pnp/logging";
import { Queryable } from "@pnp/queryable";
import { Queryable, DebugHeaders } from "@pnp/queryable";

export function spSetup(settings: ITestingSettings): SPFI {

const sp = spfi(settings.testing.sp.url).using(SPDefault({
msal: {
config: settings.testing.sp.msal.init,
scopes: settings.testing.sp.msal.scopes,
},
})).using(
const sp = spfi(settings.testing.sp.url).using(
SPDefault({
msal: {
config: settings.testing.sp.msal.init,
scopes: settings.testing.sp.msal.scopes,
},
}),
PnPLogging(LogLevel.Verbose),
DebugHeaders(),
function (instance: Queryable) {

instance.on.pre(async (url, init, result) => {
Expand All @@ -29,13 +31,15 @@ export function spSetup(settings: ITestingSettings): SPFI {

export function graphSetup(settings: ITestingSettings): GraphFI {

const graph = graphfi().using(GraphDefault({
msal: {
config: settings.testing.graph.msal.init,
scopes: settings.testing.graph.msal.scopes,
},
})).using(
const graph = graphfi().using(
GraphDefault({
msal: {
config: settings.testing.graph.msal.init,
scopes: settings.testing.graph.msal.scopes,
},
}),
PnPLogging(LogLevel.Verbose),
DebugHeaders(),
function (instance: Queryable) {

instance.on.pre(async (url, init, result) => {
Expand Down
3 changes: 3 additions & 0 deletions docs/graph/site-openextensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Site Open Extensions

// TODO
37 changes: 37 additions & 0 deletions docs/queryable/behaviors.md
Original file line number Diff line number Diff line change
Expand Up @@ -491,3 +491,40 @@ setTimeout(() => {
// this is awaiting the results of the request
await p;
```

### DebugHeaders

Adds logging for the request id and timestamp of the request, helpful when contacting Microsoft Support. It works for both Graph and SP libraries.

```TypeScript
import { DebugHeaders } from "@pnp/queryable";
import { spfi } from "@pnp/sp";

const sp = spfi().using(DebugHeaders());

sp.some_action();

// output to log:
// Server Request Id: {guid}
// Server Date: {date}
```

You can also supply additional headers to log from the response:


```TypeScript
import { DebugHeaders } from "@pnp/queryable";
import { spfi } from "@pnp/sp";

const sp = spfi().using(DebugHeaders(["X-MyHeader", "client-request-id"]));

sp.some_action();

// output to log:
// Server Request Id: {guid}
// Server Date: {date}
// X-MyHeader: {value}
// client-request-id: {guid}
```


1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ nav:
- search: 'graph/search.md'
- shares: 'graph/shares.md'
- sites: 'graph/sites.md'
- 'site openextensions': 'graph/site-openextensions.md'
- subscriptions: 'graph/subscriptions.md'
- taxonomy: 'graph/taxonomy.md'
- teams: 'graph/teams.md'
Expand Down
4 changes: 2 additions & 2 deletions packages/graph/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ export function getById<R>(factory: (...args: any[]) => R) {
return function <T extends { new(...args: any[]): {} }>(target: T) {

return class extends target {
public getById(this: IGraphQueryable, id: string): R {
return factory(this, id);
public getById(this: IGraphQueryable, id: any): R {
return factory(this, `${id}`);
}
};
};
Expand Down
15 changes: 5 additions & 10 deletions packages/graph/graphqueryable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,12 @@ export class _GraphQueryable<GetType = any> extends Queryable<GetType> {
*
* @param factory The contructor for the class to create
*/
protected getParent<T extends _GraphQueryable>(
factory: IGraphConstructor<T>,
base: GraphInit = this.parentUrl,
path?: string): T {
protected getParent<T extends IGraphQueryable>(
factory: IGraphInvokableFactory<any>,
path?: string,
base: string = this.parentUrl): T {

if (typeof base === "string") {
// we need to ensure the parent has observers, even if we are rebasing the url (#2435)
base = [this, base];
}

return new factory(base, path);
return factory([this, base], path);
}
}

Expand Down
9 changes: 9 additions & 0 deletions packages/graph/open-extensions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import "./site.js";

export {
IBaseExtensionData as IBaseOpenExtension,
IOpenExtension,
IOpenExtensions,
OpenExtension,
OpenExtensions,
} from "./types.js";
13 changes: 13 additions & 0 deletions packages/graph/open-extensions/site.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { addProp } from "@pnp/queryable";
import { _Site } from "../sites/types.js";
import { IOpenExtensions, OpenExtensions } from "./types.js";

declare module "../sites/types" {
interface _Site {
readonly extensions: IOpenExtensions;
}
interface ISite {
readonly extensions: IOpenExtensions;
}
}
addProp(_Site, "extensions", OpenExtensions);
40 changes: 40 additions & 0 deletions packages/graph/open-extensions/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { body } from "@pnp/queryable";
import { Extension as ExtensionType } from "@microsoft/microsoft-graph-types";
import { _GraphCollection, graphInvokableFactory, graphPatch, graphPost } from "../graphqueryable.js";
import { getById, IGetById, deleteable, IDeleteable, defaultPath } from "../decorators.js";

export interface IBaseExtensionData {
extensionName: string;
}

/**
* Open Extension
*/
@deleteable()
export class _OpenExtension extends _GraphCollection<ExtensionType> {

public update<T extends IBaseExtensionData>(extension: T): Promise<any> {
return graphPatch(this, body(extension));
}
}
export interface IOpenExtension extends _OpenExtension, IDeleteable { }
export const OpenExtension = graphInvokableFactory<IOpenExtension>(_OpenExtension);

/**
* Open Extensions
*/
@defaultPath("extensions")
@getById(OpenExtension)
export class _OpenExtensions extends _GraphCollection<ExtensionType> {

public create<T extends IBaseExtensionData>(extension: T): Promise<any> {

if (extension.extensionName.length > 30) {
throw Error("Extension id length should be less than or equal to 30 characters.");
}

return graphPost(this, body(extension));
}
}
export interface IOpenExtensions extends _OpenExtensions, IGetById<IOpenExtension> { }
export const OpenExtensions = graphInvokableFactory<IOpenExtensions>(_OpenExtensions);
8 changes: 8 additions & 0 deletions packages/graph/pages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import "./site.js";

export {
IPage,
IPages,
Page,
Pages,
} from "./types.js";
14 changes: 14 additions & 0 deletions packages/graph/pages/site.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { addProp } from "@pnp/queryable";
import { _Site } from "../sites/types.js";
import { IPages, Pages } from "./types.js";

declare module "../sites/types" {
interface _Site {
readonly pages: IPages;
}
interface ISite {
readonly pages: IPages;
}
}

addProp(_Site, "pages", Pages);
154 changes: 154 additions & 0 deletions packages/graph/pages/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@

import { combine } from "@pnp/core";
import { IDeleteable, IGetById, IUpdateable, defaultPath, deleteable, getById, updateable } from "../decorators.js";
import { graphInvokableFactory, _GraphCollection, _GraphInstance, GraphInit, graphPost } from "../graphqueryable.js";
import { body } from "@pnp/queryable";

/**
* Page
*/
@deleteable()
@updateable()
export class _Page extends _GraphInstance<IPageInfo> { }
export interface IPage extends _Page, IUpdateable<Partial<IPageInfo>>, IDeleteable { }
export const Page = graphInvokableFactory<IPage>(_Page);

/**
* Pages
*/
@defaultPath("pages")
@getById(Page)
export class _Pages extends _GraphCollection<IPageInfo[]> {
public get sitePages(): ISitePages {
return SitePages(this);
}
}
export interface IPages extends _Pages, IGetById<IPage> { }
export const Pages = graphInvokableFactory<IPages>(_Pages);

/**
* Site Page
*/
@deleteable()
@updateable()
export class _SitePage extends _GraphInstance<ISitePageInfo> {

/**
* Publishes the page
* @returns void
*/
public async publish(): Promise<void> {
return graphPost(SitePage(this, "publish"));
}

/**
* Gets the webparts in the page
*
* @returns array fo webpart information
*/
public async getWebPartsByPosition(): Promise<any> {
return SitePage(this, "getWebPartsByPosition")();
}

/**
* Gets the set of horizontal sections
*/
public get horizontalSections(): IHorizontalSections {
return HorizontalSections(this);
}
}
export interface ISitePage extends _SitePage, IUpdateable<Partial<ISitePageInfo>>, IDeleteable { }
export const SitePage = graphInvokableFactory<ISitePage>(_SitePage);

const SitePageTypeString = "microsoft.graph.sitePage";

/**
* Site Pages
*/
@defaultPath(SitePageTypeString)
export class _SitePages extends _GraphCollection<ISitePageInfo[]> {

private _pages: IPages;

constructor(base: GraphInit, path?: string) {
super(base, path);
this._pages = this.getParent<IPages>(Pages, "");
}

public getById(this: ISitePages, id: string): ISitePage {
return SitePage(this._pages, combine(id, SitePageTypeString));
}

public async add(pageInfo: Partial<Omit<ISitePageInfo, "@odata.type">>): Promise<ISitePageInfo> {
return graphPost(this._pages, body({ "@odata.type": SitePageTypeString, ...pageInfo }));
}
}
export interface ISitePages extends _SitePages { }
export const SitePages = graphInvokableFactory<ISitePages>(_SitePages);

export class _HorizontalSection extends _GraphInstance<IHorizontalSectionInfo> {}
export interface IHorizontalSection extends _HorizontalSection { }
export const HorizontalSection = graphInvokableFactory<IHorizontalSection>(_HorizontalSection);

@getById(HorizontalSection)
@defaultPath("canvasLayout/horizontalSections")
export class _HorizontalSections extends _GraphCollection<IHorizontalSectionInfo[]> {

public async add(props: Partial<IHorizontalSectionInfo>): Promise<IHorizontalSectionInfo> {
return graphPost(this, body(props));
}
}
export interface IHorizontalSections extends _HorizontalSections, IGetById<IHorizontalSection, number> { }
export const HorizontalSections = graphInvokableFactory<IHorizontalSections>(_HorizontalSections);







export interface IHorizontalSectionInfo {
emphasis: "none" | "netural" | "soft" | "strong" | "unknownFutureValue";
id: string;
layout: "none" | "oneColumn" | "twoColumns" | "threeColumns" | "oneThirdLeftColumn" | "oneThirdRightColumn" | "fullWidth" | "unknownFutureValue";
columns: IHorizontalSectionColumnInfo[];
}

export interface IHorizontalSectionColumnInfo {
id: string;
width: string;
webparts: any[];
}


export interface IPageUserInfo {
displayName: string;
email?: string;
}

export interface ISitePageInfo extends IPageInfo { }

export interface IPageInfo {
"@odata.type"?: string;
"@odata.etag"?: string;
contentType: {
id: string;
name: string;
};
createdDateTime: string;
eTag: string;
id: string;
createdBy: { user: IPageUserInfo };
lastModifiedBy: { user: IPageUserInfo };
lastModifiedDateTime: string;
name: string;
pageLayout: string;
parentReference: { siteId: string };
promotionKind: string;
publishingState: { level: string; versionId: string };
reactions: any;
showComments: boolean;
showRecommendedPages: boolean;
title: string;
webUrl: string;
}
Loading

0 comments on commit 17daee5

Please sign in to comment.