Skip to content

Commit

Permalink
Merge pull request #2747 from patrick-rodgers/version-4
Browse files Browse the repository at this point in the history
Version 4
  • Loading branch information
patrick-rodgers committed Jul 26, 2023
2 parents 30eae0e + 2078dd9 commit 50fe177
Show file tree
Hide file tree
Showing 40 changed files with 348 additions and 364 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,30 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Added

- graph
- explict error thrown if SPFx context is null or undefined when needed

- sp
- explict error thrown if SPFx context is null or undefined when needed

### Removed

- graph
- paged method removed from IGraphQueryableCollection

- sp
- getPaged method removed from _Items/IItems
- PagedItemCollection removed from library
- removed /items/get-all import, unneeded, use async iterator patterns

### Changed

- graph
- IGraphQueryableCollection now supports async iterator pattern
- IGraphQueryableCollection count method now returns -1 if the collection does not support counting
- All GraphQueryable*, _GraphQueryable*, and IGraphQueryable* have been renamed to remove "Queryable" (ex: GraphQueryableCollection is now GraphCollection)

- sp
- _Items and IItems now supports async iterator pattern


2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@pnp/monorepo",
"private": true,
"type": "module",
"version": "3.17.0",
"version": "4.0.0-alpha0",
"description": "A JavaScript library for SharePoint & Graph development.",
"devDependencies": {
"@azure/identity": "3.2.4",
Expand Down
6 changes: 3 additions & 3 deletions packages/graph/attachments/types.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Attachment as IAttachmentType } from "@microsoft/microsoft-graph-types";
import { body } from "@pnp/queryable";
import { _GraphQueryableCollection, _GraphQueryableInstance, graphInvokableFactory } from "../graphqueryable.js";
import { _GraphCollection, _GraphInstance, graphInvokableFactory } from "../graphqueryable.js";
import { graphPost } from "../operations.js";
import { defaultPath, getById, IGetById } from "../decorators.js";
import { type } from "../utils/type.js";

/**
* Attachment
*/
export class _Attachment extends _GraphQueryableInstance<IAttachmentType> { }
export class _Attachment extends _GraphInstance<IAttachmentType> { }
export interface IAttachment extends _Attachment { }
export const Attachment = graphInvokableFactory<IAttachment>(_Attachment);

