Skip to content

Commit

Permalink
V4 release WIP
Browse files Browse the repository at this point in the history
Working on tests fixes
Added Azure Function sample - ready for v4 release
Added updates (still WIP) for getting started docs
  • Loading branch information
Julie Turner committed Apr 15, 2024
1 parent 48afbb7 commit 65d6106
Show file tree
Hide file tree
Showing 20 changed files with 832 additions and 272 deletions.
379 changes: 211 additions & 168 deletions docs/getting-started.md

Large diffs are not rendered by default.

19 changes: 15 additions & 4 deletions packages/logging/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
export * from "./listeners.js";
/**
* A set of logging levels
*/
export var LogLevel;
(function (LogLevel) {
LogLevel[LogLevel["Verbose"] = 0] = "Verbose";
LogLevel[LogLevel["Info"] = 1] = "Info";
LogLevel[LogLevel["Warning"] = 2] = "Warning";
LogLevel[LogLevel["Error"] = 3] = "Error";
LogLevel[LogLevel["Off"] = 99] = "Off";
})(LogLevel || (LogLevel = {}));
const _subscribers = [];
let _activeLogLevel = 2 /* Warning */;
let _activeLogLevel = LogLevel.Warning;
/**
* Class used to subscribe ILogListener and log messages throughout an application
*
Expand Down Expand Up @@ -43,7 +54,7 @@ export class Logger {
* @param message The message to write
* @param level [Optional] if supplied will be used as the level of the entry (Default: LogLevel.Info)
*/
static write(message, level = 1 /* Info */) {
static write(message, level = LogLevel.Info) {
Logger.log({ level: level, message: message });
}
/**
Expand All @@ -52,7 +63,7 @@ export class Logger {
* @param json The json object to stringify and write
* @param level [Optional] if supplied will be used as the level of the entry (Default: LogLevel.Info)
*/
static writeJSON(json, level = 1 /* Info */) {
static writeJSON(json, level = LogLevel.Info) {
Logger.write(JSON.stringify(json), level);
}
/**
Expand All @@ -71,7 +82,7 @@ export class Logger {
* @param err The error object
*/
static error(err) {
Logger.log({ data: err, level: 3 /* Error */, message: err.message });
Logger.log({ data: err, level: LogLevel.Error, message: err.message });
}
}
export function PnPLogging(activeLevel) {
Expand Down
10 changes: 6 additions & 4 deletions packages/logging/listeners.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable no-console */
import { LogLevel } from "./index.js";
export function ConsoleListener(prefix, colors) {
return new _ConsoleListener(prefix, colors);
}
Expand Down Expand Up @@ -55,16 +57,16 @@ class _ConsoleListener {
log(entry) {
let logMethod = console.log;
switch (entry.level) {
case 3 /* Error */:
case LogLevel.Error:
logMethod = console.error;
break;
case 2 /* Warning */:
case LogLevel.Warning:
logMethod = console.warn;
break;
case 0 /* Verbose */:
case LogLevel.Verbose:
logMethod = console.debug;
break;
case 1 /* Info */:
case LogLevel.Info:
logMethod = console.info;
break;
default:
Expand Down
10 changes: 10 additions & 0 deletions samples/azure-function/.funcignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
*.js.map
*.ts
.git*
.vscode
__azurite_db*__.json
__blobstorage__
__queuestorage__
local.settings.json
test
tsconfig.json
99 changes: 99 additions & 0 deletions samples/azure-function/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TypeScript output
dist
out

# Azure Functions artifacts
bin
obj
appsettings.json
local.settings.json

# Azurite artifacts
__blobstorage__
__queuestorage__
__azurite_db*__.json
5 changes: 5 additions & 0 deletions samples/azure-function/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"ms-azuretools.vscode-azurefunctions"
]
}
12 changes: 12 additions & 0 deletions samples/azure-function/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Node Functions",
"type": "node",
"request": "attach",
"port": 9229,
"preLaunchTask": "func: host start"
}
]
}
13 changes: 13 additions & 0 deletions samples/azure-function/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"azureFunctions.deploySubpath": ".",
"azureFunctions.postDeployTask": "npm install (functions)",
"azureFunctions.projectLanguage": "TypeScript",
"azureFunctions.projectRuntime": "~4",
"debug.internalConsoleOptions": "neverOpen",
"azureFunctions.projectLanguageModel": 4,
"azureFunctions.preDeployTask": "npm prune (functions)",
"cSpell.words": [
"Entra"
],
"azureFunctions.templateFilter": "Verified"
}
38 changes: 38 additions & 0 deletions samples/azure-function/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "func",
"label": "func: host start",
"command": "host start",
"problemMatcher": "$func-node-watch",
"isBackground": true,
"dependsOn": "npm build (functions)"
},
{
"type": "shell",
"label": "npm build (functions)",
"command": "npm run build",
"dependsOn": "npm clean (functions)",
"problemMatcher": "$tsc"
},
{
"type": "shell",
"label": "npm install (functions)",
"command": "npm install"
},
{
"type": "shell",
"label": "npm prune (functions)",
"command": "npm prune --production",
"dependsOn": "npm build (functions)",
"problemMatcher": []
},
{
"type": "shell",
"label": "npm clean (functions)",
"command": "npm run clean",
"dependsOn": "npm install (functions)"
}
]
}
51 changes: 51 additions & 0 deletions samples/azure-function/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# PnPjs - Azure Function v4 Support

