{"id":20859000,"url":"https://github.com/s-kainet/gulp-spsave","last_synced_at":"2025-06-18T13:38:25.349Z","repository":{"id":36495763,"uuid":"40801393","full_name":"s-KaiNet/gulp-spsave","owner":"s-KaiNet","description":"Gulp plugin for saving files inside SharePoint","archived":false,"fork":false,"pushed_at":"2020-07-27T11:43:35.000Z","size":270,"stargazers_count":51,"open_issues_count":2,"forks_count":8,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-06-17T23:38:40.238Z","etag":null,"topics":["gulp","javascript","sharepoint","typescript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/s-KaiNet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-16T06:27:41.000Z","updated_at":"2024-11-16T00:22:25.000Z","dependencies_parsed_at":"2022-09-10T23:40:49.701Z","dependency_job_id":null,"html_url":"https://github.com/s-KaiNet/gulp-spsave","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/s-KaiNet/gulp-spsave","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-KaiNet%2Fgulp-spsave","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-KaiNet%2Fgulp-spsave/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-KaiNet%2Fgulp-spsave/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-KaiNet%2Fgulp-spsave/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/s-KaiNet","download_url":"https://codeload.github.com/s-KaiNet/gulp-spsave/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-KaiNet%2Fgulp-spsave/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260562638,"owners_count":23028412,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gulp","javascript","sharepoint","typescript"],"created_at":"2024-11-18T04:48:21.072Z","updated_at":"2025-06-18T13:38:20.331Z","avatar_url":"https://github.com/s-KaiNet.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gulp-spsave \n\n[![NPM](https://nodei.co/npm/gulp-spsave.png?mini=true)](https://nodei.co/npm/gulp-spsave/)  \n[![npm version](https://badge.fury.io/js/gulp-spsave.svg)](https://badge.fury.io/js/gulp-spsave)\n\n### Need help on SharePoint with Node.JS? Join our gitter chat and ask question! [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/sharepoint-node/Lobby)\n\nGulp plugin for [spsave](https://github.com/s-KaiNet/spsave) - save files in SharePoint using node.js easily. \n\n----------\n\n## How to use:\n#### Install:\n```bash\nnpm install gulp-spsave --save-dev\n```\n#### Usage:\n\n```javascript\nvar spsave = require('gulp-spsave');\nvar gulp = require('gulp');\n\ngulp.task(\"default\", function(){\n  return gulp.src(\"./build/*.js\")\n             .pipe(spsave(coreOptions, creds));\n});\n```\n\n## Options:   \n\nExactly the same as for [spsave](https://github.com/s-KaiNet/spsave), except file content options (because the file is piped through the gulp stream).  \nThat means no need to provide such options as `fileName`, `fileContent`, `glob`, `file`, `base` (`base` can be provided for the `gulp.src`, see samples below).  \nI recommend you look at the [spsave](https://github.com/s-KaiNet/spsave) page to get a better understanding.\n\n#### Core options (passed to `spsave`):\nThe same as for [spsave core options](https://github.com/s-KaiNet/spsave#core-options) plus two additional options exclusive to `gulp-spsave`:\n - `folder` - required string, SharePoint folder to upload file to (can be the url to document library)\n - `flatten` - boolean, default true, when true all files will be uploaded to `folder` provided, regardles of the file physical location. For example, if folder equal to `MyAppAssets` and you pipe two files `app/controllers/HomeCtrl.js` and `app/templates/home.html`, then `MyAppAssets` will contain both `HomeCtrl.js` and `home.html` in the root.   \n\t If `flatten` is false, `gulp-spsave` will look for base for the file and will use this base for upload file in a particular folder (or create this folder automatically if required). See [gulp API docs](https://github.com/gulpjs/gulp/blob/master/docs/API.md), `gulp.src(globs[, options])` and [glob2base](https://github.com/contra/glob2base).   \n\n#### Credentials:\n\n`gulp-spsave` implicitly depends on another module used for SharePoint authentication from node js - [node-sp-auth](https://github.com/s-KaiNet/node-sp-auth). For credentials param you need to pass exactly the same object, as for `node-sp-auth` [credentialsOptions object](https://github.com/s-KaiNet/node-sp-auth#params). That also means that `gulp-spsave` supports all authentication options supported by `node-sp-auth`. See examples below for more info.  \nYou can also pass a `null` as credentials, in that case `gulp-spsave` will ask you for credentials and will store your credentials in a user folder in an encrypted manner (everything is handled by `node-sp-auth` actually). \n\nExamples:\n--    \n\nImagine we have `settings.js` which stores all sensitive information for us (credential information, client id\\client secret etc.): \n\n```javascript\nmodule.exports = {\n    username: \"[user]\",\n    password: \"[pass]\"\n}\n```\n\n1.Watch for file changes in scripts, then bundle, minify, whatever, and upload to SharePoint automatically:\n\n----------\n\n\n```javascript\n//sensitive data stored in external file:\nvar creds = require(\"./settings.js\");\ngulp.task(\"buildJS\", function(){\n\treturn gulp.src(\"./Scripts/**/*.js\")\n\t.pipe(concat())\n\t.pipe(uglify())\n\t.pipe(gulp.dest(\"./build\"));\n});\n\ngulp.task(\"copyToSharePoint\", [\"buildJS\"], function(){\n\treturn gulp.src(\"./build/*.js\")\n\t\t.pipe(spsave({\n\t\t\tsiteUrl: settings.siteUrl,\n\t\t\tfolder: \"YourAppAssets/js\"\n\t\t}, creds));\n});\n\ngulp.task(\"watch\", function(){\n\tgulp.watch([\"./Scripts/**/*.js\"], [\"copyToSharePoint\"]);\n});\n```  \n2.Save all files from `App/build` to SharePoint:\n\n----------\n\n```javascript\n//sensitive data stored in external file:\nvar creds = require(\"./settings.js\");\ngulp.task(\"spsave\", function () {\n\treturn gulp.src([\"App/build/*.*\"])\n\t\t.pipe($.spsave({\n\t\t\tsiteUrl: settings.siteUrl,\n\t\t\tfolder: \"App/build\",\n\t\t\tflatten: true\n\t\t}, creds));\n});\n```  \n3.Watch all javascript file changes in `ng` (stands for angular) folder and upload that file automatically in SharePoint with preserved folder structure: \n\n----------\n\n\n```javascript\n//sensitive data stored in external file:\nvar creds = require(\"./settings.js\");\ngulp.watch(\"App/ng/**/*.js\", function (event) {\n\t\tgulp.src(event.path)\n\t\t\t.pipe($.spsave({\n\t\t\t\tsiteUrl: settings.siteUrl,\n\t\t\t\tfolder: \"AppAssets\",\n\t\t\t\tflatten: false\n\t\t\t}, creds));\n\t});\n```  \nIn this sample `base` will be equal to `App/ng`. If file path is `App/ng/controllers/HomeCtrl.js`, then it will saved under `AppAssets/controllers/HomeCtrl.js` (if some folders are missing, they will be created by `spsave` automatically). Next sample demonstrate how can you save it under `AppAssets/ng/controllers/HomeCtrl.js` \n\n4.You can also explicitly provide `base` for `gulp.src`: \n\n----------\n \n```javascript\n//sensitive data stored in external file:\nvar creds = require(\"./settings.js\");\ngulp.watch(\"App/ng/**/*.js\", function (event) {\n\t\tgulp.src(event.path, { base: \"App\" })\n\t\t\t.pipe($.spsave({\n\t\t\t\tsiteUrl: settings.siteUrl,\n\t\t\t\tfolder: \"AppAssets\",\n\t\t\t\tflatten: false\n\t\t\t}, creds));\n\t});\n```  \nIn this case file be saved under `AppAssets/ng/controllers/HomeCtrl.js` path.   \n\n5.Upload search display template with metadata:\n\n----------\n\n```javascript\n//sensitive data stored in external file:\nvar creds = require(\"./settings.js\");\ngulp.watch(\"App/search/Item_Display.js\", function (event) {\n\t\tgulp.src(event.path)\n\t\t\t.pipe($.spsave({\n\t\t\t\tsiteUrl: settings.siteUrl,\n\t\t\t\tfolder: \"_catalogs/masterpage/Display Templates/Search\",\n\t\t\t\tflatten: true,\n\t\t\t\tfilesMetaData: [{\n\t\t\t\t\tfileName: \"Item_Display.js\",\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\"__metadata\": { type: \"SP.Data.OData__x005f_catalogs_x002f_masterpageItem\" },\n\t\t\t\t\t\tTitle: \"SPSave Display Template\",\n\t\t\t\t\t\tDisplayTemplateLevel: \"Item\",\n\t\t\t\t\t\tTargetControlType: {\n\t\t\t\t\t\t\t\"__metadata\": {\n\t\t\t\t\t\t\t\t\"type\": \"Collection(Edm.String)\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"results\": [\n\t\t\t\t\t\t\t\t\"SearchResults\"\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tManagedPropertyMapping: `'Title':'Title','Path':'Path','Description':'Description'`,\n\t\t\t\t\t\tContentTypeId: \"0x0101002039C03B61C64EC4A04F5361F38510660500A0383064C59087438E649B7323C95AF6\",\n\t\t\t\t\t\tTemplateHidden: false\n\t\t\t\t\t}\n\t\t\t\t}]\n\t\t\t}, creds));\n\t});\n```  \n...and any other scenarios you need.\n\nFor list of all options for the `spsave` refer to the [git hub repository](https://github.com/s-KaiNet/spsave).  \n\n## Integration testing:\n1. Rename file `/test/integration/config.sample.js` to `config.js`.\n2. Update information in `config.js` with appropriate values (urls, credentials, environment).\n3. Run `npm run test-int`.\n\nKnown Issues\n--\n\nWhen heavily utilizing watchers along with `gulp-spsave` you may see errors \"Save conflict\" or \"Cobalt error\". [spsave](https://github.com/s-KaiNet/spsave) tries to recover from these errors by trying to re-upload the file once or twice again. But usually it's a good idea to use [gulp-plumber](https://github.com/floatdrop/gulp-plumber) or similar tool in order to make sure that your watchers will not be broken when errors occur.   \nNormally you can do the following in your `gulpfile.js`:   \n\n```javascript \nvar plumber = require(\"gulp-plumber\");\nvar onError = function (err) {\n\tconsole.log(err);\n\tthis.emit(\"end\");\n};\ngulp.watch([\"App/index.html\"], function (event) {\n\t\treturn gulp.src(event.path, { base: \"App\" })\n\t\t\t.pipe(plumber({\n\t\t\t\terrorHandler: onError\n\t\t\t}))\n\t\t\t.pipe(spsave(settings));\n\t});\n\n```\n\nIn case of error, your watch will remain up and running regardless of the error. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs-kainet%2Fgulp-spsave","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fs-kainet%2Fgulp-spsave","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs-kainet%2Fgulp-spsave/lists"}