Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
estruyf committed Dec 11, 2020
0 parents commit 56c0cec
Show file tree
Hide file tree
Showing 18 changed files with 6,055 additions and 0 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# This is a basic workflow to help you get started with Actions
name: Publish to NPM

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
push:
branches:
- main
- dev

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/[email protected]
with:
node-version: 12.15
registry-url: https://registry.npmjs.org/

- name: Install npm dependencies
run: npm i

- name: Run build
run: npm start

- name: Publish release
run: npm publish --access public
if: github.ref == 'refs/heads/master'
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

- name: Update the package version
if: github.ref == 'refs/heads/dev'
run: node scripts/update-package-version.js $GITHUB_RUN_ID

- name: Publish beta release
run: npm publish --tag next --access public
if: github.ref == 'refs/heads/dev'
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
7 changes: 7 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
src
.gitignore
.github
.vscode
scripts
tsconfig.json
4 changes: 4 additions & 0 deletions bin/doctor
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env node

require = require('esm')(module /*, options*/);
require('../dist/cli').cli(process.argv);
5,110 changes: 5,110 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@valo/doctor",
"version": "1.0.0",
"description": "The static site generator for SharePoint",
"main": "index.js",
"bin": {
"doctor": "bin/doctor"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"start": "npm run build",
"build": "npm run clean && tsc",
"watch": "tsc -w",
"clean": "rm -rf dist"
},
"keywords": [
"cli",
"markdown",
"documentation"
],
"author": "Elio Struyf",
"license": "MIT",
"devDependencies": {
"@types/inquirer": "7.3.1",
"@types/jsdom": "16.2.5",
"@types/listr": "0.14.2",
"@types/mime": "2.0.3",
"@types/showdown": "1.9.3"
},
"dependencies": {
"@pnp/cli-microsoft365": "3.3.0",
"arg": "4.1.3",
"esm": "3.2.25",
"fast-glob": "3.2.4",
"frontmatter": "0.0.3",
"inquirer": "7.3.3",
"jsdom": "16.4.0",
"kleur": "4.1.3",
"listr": "0.14.3",
"mime": "2.4.6",
"rxjs": "6.6.3",
"showdown": "1.9.1",
"tslib": "2.0.3",
"typescript": "4.0.5"
}
}
33 changes: 33 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Doctor (The static site generator for SharePoint)

`Doctor` is a tool created and provided by Valo. Initially, we started `doctor` as an internal tool to dogfood our products and keep documentation in one place. For our team, this is SharePoint.

As we understand that it is not the best experience for developers to write documentation on SharePoint, we created this tool to simplify the process. `Doctor` allows developers to use tools/applications they are used to, like VSCode and Markdown, and still provide the information on your SharePoint environment.

`Doctor` follows the concept of many Static Site Generators. These generators make it possible to write your articles/documentation in Markdown and convert them to HTML files.

`Doctor` is a bit different, as instead of creating HTML files, it makes SharePoint pages instead.

Under the hood, it makes use of the [CLI for Microsoft 365](https://pnp.github.io/cli-microsoft365/).

## Installation



## Settings

`config.json`

```json
{
"folder": "./src",
"url": "https://estruyfdev2.sharepoint.com/sites/StaticPages",
...
}
```

> **Info**: you can provide the same flags and values like in the parameters. Parameters can override what is defined in the `config.json`.
## Parameters

`--`
6 changes: 6 additions & 0 deletions scripts/update-package-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const fs = require('fs');
const path = require('path');
const packageJson = require('../package.json');
packageJson.version += `-beta.${process.argv[process.argv.length-1].substr(0, 7)}`;
console.log(packageJson.version);
fs.writeFileSync(path.join(path.resolve('.'), 'package.json'), JSON.stringify(packageJson, null, 2));
14 changes: 14 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import kleur = require("kleur");
import { OptionsHelper } from "./helpers/OptionsHelper";
import { Commands } from "./main";

export async function cli(args: string[]) {
let options = OptionsHelper.fetchConfig();
options = OptionsHelper.parseArguments(options, args);
options = await OptionsHelper.promptForMissingArgs(options);
try {
await Commands.start(options);
} catch (e) {
console.log(kleur.bgRed().bold().white(` ERROR: `), kleur.bold().red(e.message));
}
}
54 changes: 54 additions & 0 deletions src/helpers/FileHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as path from 'path';
import { execScript } from "./execScript";


export class FileHelpers {
private static checkedFiles: string[] = [];

/**
* Retrieve the relative path for the file
* @param webUrl
* @param library
* @param filePath
*/
public static getRelUrl(webUrl: string, filePath: string) {
const relWebUrl = webUrl.split('sharepoint.com').pop();
return `${ relWebUrl.startsWith('/') ? '' : '/' }${ relWebUrl }${ relWebUrl.endsWith('/') ? '' : '/' }${filePath}`;
}

/**
* Create the file on SharePoint
* @param crntFolder
* @param imgPath
* @param webUrl
* @param override
*/
public static async create(crntFolder: string, imgPath: string, webUrl: string, override: boolean = false) {
if (this.checkedFiles.indexOf(imgPath) === -1) {
if (override) {
await this.upload(webUrl, crntFolder, imgPath);
} else {
try {
// Check if file exists
const filePath = `${crntFolder}/${path.basename(imgPath)}`;
const relativeUrl = this.getRelUrl(webUrl, filePath);
await execScript(`m365`, [`spo`, `file`, `get`, `--webUrl`, `"${webUrl}"`, `--url`, `"${relativeUrl}"`]);
} catch (e) {
await this.upload(webUrl, crntFolder, imgPath);
}
}

this.checkedFiles.push(imgPath);
}
}

/**
* Upload the file
* @param webUrl
* @param crntFolder
* @param imgPath
*/
private static async upload(webUrl: string, crntFolder: string, imgPath: string) {
await execScript(`m365`, [`spo`, `file`, `add`, `--webUrl`, `"${webUrl}"`, `--folder`, `'${crntFolder}'`, `--path`, `'${imgPath}'`]);
}
}
32 changes: 32 additions & 0 deletions src/helpers/FolderHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { execScript } from "./execScript";


export class FolderHelpers {
private static checkedFolders: string[] = [];

public static async create(crntFolder: string, folders: string[], webUrl: string) {
for (const folder of folders) {
// Check if folder exists
const folderToProcess = `/${crntFolder}/${folder}`
if (folder) {
if (this.checkedFolders.indexOf(folderToProcess) === -1) {
try {
const scriptData: any = await execScript(`m365`, [`spo`, `folder`, `get`, `--webUrl`, `'${webUrl}'`, `--folderUrl`, `'${folderToProcess}'`, `-o`, `json`, `|`, `jq`]);

if (!scriptData && !scriptData.Exists) {
throw "Folder doesn't seem to exist yet";
}
} catch (e) {
await execScript(`m365`, [`spo`, `folder`, `add`, `--webUrl`, `'${webUrl}'`, `--parentFolderUrl`, `'/${crntFolder}'`, `--name`, `'${folder}'`]);
}

this.checkedFolders.push(folderToProcess);
}

crntFolder = `${crntFolder}/${folder}`
}
}

return crntFolder;
}
}
Loading

0 comments on commit 56c0cec

Please sign in to comment.