This sample project demonstrates how to use the PnPjs SDK inside of an Azure Function v4 with Application Insights, one of the most common scenarios when building extensibility solutions for Microsoft 365.

By default Azure Functions are configured to use Node.js CommonJS modules. However, PnPjs only supports ESModules. This sample shows you how to reconfigure your solution so that you can use ESModules and import any other CommonJS modules that you have as dependencies.

## List of changes

- tsconfig.json: [Intro to TSConfig Reference](https://www.typescriptlang.org/tsconfig)
- "module": "ESNext"
- "target": "ESNext"
- "moduleResolution": "Node"
- "allowSyntheticDefaultImports": true

- package.json
- "type": "module"

## Importing CommonJS packages

With these settings updated we can now import our CommonJS packages by using

`import AppInsights from 'applicationinsights';`

instead of

`let appInsights = require('applicationinsights');`

## Azure Identity

Azure Identity is an SDK that provides Microsoft Entra ID (formerly Azure Active Directory - Azure AD) token authentication through a set of convenient TokenCredential implementations. [More information](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/README.md)

This sample implements PnPjs security expecting Managed Identity has been configured for the Azure Function.

> We find the [CLI for Microsoft 365](https://pnp.github.io/cli-microsoft365/) - [entra approleassignment add](https://pnp.github.io/cli-microsoft365/cmd/entra/approleassignment/approleassignment-add) especially handy for assigning the permissions necessary to your Azure Functions' system-managed identity.
When in local development mode you can log into Azure by including the Azure Account extension for Visual Studio Code, or preferably you can configure 3 additional settings in your [local.settings.json](./local.settings.example.json) file to point to an Entra ID App Registration in your development tenant using Certificate authentication.

```JSON
"AZURE_CLIENT_ID": "99999999-9999-9999-9999-999999999999",
"AZURE_TENANT_ID": "99999999-9999-9999-9999-999999999999",
// path to .pem file that is the companion the app registration certificate.
"AZURE_CLIENT_CERTIFICATE_PATH":"c:\\cert.pem"
```

See the more information link above for other supported authentication scenarios like Client Secret and Certificate. Be aware many SharePoint endpoint do not support Client Secret authentication.

## Application Insights

Azure Application Insights monitors your backend services and components after you deploy them to help you discover and rapidly diagnose performance and other issues. Add this SDK to your Node.js services to include deep info about Node.js processes and their external dependencies such as database and cache services. You can use this SDK for your Node.js services hosted anywhere: your datacenter, Azure VMs and Web Apps, and even other public clouds.

To get [more information](https://github.com/microsoft/ApplicationInsights-node.js#readme) on Application Insights.
15 changes: 15 additions & 0 deletions samples/azure-function/host.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[3.15.0, 4.0.0)"
}
}
17 changes: 17 additions & 0 deletions samples/azure-function/local.settings.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "node",
"AzureWebJobsFeatureFlags": "EnableWorkerIndexing",
"APPLICATIONINSIGHTS_CONNECTION_STRING": "",
"SiteUrl": "https://contoso.sharepoint.com/sites/pnpjs",
"Tenant": "contoso",
"ListGUID": "99999999-9999-9999-9999-999999999999",
// Next 3 setting are only for local Azure Identity debugging
"AZURE_CLIENT_ID": "99999999-9999-9999-9999-999999999999",
"AZURE_TENANT_ID": "99999999-9999-9999-9999-999999999999",
// path to .pem file
"AZURE_CLIENT_CERTIFICATE_PATH":"c:\\cert.pem"
}
}
28 changes: 28 additions & 0 deletions samples/azure-function/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "azfuncnode",
"version": "1.0.0",
"description": "",
"type": "module",
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"clean": "rimraf dist",
"prestart": "npm run clean && npm run build",
"start": "func start",
"test": "echo \"No tests yet...\""
},
"dependencies": {
"@azure/functions": "4.4.0",
"@pnp/azidjsclient": "4.0.0",
"@pnp/graph": "4.0.0",
"@pnp/nodejs": "4.0.0",
"@pnp/sp": "4.0.0",
"applicationinsights": "2.9.5"
},
"devDependencies": {
"@types/node": "^18.x",
"typescript": "^5.0.0",
"rimraf": "^5.0.0"
},
"main": "dist/src/functions/*.js"
}
5 changes: 5 additions & 0 deletions samples/azure-function/src/common/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface MyItem {
Id: string;
Title: string;
Description: string;
}
Loading

0 comments on commit 65d6106

Please sign in to comment.