Expand All @@ -17,7 +17,7 @@ export const Attachment = graphInvokableFactory<IAttachment>(_Attachment);
*/
@defaultPath("attachments")
@getById(Attachment)
export class _Attachments extends _GraphQueryableCollection<IAttachmentType[]> {
export class _Attachments extends _GraphCollection<IAttachmentType[]> {

/**
* Add attachment to this collection
Expand Down
55 changes: 4 additions & 51 deletions packages/graph/behaviors/paged.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { hOP, objectDefinedNotNull, stringIsNullOrEmpty, TimelinePipe } from "@pnp/core";
import { hOP, stringIsNullOrEmpty, TimelinePipe } from "@pnp/core";
import { errorCheck, parseODataJSON } from "@pnp/queryable";
import { GraphQueryableCollection, IGraphQueryable, IGraphQueryableCollection } from "../graphqueryable.js";
import { GraphCollection, IGraphQueryable, IGraphCollection } from "../graphqueryable.js";
import { ConsistencyLevel } from "./consistency-level.js";

export interface IPagedResult {
Expand All @@ -17,63 +17,16 @@ export interface IPagedResult {
* @param col The collection to count
* @returns number representing the count
*/
export async function Count<T>(col: IGraphQueryableCollection<T>): Promise<number> {
export async function Count<T>(col: IGraphCollection<T>): Promise<number> {

const q = GraphQueryableCollection(col).using(Paged(), ConsistencyLevel());
const q = GraphCollection(col).using(Paged(), ConsistencyLevel());
q.query.set("$count", "true");
q.top(1);

const y: IPagedResult = await q();
return y.count;
}

/**
* Configures a collection query to returned paged results via async iteration
*
* @param col Collection forming the basis of the paged collection, this param is NOT modified
* @returns A duplicate collection which will return paged results
*/
export function AsAsyncIterable<T>(col: IGraphQueryableCollection<T>): AsyncIterable<T> {

const q = GraphQueryableCollection(col).using(Paged(), ConsistencyLevel());

const queryParams = ["$search", "$top", "$select", "$expand", "$filter", "$orderby"];

for (let i = 0; i < queryParams.length; i++) {
const param = col.query.get(queryParams[i]);
if (objectDefinedNotNull(param)) {
q.query.set(queryParams[i], param);
}
}

return {

[Symbol.asyncIterator]() {
return <AsyncIterator<T>>{

_next: q,

async next() {

if (this._next === null) {
return { done: true, value: undefined };
}

const result: IPagedResult = await this._next();

if (result.hasNext) {
this._next = GraphQueryableCollection([this._next, result.nextLink]);
return { done: false, value: result.value };
} else {
this._next = null;
return { done: false, value: result.value };
}
},
};
},
};
}

/**
* Behavior that converts results to pages when used with a collection (exposed through the paged method of GraphCollection)
*
Expand Down
17 changes: 17 additions & 0 deletions packages/graph/behaviors/spfx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,23 @@ interface ISPFXContext {
};
}

class SPFxTokenNullOrUndefinedError extends Error {

constructor(behaviorName: string) {
super(`SPFx Context supplied to ${behaviorName} Behavior is null or undefined.`);
}

public static check(behaviorName: string, context?: ISPFXContext): void {
if (typeof context === "undefined" || context === null) {
throw new SPFxTokenNullOrUndefinedError(behaviorName);
}
}
}

export function SPFxToken(context: ISPFXContext): TimelinePipe<Queryable> {

SPFxTokenNullOrUndefinedError.check("SPFxToken");

return (instance: Queryable) => {

instance.on.auth.replace(async function (url: URL, init: RequestInit) {
Expand All @@ -32,6 +47,8 @@ export function SPFxToken(context: ISPFXContext): TimelinePipe<Queryable> {

export function SPFx(context: ISPFXContext): TimelinePipe<Queryable> {

SPFxTokenNullOrUndefinedError.check("SPFx");

return (instance: Queryable) => {

instance.using(
Expand Down
6 changes: 3 additions & 3 deletions packages/graph/bookings/funcs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

import { IGraphQueryable, GraphQueryableCollection, IGraphQueryableCollection } from "../graphqueryable.js";
import { IGraphQueryable, GraphCollection, IGraphCollection } from "../graphqueryable.js";
import { BookingAppointment as IBookingAppointmentEntity } from "@microsoft/microsoft-graph-types";

/**
Expand All @@ -9,9 +9,9 @@ import { BookingAppointment as IBookingAppointmentEntity } from "@microsoft/micr
* @param start start time
* @param end end time
*/
export function calendarView(this: IGraphQueryable, start: string, end: string): IGraphQueryableCollection<IBookingAppointmentEntity[]> {
export function calendarView(this: IGraphQueryable, start: string, end: string): IGraphCollection<IBookingAppointmentEntity[]> {

const query = GraphQueryableCollection(this, "calendarView");
const query = GraphCollection(this, "calendarView");
query.query.set("startDateTime", start);
query.query.set("endDateTime", end);
return query;
Expand Down
30 changes: 15 additions & 15 deletions packages/graph/bookings/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
BookingCurrency as IBookingCurrencyEntity,
BookingCustomQuestion as IBookingCustomQuestionEntity,
} from "@microsoft/microsoft-graph-types";
import { _GraphQueryableCollection, graphInvokableFactory, _GraphQueryableInstance } from "../graphqueryable.js";
import { _GraphCollection, graphInvokableFactory, _GraphInstance } from "../graphqueryable.js";
import { defaultPath, deleteable, IDeleteable, updateable, IUpdateable, getById, IGetById } from "../decorators.js";
import { graphPost } from "../operations.js";
import { body } from "@pnp/queryable";
Expand All @@ -17,7 +17,7 @@ import { calendarView } from "./funcs.js";
* Describes a Booking Currency entity
*
*/
export class _BookingCurrency extends _GraphQueryableInstance<IBookingCurrencyEntity> { }
export class _BookingCurrency extends _GraphInstance<IBookingCurrencyEntity> { }
export interface IBookingCurrency extends _BookingCurrency { }
export const BookingCurrency = graphInvokableFactory<IBookingCurrency>(_BookingCurrency);

Expand All @@ -27,7 +27,7 @@ export const BookingCurrency = graphInvokableFactory<IBookingCurrency>(_BookingC
*/
@defaultPath("solutions/bookingCurrencies")
@getById(BookingCurrency)
export class _BookingCurrencies extends _GraphQueryableCollection<IBookingCurrencyEntity[]>{ }
export class _BookingCurrencies extends _GraphCollection<IBookingCurrencyEntity[]>{ }
export interface IBookingCurrencies extends _BookingCurrencies, IGetById<IBookingCurrency> { }
export const BookingCurrencies = graphInvokableFactory<IBookingCurrencies>(_BookingCurrencies);

Expand All @@ -36,7 +36,7 @@ export const BookingCurrencies = graphInvokableFactory<IBookingCurrencies>(_Book
*/
@deleteable()
@updateable()
export class _BookingBusiness extends _GraphQueryableInstance<IBookingBusinessEntity> {
export class _BookingBusiness extends _GraphInstance<IBookingBusinessEntity> {
/**
* Get the calendar view for the booking business.
*/
Expand Down Expand Up @@ -99,7 +99,7 @@ export const BookingBusiness = graphInvokableFactory<IBookingBusiness>(_BookingB
*/
@defaultPath("solutions/bookingBusinesses")
@getById(BookingBusiness)
export class _BookingBusinesses extends _GraphQueryableCollection<IBookingBusinessEntity[]>{
export class _BookingBusinesses extends _GraphCollection<IBookingBusinessEntity[]>{
/**
* Create a new booking business as specified in the request body.
*
Expand Down Expand Up @@ -130,7 +130,7 @@ export const BookingBusinesses = graphInvokableFactory<IBookingBusinesses>(_Book
*/
@deleteable()
@updateable()
export class _BookingApointment extends _GraphQueryableInstance<IBookingAppointmentEntity> {
export class _BookingApointment extends _GraphInstance<IBookingAppointmentEntity> {
/**
* Cancel the specified bookingAppointment in the specified bookingBusiness and send a message to the involved customer and staff members.
*/
Expand All @@ -148,7 +148,7 @@ export const BookingAppointment = graphInvokableFactory<IBookingAppointment>(_Bo
*/
@defaultPath("appointments")
@getById(BookingAppointment)
export class _BookingAppointments extends _GraphQueryableCollection<IBookingAppointmentEntity[]>{
export class _BookingAppointments extends _GraphCollection<IBookingAppointmentEntity[]>{
/**
* Create a new booking appointment as specified in the request body.
*
Expand All @@ -172,7 +172,7 @@ export const BookingAppointments = graphInvokableFactory<IBookingAppointments>(_
*/
@deleteable()
@updateable()
export class _BookingCustomer extends _GraphQueryableInstance<IBookingCustomerEntity> { }
export class _BookingCustomer extends _GraphInstance<IBookingCustomerEntity> { }
export interface IBookingCustomer extends _BookingCustomer, IDeleteable, IUpdateable { }
export const BookingCustomer = graphInvokableFactory<IBookingCustomer>(_BookingCustomer);

Expand All @@ -182,7 +182,7 @@ export const BookingCustomer = graphInvokableFactory<IBookingCustomer>(_BookingC
*/
@defaultPath("customers")
@getById(BookingCustomer)
export class _BookingCustomers extends _GraphQueryableCollection<IBookingCustomerEntity[]>{
export class _BookingCustomers extends _GraphCollection<IBookingCustomerEntity[]>{
/**
* Create a new booking customer as specified in the request body.
*
Expand All @@ -206,7 +206,7 @@ export const BookingCustomers = graphInvokableFactory<IBookingCustomers>(_Bookin
*/
@deleteable()
@updateable()
export class _BookingService extends _GraphQueryableInstance<IBookingServiceEntity> { }
export class _BookingService extends _GraphInstance<IBookingServiceEntity> { }
export interface IBookingService extends _BookingService, IDeleteable, IUpdateable { }
export const BookingService = graphInvokableFactory<IBookingService>(_BookingService);

Expand All @@ -216,7 +216,7 @@ export const BookingService = graphInvokableFactory<IBookingService>(_BookingSer
*/
@defaultPath("services")
@getById(BookingService)
export class _BookingServices extends _GraphQueryableCollection<IBookingServiceEntity[]>{
export class _BookingServices extends _GraphCollection<IBookingServiceEntity[]>{
/**
* Create a new booking service as specified in the request body.
*
Expand All @@ -240,7 +240,7 @@ export const BookingServices = graphInvokableFactory<IBookingServices>(_BookingS
*/
@deleteable()
@updateable()
export class _BookingStaffMember extends _GraphQueryableInstance<IBookingStaffMemberEntity> { }
export class _BookingStaffMember extends _GraphInstance<IBookingStaffMemberEntity> { }
export interface IBookingStaffMember extends _BookingStaffMember, IDeleteable, IUpdateable { }
export const BookingStaffMember = graphInvokableFactory<IBookingStaffMember>(_BookingStaffMember);

Expand All @@ -250,7 +250,7 @@ export const BookingStaffMember = graphInvokableFactory<IBookingStaffMember>(_Bo
*/
@defaultPath("staffMembers")
@getById(BookingStaffMember)
export class _BookingStaffMembers extends _GraphQueryableCollection<IBookingStaffMemberEntity[]>{
export class _BookingStaffMembers extends _GraphCollection<IBookingStaffMemberEntity[]>{
/**
* Create a new booking staffmember as specified in the request body.
*
Expand All @@ -274,7 +274,7 @@ export const BookingStaffMembers = graphInvokableFactory<IBookingStaffMembers>(_
*/
@deleteable()
@updateable()
export class _BookingCustomQuestion extends _GraphQueryableInstance<IBookingCustomQuestionEntity> { }
export class _BookingCustomQuestion extends _GraphInstance<IBookingCustomQuestionEntity> { }
export interface IBookingCustomQuestion extends _BookingCustomQuestion, IDeleteable, IUpdateable { }
export const BookingCustomQuestion = graphInvokableFactory<IBookingCustomQuestion>(_BookingCustomQuestion);

Expand All @@ -284,7 +284,7 @@ export const BookingCustomQuestion = graphInvokableFactory<IBookingCustomQuestio
*/
@defaultPath("customquestions")
@getById(BookingCustomQuestion)
export class _BookingCustomQuestions extends _GraphQueryableCollection<IBookingCustomQuestionEntity[]>{
export class _BookingCustomQuestions extends _GraphCollection<IBookingCustomQuestionEntity[]>{
/**
* Create a new booking customquestions as specified in the request body.
*
Expand Down
14 changes: 7 additions & 7 deletions packages/graph/calendars/funcs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IGraphQueryable, GraphQueryableCollection, IGraphQueryableCollection } from "../graphqueryable.js";
import { IGraphQueryable, GraphCollection, IGraphCollection } from "../graphqueryable.js";
import { EmailAddress, Event as IEvent } from "@microsoft/microsoft-graph-types";
import { Endpoint } from "../behaviors/endpoint.js";

Expand All @@ -14,9 +14,9 @@ interface IEventWithTag extends IEvent {
* @param start start time
* @param end end time
*/
export function calendarView(this: IGraphQueryable, start: string, end: string): IGraphQueryableCollection<ICalendarViewInfo[]> {
export function calendarView(this: IGraphQueryable, start: string, end: string): IGraphCollection<ICalendarViewInfo[]> {

const query = GraphQueryableCollection(this, "calendarView");
const query = GraphCollection(this, "calendarView");
query.query.set("startDateTime", start);
query.query.set("endDateTime", end);
return query;
Expand All @@ -31,8 +31,8 @@ export type ICalendarViewInfo = IEventWithTag;
* @param this IGraphQueryable instance
* @param roomList The SMTP address associated with the room list.
*/
export function findRooms(this: IGraphQueryable, roomList?: string): IGraphQueryableCollection<EmailAddress[]> {
const query = GraphQueryableCollection(this, roomList ? "findRooms(RoomList=@roomList)" : "findRooms");
export function findRooms(this: IGraphQueryable, roomList?: string): IGraphCollection<EmailAddress[]> {
const query = GraphCollection(this, roomList ? "findRooms(RoomList=@roomList)" : "findRooms");
query.using(Endpoint("beta"));
if (roomList) {
query.query.set("@roomList", `'${roomList}'`);
Expand All @@ -48,8 +48,8 @@ export function findRooms(this: IGraphQueryable, roomList?: string): IGraphQuery
* @param start start time
* @param end end time
*/
export function instances(this: IGraphQueryable, start: string, end: string): IGraphQueryableCollection<IInstance[]> {
const query = GraphQueryableCollection(this, "instances");
export function instances(this: IGraphQueryable, start: string, end: string): IGraphCollection<IInstance[]> {
const query = GraphCollection(this, "instances");
query.query.set("startDateTime", start);
query.query.set("endDateTime", end);
return query;
Expand Down
Loading

0 comments on commit 50fe177

Please sign in to comment.