diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..fe11a63 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,20 @@ +name: Release datasync asset store filesystem +on: + push: + branches: [master] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: "16.x" + - name: Installing dependencies + run: npm install + - name: Build + run: npm run build-ts + - name: Publishing datasync asset store filesystem + uses: JS-DevTools/npm-publish@v1 + with: + token: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index e60431a..d0f3d13 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,4 @@ coverage # Data _contents example/_contents/ - +dist/ \ No newline at end of file diff --git a/dist/config.js b/dist/config.js deleted file mode 100644 index ba5c687..0000000 --- a/dist/config.js +++ /dev/null @@ -1,17 +0,0 @@ -"use strict"; -/*! -* contentstack-sync-asset-store-filesystem -* copyright (c) Contentstack LLC -* MIT Licensed -*/ -Object.defineProperty(exports, "__esModule", { value: true }); -exports.defaultConfig = void 0; -exports.defaultConfig = { - assetStore: { - // optional prefixing of asset in internal urls - // assetFolderPrefixKey: 'dev-assets', - baseDir: './_contents', - pattern: '/:locale/assets/:uid/:filename', - patternWithBranch: ':branch/:locale/assets/:uid/:filename', - }, -}; diff --git a/dist/filesystem.js b/dist/filesystem.js deleted file mode 100644 index e7078e3..0000000 --- a/dist/filesystem.js +++ /dev/null @@ -1,153 +0,0 @@ -"use strict"; -/*! - * contentstack-sync-asset-store-filesystem - * copyright (c) Contentstack LLC - * MIT Licensed - */ -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.FSAssetStore = void 0; -const debug_1 = require("debug"); -const fs_1 = require("fs"); -const lodash_1 = require("lodash"); -const mkdirp_1 = __importDefault(require("mkdirp")); -const path_1 = require("path"); -const request_1 = __importDefault(require("request")); -const rimraf_1 = __importDefault(require("rimraf")); -const index_1 = require("./index"); -const utils_1 = require("./utils"); -const debug = debug_1.debug('asset-store-filesystem'); -/** - * @class - * @private - * @summary Class that downloads and deletes assets from FS DB - * @example - * const assetStore = new FSAssetStore(config) - * return assetStore.download(asset) - * .then() - * .catch() - * @returns {FSAssetStore} - */ -class FSAssetStore { - constructor(config) { - this.config = config.assetStore; - } - /** - * @public - * @method download - * @description Downloads the asset object onto local fs - * @param {object} asset Asset object details - * @returns {Promise} returns the asset object, if successful. - */ - download(asset) { - debug('Asset download invoked ' + JSON.stringify(asset)); - return new Promise((resolve, reject) => { - try { - utils_1.validatePublishAsset(asset); - return request_1.default.get({ - url: encodeURI(asset.url), - }) - .on('response', (resp) => { - if (resp.statusCode === 200) { - if (asset.hasOwnProperty('download_id')) { - const attachment = resp.headers['content-disposition']; - asset.filename = decodeURIComponent(attachment.split('=')[1]); - } - asset._internal_url = index_1.getAssetLocation(asset, this.config); - const filePathArray = index_1.getFileLocation(asset, this.config); - const folderPathArray = lodash_1.cloneDeep(filePathArray); - folderPathArray.splice(folderPathArray.length - 1); - const folderPath = path_1.resolve(path_1.join.apply(this, folderPathArray)); - const filePath = path_1.resolve(path_1.join.apply(this, filePathArray)); - if (!fs_1.existsSync(folderPath)) { - mkdirp_1.default.sync(folderPath, '0755'); - } - const localStream = fs_1.createWriteStream(filePath); - resp.pipe(localStream); - localStream.on('close', () => { - return resolve(asset); - }); - } - else { - return reject(`Failed to download asset ${JSON.stringify(asset)}`); - } - }) - .on('error', reject) - .end(); - } - catch (error) { - debug(`${asset.uid} asset download failed`); - return reject(error); - } - }); - } - /** - * @private - * @method delete - * @description Delete the asset from fs db - * @param {array} assets Assets to be deleted - * @returns {Promise} returns the asset object, if successful. - */ - delete(assets) { - debug('Asset deletion called for', JSON.stringify(assets)); - const asset = assets[0]; - return new Promise((resolve, reject) => { - try { - utils_1.validateUnPublishAsset(asset); - const folderPathArray = index_1.getFileLocation(asset, this.config); - folderPathArray.splice(folderPathArray.length - 1, 1); - const folderPath = path_1.resolve(path_1.join.apply(this, folderPathArray)); - if (fs_1.existsSync(folderPath)) { - return rimraf_1.default(folderPath, (error) => { - if (error) { - debug(`Error while removing ${folderPath} asset file`); - return reject(error); - } - return resolve(asset); - }); - } - else { - debug(`${folderPath} did not exist!`); - return resolve(asset); - } - } - catch (error) { - return reject(error); - } - }); - } - /** - * @private - * @method unpublish - * @description Unpublish the asset from filesystem - * @param {object} asset Asset to be unpublished - * @returns {Promise} returns the asset object, if successful. - */ - unpublish(asset) { - debug(`Asset unpublish called ${JSON.stringify(asset)}`); - return new Promise((resolve, reject) => { - try { - utils_1.validateUnPublishAsset(asset); - const filePathArray = index_1.getFileLocation(asset, this.config); - const filePath = path_1.resolve(path_1.join.apply(this, filePathArray)); - if (fs_1.existsSync(filePath)) { - return rimraf_1.default(filePath, (error) => { - if (error) { - debug(`Error while removing ${filePath} asset file`); - return reject(error); - } - return resolve(asset); - }); - } - debug(`${filePath} did not exist!`); - return resolve(asset); - } - catch (error) { - return reject(error); - } - }); - } -} -exports.FSAssetStore = FSAssetStore; diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index 7e1d166..0000000 --- a/dist/index.js +++ /dev/null @@ -1,129 +0,0 @@ -"use strict"; -/*! -* contentstack-sync-asset-store-filesystem -* copyright (c) Contentstack LLC -* MIT Licensed -*/ -Object.defineProperty(exports, "__esModule", { value: true }); -exports.start = exports.assetStoreInstance = exports.getConfig = exports.setConfig = exports.getFileLocation = exports.getAssetLocation = void 0; -const debug_1 = require("debug"); -const lodash_1 = require("lodash"); -const path_1 = require("path"); -const config_1 = require("./config"); -const filesystem_1 = require("./filesystem"); -let assetStoreConfig; -let assetStoreInstance; -exports.assetStoreInstance = assetStoreInstance; -exports.getAssetLocation = (asset, config) => { - const values = []; - const keys = assetStoreConfig.contentstack.branch ? lodash_1.compact(config.patternWithBranch.split('/')) : lodash_1.compact(config.pattern.split('/')); - if (config.assetFolderPrefixKey && typeof config.assetFolderPrefixKey === 'string') { - values.push(config.assetFolderPrefixKey); - } - const regexp = new RegExp('https://(assets|images|dev-assets|dev-images|stag-assets|stag-images).contentstack.io/(v[\\d])/assets/(.*?)/(.*?)/(.*?)/(.*)', 'g'); - let matches; - // tslint:disable-next-line: no-conditional-assignment - while ((matches = regexp.exec(asset.url)) !== null) { - if (matches && matches.length) { - if (matches[2]) { - asset.apiVersion = matches[2]; - } - if (matches[3]) { - asset.apiKey = matches[3]; - } - if (matches[4]) { - asset.downloadId = matches[4]; - } - } - } - for (let i = 0, keyLength = keys.length; i < keyLength; i++) { - if (keys[i].charAt(0) === ':') { - const k = keys[i].substring(1); - if (asset[k]) { - values.push(asset[k]); - } - else { - throw new TypeError(`The key ${keys[i]} did not exist on ${JSON.stringify(asset)}`); - } - } - else { - values.push(keys[i]); - } - } - return path_1.join.apply(this, values); -}; -exports.getFileLocation = (asset, config) => { - const values = []; - let keys = lodash_1.compact(config.baseDir.split('/')); - const dir = assetStoreConfig.contentstack.branch ? lodash_1.compact(config.patternWithBranch.split('/')) : lodash_1.compact(config.pattern.split('/')); - keys = keys.concat(dir); - if (config.assetFolderPrefixKey && typeof config.assetFolderPrefixKey === 'string') { - values.push(config.assetFolderPrefixKey); - } - const regexp = new RegExp('https://(assets|images|dev-assets|dev-images|stag-assets|stag-images).contentstack.io/(v[\\d])/assets/(.*?)/(.*?)/(.*?)/(.*)', 'g'); - let matches; - // tslint:disable-next-line: no-conditional-assignment - while ((matches = regexp.exec(asset.url)) !== null) { - if (matches && matches.length) { - if (matches[2]) { - asset.apiVersion = matches[2]; - } - if (matches[3]) { - asset.apiKey = matches[3]; - } - if (matches[4]) { - asset.downloadId = matches[4]; - } - } - } - for (let i = 0, keyLength = keys.length; i < keyLength; i++) { - if (keys[i].charAt(0) === ':') { - const k = keys[i].substring(1); - if (asset[k]) { - values.push(asset[k]); - } - else { - throw new TypeError(`The key ${keys[i]} did not exist on ${JSON.stringify(asset)}`); - } - } - else { - values.push(keys[i]); - } - } - return values; -}; -exports.setConfig = (config) => { - assetStoreConfig = config; -}; -exports.getConfig = () => { - return assetStoreConfig; -}; -const debug = debug_1.debug('asset-store-filesystem'); -/** - * @description to start the asset connector - * @param {object} config Optional app config - * @example - * import { start } from '@contentstack/datasync-asset-store-filesystem' - * const assetStore = start(config) - * .then() - * .catch() - * - * return assetStore.download(asset) - * return assetStore.unpublish(asset) - * - * @return {FSAssetStore} - */ -function start(config) { - return new Promise((resolve, reject) => { - try { - assetStoreConfig = (config) ? lodash_1.merge(config_1.defaultConfig, config) : config_1.defaultConfig; - exports.assetStoreInstance = assetStoreInstance = new filesystem_1.FSAssetStore(assetStoreConfig); - return resolve(assetStoreInstance); - } - catch (error) { - debug('Failed to load content-store due to', error); - reject(error); - } - }); -} -exports.start = start; diff --git a/dist/utils.js b/dist/utils.js deleted file mode 100644 index 1729378..0000000 --- a/dist/utils.js +++ /dev/null @@ -1,19 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.validateUnPublishAsset = exports.validatePublishAsset = void 0; -const requiredKeysForPublish = ['url', 'locale', 'uid']; -const requiredKeysForUnpublish = ['url', 'locale', 'filename', 'uid']; -exports.validatePublishAsset = (asset) => { - requiredKeysForPublish.forEach((key) => { - if (!(key in asset)) { - throw new Error(`${key} is missing in asset publish!\n${JSON.stringify(asset)}`); - } - }); -}; -exports.validateUnPublishAsset = (asset) => { - requiredKeysForUnpublish.forEach((key) => { - if (!(key in asset)) { - throw new Error(`${key} is missing in asset unpublish!\n${JSON.stringify(asset)}`); - } - }); -}; diff --git a/package.json b/package.json index 0d0d871..f5d7f11 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,11 @@ "utility", "datasync" ], + "files": [ + "/dist", + "/typings", + "/npm-shrinkwrap.json" + ], "scripts": { "clean": "rimraf dist coverage", "build-ts": "npm run clean && tsc",