extends {
- thisArg: infer OrigThis;
- params: infer P extends readonly unknown[];
- returnType: infer R;
-}
- ? ReceiverBound extends true
- ? (...args: RemoveFromTuple>) => R extends [OrigThis, ...infer Rest]
- ? [TThis, ...Rest] // Replace `this` with `thisArg`
- : R
- : >>(
- thisArg: U,
- ...args: RemainingArgs
- ) => R extends [OrigThis, ...infer Rest]
- ? [U, ...ConcatTuples] // Preserve bound args in return type
- : R
- : never;
-
-declare function callBind<
- const T extends (this: any, ...args: any[]) => any,
- Extracted extends ExtractFunctionParams,
- const TBoundArgs extends Partial & readonly unknown[],
- const TThis extends Extracted["thisArg"]
->(
- args: [fn: T, thisArg: TThis, ...boundArgs: TBoundArgs]
-): BindFunction;
-
-declare function callBind<
- const T extends (this: any, ...args: any[]) => any,
- Extracted extends ExtractFunctionParams,
- const TBoundArgs extends Partial & readonly unknown[]
->(
- args: [fn: T, ...boundArgs: TBoundArgs]
-): BindFunction;
-
-declare function callBind(
- args: [fn: Exclude, ...rest: TArgs]
-): never;
-
-// export as namespace callBind;
-export = callBind;
diff --git a/server/node_modules/call-bind-apply-helpers/index.js b/server/node_modules/call-bind-apply-helpers/index.js
deleted file mode 100644
index 2f6dab4..0000000
--- a/server/node_modules/call-bind-apply-helpers/index.js
+++ /dev/null
@@ -1,15 +0,0 @@
-'use strict';
-
-var bind = require('function-bind');
-var $TypeError = require('es-errors/type');
-
-var $call = require('./functionCall');
-var $actualApply = require('./actualApply');
-
-/** @type {(args: [Function, thisArg?: unknown, ...args: unknown[]]) => Function} TODO FIXME, find a way to use import('.') */
-module.exports = function callBindBasic(args) {
- if (args.length < 1 || typeof args[0] !== 'function') {
- throw new $TypeError('a function is required');
- }
- return $actualApply(bind, $call, args);
-};
diff --git a/server/node_modules/call-bind-apply-helpers/package.json b/server/node_modules/call-bind-apply-helpers/package.json
deleted file mode 100644
index 923b8be..0000000
--- a/server/node_modules/call-bind-apply-helpers/package.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "name": "call-bind-apply-helpers",
- "version": "1.0.2",
- "description": "Helper functions around Function call/apply/bind, for use in `call-bind`",
- "main": "index.js",
- "exports": {
- ".": "./index.js",
- "./actualApply": "./actualApply.js",
- "./applyBind": "./applyBind.js",
- "./functionApply": "./functionApply.js",
- "./functionCall": "./functionCall.js",
- "./reflectApply": "./reflectApply.js",
- "./package.json": "./package.json"
- },
- "scripts": {
- "prepack": "npmignore --auto --commentLines=auto",
- "prepublish": "not-in-publish || npm run prepublishOnly",
- "prepublishOnly": "safe-publish-latest",
- "prelint": "evalmd README.md",
- "lint": "eslint --ext=.js,.mjs .",
- "postlint": "tsc -p . && attw -P",
- "pretest": "npm run lint",
- "tests-only": "nyc tape 'test/**/*.js'",
- "test": "npm run tests-only",
- "posttest": "npx npm@'>=10.2' audit --production",
- "version": "auto-changelog && git add CHANGELOG.md",
- "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/ljharb/call-bind-apply-helpers.git"
- },
- "author": "Jordan Harband ",
- "license": "MIT",
- "bugs": {
- "url": "https://github.com/ljharb/call-bind-apply-helpers/issues"
- },
- "homepage": "https://github.com/ljharb/call-bind-apply-helpers#readme",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "devDependencies": {
- "@arethetypeswrong/cli": "^0.17.3",
- "@ljharb/eslint-config": "^21.1.1",
- "@ljharb/tsconfig": "^0.2.3",
- "@types/for-each": "^0.3.3",
- "@types/function-bind": "^1.1.10",
- "@types/object-inspect": "^1.13.0",
- "@types/tape": "^5.8.1",
- "auto-changelog": "^2.5.0",
- "encoding": "^0.1.13",
- "es-value-fixtures": "^1.7.1",
- "eslint": "=8.8.0",
- "evalmd": "^0.0.19",
- "for-each": "^0.3.5",
- "has-strict-mode": "^1.1.0",
- "in-publish": "^2.0.1",
- "npmignore": "^0.3.1",
- "nyc": "^10.3.2",
- "object-inspect": "^1.13.4",
- "safe-publish-latest": "^2.0.0",
- "tape": "^5.9.0",
- "typescript": "next"
- },
- "testling": {
- "files": "test/index.js"
- },
- "auto-changelog": {
- "output": "CHANGELOG.md",
- "template": "keepachangelog",
- "unreleased": false,
- "commitLimit": false,
- "backfillLimit": false,
- "hideCredit": true
- },
- "publishConfig": {
- "ignore": [
- ".github/workflows"
- ]
- },
- "engines": {
- "node": ">= 0.4"
- }
-}
diff --git a/server/node_modules/call-bind-apply-helpers/reflectApply.d.ts b/server/node_modules/call-bind-apply-helpers/reflectApply.d.ts
deleted file mode 100644
index 6b2ae76..0000000
--- a/server/node_modules/call-bind-apply-helpers/reflectApply.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-declare const reflectApply: false | typeof Reflect.apply;
-
-export = reflectApply;
diff --git a/server/node_modules/call-bind-apply-helpers/reflectApply.js b/server/node_modules/call-bind-apply-helpers/reflectApply.js
deleted file mode 100644
index 3d03caa..0000000
--- a/server/node_modules/call-bind-apply-helpers/reflectApply.js
+++ /dev/null
@@ -1,4 +0,0 @@
-'use strict';
-
-/** @type {import('./reflectApply')} */
-module.exports = typeof Reflect !== 'undefined' && Reflect && Reflect.apply;
diff --git a/server/node_modules/call-bind-apply-helpers/test/index.js b/server/node_modules/call-bind-apply-helpers/test/index.js
deleted file mode 100644
index 1cdc89e..0000000
--- a/server/node_modules/call-bind-apply-helpers/test/index.js
+++ /dev/null
@@ -1,63 +0,0 @@
-'use strict';
-
-var callBind = require('../');
-var hasStrictMode = require('has-strict-mode')();
-var forEach = require('for-each');
-var inspect = require('object-inspect');
-var v = require('es-value-fixtures');
-
-var test = require('tape');
-
-test('callBindBasic', function (t) {
- forEach(v.nonFunctions, function (nonFunction) {
- t['throws'](
- // @ts-expect-error
- function () { callBind([nonFunction]); },
- TypeError,
- inspect(nonFunction) + ' is not a function'
- );
- });
-
- var sentinel = { sentinel: true };
- /** @type {(this: T, a: A, b: B) => [T | undefined, A, B]} */
- var func = function (a, b) {
- // eslint-disable-next-line no-invalid-this
- return [!hasStrictMode && this === global ? undefined : this, a, b];
- };
- t.equal(func.length, 2, 'original function length is 2');
-
- /** type {(thisArg: unknown, a: number, b: number) => [unknown, number, number]} */
- var bound = callBind([func]);
- /** type {((a: number, b: number) => [typeof sentinel, typeof a, typeof b])} */
- var boundR = callBind([func, sentinel]);
- /** type {((b: number) => [typeof sentinel, number, typeof b])} */
- var boundArg = callBind([func, sentinel, /** @type {const} */ (1)]);
-
- // @ts-expect-error
- t.deepEqual(bound(), [undefined, undefined, undefined], 'bound func with no args');
-
- // @ts-expect-error
- t.deepEqual(func(), [undefined, undefined, undefined], 'unbound func with too few args');
- // @ts-expect-error
- t.deepEqual(bound(1, 2), [hasStrictMode ? 1 : Object(1), 2, undefined], 'bound func too few args');
- // @ts-expect-error
- t.deepEqual(boundR(), [sentinel, undefined, undefined], 'bound func with receiver, with too few args');
- // @ts-expect-error
- t.deepEqual(boundArg(), [sentinel, 1, undefined], 'bound func with receiver and arg, with too few args');
-
- t.deepEqual(func(1, 2), [undefined, 1, 2], 'unbound func with right args');
- t.deepEqual(bound(1, 2, 3), [hasStrictMode ? 1 : Object(1), 2, 3], 'bound func with right args');
- t.deepEqual(boundR(1, 2), [sentinel, 1, 2], 'bound func with receiver, with right args');
- t.deepEqual(boundArg(2), [sentinel, 1, 2], 'bound func with receiver and arg, with right arg');
-
- // @ts-expect-error
- t.deepEqual(func(1, 2, 3), [undefined, 1, 2], 'unbound func with too many args');
- // @ts-expect-error
- t.deepEqual(bound(1, 2, 3, 4), [hasStrictMode ? 1 : Object(1), 2, 3], 'bound func with too many args');
- // @ts-expect-error
- t.deepEqual(boundR(1, 2, 3), [sentinel, 1, 2], 'bound func with receiver, with too many args');
- // @ts-expect-error
- t.deepEqual(boundArg(2, 3), [sentinel, 1, 2], 'bound func with receiver and arg, with too many args');
-
- t.end();
-});
diff --git a/server/node_modules/call-bind-apply-helpers/tsconfig.json b/server/node_modules/call-bind-apply-helpers/tsconfig.json
deleted file mode 100644
index aef9993..0000000
--- a/server/node_modules/call-bind-apply-helpers/tsconfig.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "extends": "@ljharb/tsconfig",
- "compilerOptions": {
- "target": "es2021",
- },
- "exclude": [
- "coverage",
- ],
-}
\ No newline at end of file
diff --git a/server/node_modules/call-bound/.eslintrc b/server/node_modules/call-bound/.eslintrc
deleted file mode 100644
index 2612ed8..0000000
--- a/server/node_modules/call-bound/.eslintrc
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "root": true,
-
- "extends": "@ljharb",
-
- "rules": {
- "new-cap": [2, {
- "capIsNewExceptions": [
- "GetIntrinsic",
- ],
- }],
- },
-}
diff --git a/server/node_modules/call-bound/.github/FUNDING.yml b/server/node_modules/call-bound/.github/FUNDING.yml
deleted file mode 100644
index 2a2a135..0000000
--- a/server/node_modules/call-bound/.github/FUNDING.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-# These are supported funding model platforms
-
-github: [ljharb]
-patreon: # Replace with a single Patreon username
-open_collective: # Replace with a single Open Collective username
-ko_fi: # Replace with a single Ko-fi username
-tidelift: npm/call-bound
-community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
-liberapay: # Replace with a single Liberapay username
-issuehunt: # Replace with a single IssueHunt username
-otechie: # Replace with a single Otechie username
-custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/server/node_modules/call-bound/.nycrc b/server/node_modules/call-bound/.nycrc
deleted file mode 100644
index bdd626c..0000000
--- a/server/node_modules/call-bound/.nycrc
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "all": true,
- "check-coverage": false,
- "reporter": ["text-summary", "text", "html", "json"],
- "exclude": [
- "coverage",
- "test"
- ]
-}
diff --git a/server/node_modules/call-bound/CHANGELOG.md b/server/node_modules/call-bound/CHANGELOG.md
deleted file mode 100644
index 8bde4e9..0000000
--- a/server/node_modules/call-bound/CHANGELOG.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# Changelog
-
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
-and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-
-## [v1.0.4](https://github.com/ljharb/call-bound/compare/v1.0.3...v1.0.4) - 2025-03-03
-
-### Commits
-
-- [types] improve types [`e648922`](https://github.com/ljharb/call-bound/commit/e6489222a9e54f350fbf952ceabe51fd8b6027ff)
-- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/tsconfig`, `@types/tape`, `es-value-fixtures`, `for-each`, `has-strict-mode`, `object-inspect` [`a42a5eb`](https://github.com/ljharb/call-bound/commit/a42a5ebe6c1b54fcdc7997c7dc64fdca9e936719)
-- [Deps] update `call-bind-apply-helpers`, `get-intrinsic` [`f529eac`](https://github.com/ljharb/call-bound/commit/f529eac132404c17156bbc23ab2297a25d0f20b8)
-
-## [v1.0.3](https://github.com/ljharb/call-bound/compare/v1.0.2...v1.0.3) - 2024-12-15
-
-### Commits
-
-- [Refactor] use `call-bind-apply-helpers` instead of `call-bind` [`5e0b134`](https://github.com/ljharb/call-bound/commit/5e0b13496df14fb7d05dae9412f088da8d3f75be)
-- [Deps] update `get-intrinsic` [`41fc967`](https://github.com/ljharb/call-bound/commit/41fc96732a22c7b7e8f381f93ccc54bb6293be2e)
-- [readme] fix example [`79a0137`](https://github.com/ljharb/call-bound/commit/79a0137723f7c6d09c9c05452bbf8d5efb5d6e49)
-- [meta] add `sideEffects` flag [`08b07be`](https://github.com/ljharb/call-bound/commit/08b07be7f1c03f67dc6f3cdaf0906259771859f7)
-
-## [v1.0.2](https://github.com/ljharb/call-bound/compare/v1.0.1...v1.0.2) - 2024-12-10
-
-### Commits
-
-- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/tsconfig`, `gopd` [`e6a5ffe`](https://github.com/ljharb/call-bound/commit/e6a5ffe849368fe4f74dfd6cdeca1b9baa39e8d5)
-- [Deps] update `call-bind`, `get-intrinsic` [`2aeb5b5`](https://github.com/ljharb/call-bound/commit/2aeb5b521dc2b2683d1345c753ea1161de2d1c14)
-- [types] improve return type [`1a0c9fe`](https://github.com/ljharb/call-bound/commit/1a0c9fe3114471e7ca1f57d104e2efe713bb4871)
-
-## v1.0.1 - 2024-12-05
-
-### Commits
-
-- Initial implementation, tests, readme, types [`6d94121`](https://github.com/ljharb/call-bound/commit/6d94121a9243602e506334069f7a03189fe3363d)
-- Initial commit [`0eae867`](https://github.com/ljharb/call-bound/commit/0eae867334ea025c33e6e91cdecfc9df96680cf9)
-- npm init [`71b2479`](https://github.com/ljharb/call-bound/commit/71b2479c6723e0b7d91a6b663613067e98b7b275)
-- Only apps should have lockfiles [`c3754a9`](https://github.com/ljharb/call-bound/commit/c3754a949b7f9132b47e2d18c1729889736741eb)
-- [actions] skip `npm ls` in node < 10 [`74275a5`](https://github.com/ljharb/call-bound/commit/74275a5186b8caf6309b6b97472bdcb0df4683a8)
-- [Dev Deps] add missing peer dep [`1354de8`](https://github.com/ljharb/call-bound/commit/1354de8679413e4ae9c523d85f76fa7a5e032d97)
diff --git a/server/node_modules/call-bound/LICENSE b/server/node_modules/call-bound/LICENSE
deleted file mode 100644
index f82f389..0000000
--- a/server/node_modules/call-bound/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 Jordan Harband
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/server/node_modules/call-bound/README.md b/server/node_modules/call-bound/README.md
deleted file mode 100644
index a44e43e..0000000
--- a/server/node_modules/call-bound/README.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# call-bound [![Version Badge][npm-version-svg]][package-url]
-
-[![github actions][actions-image]][actions-url]
-[![coverage][codecov-image]][codecov-url]
-[![dependency status][deps-svg]][deps-url]
-[![dev dependency status][dev-deps-svg]][dev-deps-url]
-[![License][license-image]][license-url]
-[![Downloads][downloads-image]][downloads-url]
-
-[![npm badge][npm-badge-png]][package-url]
-
-Robust call-bound JavaScript intrinsics, using `call-bind` and `get-intrinsic`.
-
-## Getting started
-
-```sh
-npm install --save call-bound
-```
-
-## Usage/Examples
-
-```js
-const assert = require('assert');
-const callBound = require('call-bound');
-
-const slice = callBound('Array.prototype.slice');
-
-delete Function.prototype.call;
-delete Function.prototype.bind;
-delete Array.prototype.slice;
-
-assert.deepEqual(slice([1, 2, 3, 4], 1, -1), [2, 3]);
-```
-
-## Tests
-
-Clone the repo, `npm install`, and run `npm test`
-
-[package-url]: https://npmjs.org/package/call-bound
-[npm-version-svg]: https://versionbadg.es/ljharb/call-bound.svg
-[deps-svg]: https://david-dm.org/ljharb/call-bound.svg
-[deps-url]: https://david-dm.org/ljharb/call-bound
-[dev-deps-svg]: https://david-dm.org/ljharb/call-bound/dev-status.svg
-[dev-deps-url]: https://david-dm.org/ljharb/call-bound#info=devDependencies
-[npm-badge-png]: https://nodei.co/npm/call-bound.png?downloads=true&stars=true
-[license-image]: https://img.shields.io/npm/l/call-bound.svg
-[license-url]: LICENSE
-[downloads-image]: https://img.shields.io/npm/dm/call-bound.svg
-[downloads-url]: https://npm-stat.com/charts.html?package=call-bound
-[codecov-image]: https://codecov.io/gh/ljharb/call-bound/branch/main/graphs/badge.svg
-[codecov-url]: https://app.codecov.io/gh/ljharb/call-bound/
-[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/call-bound
-[actions-url]: https://github.com/ljharb/call-bound/actions
diff --git a/server/node_modules/call-bound/index.d.ts b/server/node_modules/call-bound/index.d.ts
deleted file mode 100644
index 5562f00..0000000
--- a/server/node_modules/call-bound/index.d.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-type Intrinsic = typeof globalThis;
-
-type IntrinsicName = keyof Intrinsic | `%${keyof Intrinsic}%`;
-
-type IntrinsicPath = IntrinsicName | `${StripPercents}.${string}` | `%${StripPercents}.${string}%`;
-
-type AllowMissing = boolean;
-
-type StripPercents = T extends `%${infer U}%` ? U : T;
-
-type BindMethodPrecise =
- F extends (this: infer This, ...args: infer Args) => infer R
- ? (obj: This, ...args: Args) => R
- : F extends {
- (this: infer This1, ...args: infer Args1): infer R1;
- (this: infer This2, ...args: infer Args2): infer R2
- }
- ? {
- (obj: This1, ...args: Args1): R1;
- (obj: This2, ...args: Args2): R2
- }
- : never
-
-// Extract method type from a prototype
-type GetPrototypeMethod =
- (typeof globalThis)[T] extends { prototype: any }
- ? M extends keyof (typeof globalThis)[T]['prototype']
- ? (typeof globalThis)[T]['prototype'][M]
- : never
- : never
-
-// Get static property/method
-type GetStaticMember =
- P extends keyof (typeof globalThis)[T] ? (typeof globalThis)[T][P] : never
-
-// Type that maps string path to actual bound function or value with better precision
-type BoundIntrinsic =
- S extends `${infer Obj}.prototype.${infer Method}`
- ? Obj extends keyof typeof globalThis
- ? BindMethodPrecise>
- : unknown
- : S extends `${infer Obj}.${infer Prop}`
- ? Obj extends keyof typeof globalThis
- ? GetStaticMember
- : unknown
- : unknown
-
-declare function arraySlice(array: readonly T[], start?: number, end?: number): T[];
-declare function arraySlice(array: ArrayLike, start?: number, end?: number): T[];
-declare function arraySlice(array: IArguments, start?: number, end?: number): T[];
-
-// Special cases for methods that need explicit typing
-interface SpecialCases {
- '%Object.prototype.isPrototypeOf%': (thisArg: {}, obj: unknown) => boolean;
- '%String.prototype.replace%': {
- (str: string, searchValue: string | RegExp, replaceValue: string): string;
- (str: string, searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string
- };
- '%Object.prototype.toString%': (obj: {}) => string;
- '%Object.prototype.hasOwnProperty%': (obj: {}, v: PropertyKey) => boolean;
- '%Array.prototype.slice%': typeof arraySlice;
- '%Array.prototype.map%': (array: readonly T[], callbackfn: (value: T, index: number, array: readonly T[]) => U, thisArg?: any) => U[];
- '%Array.prototype.filter%': (array: readonly T[], predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any) => T[];
- '%Array.prototype.indexOf%': (array: readonly T[], searchElement: T, fromIndex?: number) => number;
- '%Function.prototype.apply%': (fn: (...args: A) => R, thisArg: any, args: A) => R;
- '%Function.prototype.call%': (fn: (...args: A) => R, thisArg: any, ...args: A) => R;
- '%Function.prototype.bind%': (fn: (...args: A) => R, thisArg: any, ...args: A) => (...remainingArgs: A) => R;
- '%Promise.prototype.then%': {
- (promise: Promise, onfulfilled: (value: T) => R | PromiseLike): Promise;
- (promise: Promise, onfulfilled: ((value: T) => R | PromiseLike) | undefined | null, onrejected: (reason: any) => R | PromiseLike): Promise;
- };
- '%RegExp.prototype.test%': (regexp: RegExp, str: string) => boolean;
- '%RegExp.prototype.exec%': (regexp: RegExp, str: string) => RegExpExecArray | null;
- '%Error.prototype.toString%': (error: Error) => string;
- '%TypeError.prototype.toString%': (error: TypeError) => string;
- '%String.prototype.split%': (
- obj: unknown,
- splitter: string | RegExp | {
- [Symbol.split](string: string, limit?: number): string[];
- },
- limit?: number | undefined
- ) => string[];
-}
-
-/**
- * Returns a bound function for a prototype method, or a value for a static property.
- *
- * @param name - The name of the intrinsic (e.g. 'Array.prototype.slice')
- * @param {AllowMissing} [allowMissing] - Whether to allow missing intrinsics (default: false)
- */
-declare function callBound, S extends IntrinsicPath>(name: K, allowMissing?: AllowMissing): SpecialCases[`%${StripPercents}%`];
-declare function callBound, S extends IntrinsicPath>(name: S, allowMissing?: AllowMissing): BoundIntrinsic;
-
-export = callBound;
diff --git a/server/node_modules/call-bound/index.js b/server/node_modules/call-bound/index.js
deleted file mode 100644
index e9ade74..0000000
--- a/server/node_modules/call-bound/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-'use strict';
-
-var GetIntrinsic = require('get-intrinsic');
-
-var callBindBasic = require('call-bind-apply-helpers');
-
-/** @type {(thisArg: string, searchString: string, position?: number) => number} */
-var $indexOf = callBindBasic([GetIntrinsic('%String.prototype.indexOf%')]);
-
-/** @type {import('.')} */
-module.exports = function callBoundIntrinsic(name, allowMissing) {
- /* eslint no-extra-parens: 0 */
-
- var intrinsic = /** @type {(this: unknown, ...args: unknown[]) => unknown} */ (GetIntrinsic(name, !!allowMissing));
- if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {
- return callBindBasic(/** @type {const} */ ([intrinsic]));
- }
- return intrinsic;
-};
diff --git a/server/node_modules/call-bound/package.json b/server/node_modules/call-bound/package.json
deleted file mode 100644
index d542db4..0000000
--- a/server/node_modules/call-bound/package.json
+++ /dev/null
@@ -1,99 +0,0 @@
-{
- "name": "call-bound",
- "version": "1.0.4",
- "description": "Robust call-bound JavaScript intrinsics, using `call-bind` and `get-intrinsic`.",
- "main": "index.js",
- "exports": {
- ".": "./index.js",
- "./package.json": "./package.json"
- },
- "sideEffects": false,
- "scripts": {
- "prepack": "npmignore --auto --commentLines=auto",
- "prepublish": "not-in-publish || npm run prepublishOnly",
- "prepublishOnly": "safe-publish-latest",
- "prelint": "evalmd README.md",
- "lint": "eslint --ext=.js,.mjs .",
- "postlint": "tsc -p . && attw -P",
- "pretest": "npm run lint",
- "tests-only": "nyc tape 'test/**/*.js'",
- "test": "npm run tests-only",
- "posttest": "npx npm@'>=10.2' audit --production",
- "version": "auto-changelog && git add CHANGELOG.md",
- "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/ljharb/call-bound.git"
- },
- "keywords": [
- "javascript",
- "ecmascript",
- "es",
- "js",
- "callbind",
- "callbound",
- "call",
- "bind",
- "bound",
- "call-bind",
- "call-bound",
- "function",
- "es-abstract"
- ],
- "author": "Jordan Harband ",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- },
- "license": "MIT",
- "bugs": {
- "url": "https://github.com/ljharb/call-bound/issues"
- },
- "homepage": "https://github.com/ljharb/call-bound#readme",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
- },
- "devDependencies": {
- "@arethetypeswrong/cli": "^0.17.4",
- "@ljharb/eslint-config": "^21.1.1",
- "@ljharb/tsconfig": "^0.3.0",
- "@types/call-bind": "^1.0.5",
- "@types/get-intrinsic": "^1.2.3",
- "@types/tape": "^5.8.1",
- "auto-changelog": "^2.5.0",
- "encoding": "^0.1.13",
- "es-value-fixtures": "^1.7.1",
- "eslint": "=8.8.0",
- "evalmd": "^0.0.19",
- "for-each": "^0.3.5",
- "gopd": "^1.2.0",
- "has-strict-mode": "^1.1.0",
- "in-publish": "^2.0.1",
- "npmignore": "^0.3.1",
- "nyc": "^10.3.2",
- "object-inspect": "^1.13.4",
- "safe-publish-latest": "^2.0.0",
- "tape": "^5.9.0",
- "typescript": "next"
- },
- "testling": {
- "files": "test/index.js"
- },
- "auto-changelog": {
- "output": "CHANGELOG.md",
- "template": "keepachangelog",
- "unreleased": false,
- "commitLimit": false,
- "backfillLimit": false,
- "hideCredit": true
- },
- "publishConfig": {
- "ignore": [
- ".github/workflows"
- ]
- },
- "engines": {
- "node": ">= 0.4"
- }
-}
diff --git a/server/node_modules/call-bound/test/index.js b/server/node_modules/call-bound/test/index.js
deleted file mode 100644
index a2fc9f0..0000000
--- a/server/node_modules/call-bound/test/index.js
+++ /dev/null
@@ -1,61 +0,0 @@
-'use strict';
-
-var test = require('tape');
-
-var callBound = require('../');
-
-/** @template {true} T @template U @typedef {T extends U ? T : never} AssertType */
-
-test('callBound', function (t) {
- // static primitive
- t.equal(callBound('Array.length'), Array.length, 'Array.length yields itself');
- t.equal(callBound('%Array.length%'), Array.length, '%Array.length% yields itself');
-
- // static non-function object
- t.equal(callBound('Array.prototype'), Array.prototype, 'Array.prototype yields itself');
- t.equal(callBound('%Array.prototype%'), Array.prototype, '%Array.prototype% yields itself');
- t.equal(callBound('Array.constructor'), Array.constructor, 'Array.constructor yields itself');
- t.equal(callBound('%Array.constructor%'), Array.constructor, '%Array.constructor% yields itself');
-
- // static function
- t.equal(callBound('Date.parse'), Date.parse, 'Date.parse yields itself');
- t.equal(callBound('%Date.parse%'), Date.parse, '%Date.parse% yields itself');
-
- // prototype primitive
- t.equal(callBound('Error.prototype.message'), Error.prototype.message, 'Error.prototype.message yields itself');
- t.equal(callBound('%Error.prototype.message%'), Error.prototype.message, '%Error.prototype.message% yields itself');
-
- var x = callBound('Object.prototype.toString');
- var y = callBound('%Object.prototype.toString%');
-
- // prototype function
- t.notEqual(x, Object.prototype.toString, 'Object.prototype.toString does not yield itself');
- t.notEqual(y, Object.prototype.toString, '%Object.prototype.toString% does not yield itself');
- t.equal(x(true), Object.prototype.toString.call(true), 'call-bound Object.prototype.toString calls into the original');
- t.equal(y(true), Object.prototype.toString.call(true), 'call-bound %Object.prototype.toString% calls into the original');
-
- t['throws'](
- // @ts-expect-error
- function () { callBound('does not exist'); },
- SyntaxError,
- 'nonexistent intrinsic throws'
- );
- t['throws'](
- // @ts-expect-error
- function () { callBound('does not exist', true); },
- SyntaxError,
- 'allowMissing arg still throws for unknown intrinsic'
- );
-
- t.test('real but absent intrinsic', { skip: typeof WeakRef !== 'undefined' }, function (st) {
- st['throws'](
- function () { callBound('WeakRef'); },
- TypeError,
- 'real but absent intrinsic throws'
- );
- st.equal(callBound('WeakRef', true), undefined, 'allowMissing arg avoids exception');
- st.end();
- });
-
- t.end();
-});
diff --git a/server/node_modules/call-bound/tsconfig.json b/server/node_modules/call-bound/tsconfig.json
deleted file mode 100644
index 8976d98..0000000
--- a/server/node_modules/call-bound/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "@ljharb/tsconfig",
- "compilerOptions": {
- "target": "ESNext",
- "lib": ["es2024"],
- },
- "exclude": [
- "coverage",
- ],
-}
diff --git a/server/node_modules/cloudinary/CHANGELOG.md b/server/node_modules/cloudinary/CHANGELOG.md
deleted file mode 100644
index bceaa8f..0000000
--- a/server/node_modules/cloudinary/CHANGELOG.md
+++ /dev/null
@@ -1,1040 +0,0 @@
-2.7.0 / 2025-06-18
-==================
-
-* fix: prevent parameter injection via ampersand in parameter values (#709)
-
-2.6.1 / 2025-05-05
-==================
-
-
-
-2.6.1-rc.1 / 2025-05-05
-==================
-
-* fix: uploader interface
-
-2.6.0 / 2025-03-11
-==================
-
- * chore: bumped jsdoc
- * fix: defaults for related asset methods and proper content_type
- * chore: Updated Sample Projects (#698)
- * fix: metadata field datasource type (#693)
- * feat: Add support for DELETE /resources/backup/:asset_id (#700)
- * chore: dev dependencies cleanup
- * chore: new node version support in CI
-
-2.5.1 / 2024-10-08
-==================
-
-* fix: added missing stream method to ts spec
-
-2.5.0 / 2024-09-15
-==================
-
-* feat: auto_transcription on upload and explicit support (#690)
-* feat: auto_chaptering on upload and explicit support (#689)
-* feat: access key management via provisioning api (#687)
-
-2.4.0 / 2024-07-30
-==================
-
-* feat: exposing config endpoint from admin api
-* fix: update metadata field added missing param default_disabled
-* fix: types definitions
-
-
-2.3.1 / 2024-07-25
-==================
-
-* fix: use 0.0.0 as fallback when package.json unavailable
-* fix: upload_chunked_stream works properly with more than 2 chunks
-
-2.3.0 / 2024-07-16
-==================
-
- * fix: url analytics property name
- * fix: dependencies explicit version (fix for CI)
- * fix: decoding transformation string before sending in upload payload
- * feat: update folders
-
-2.2.0 / 2024-04-22
-==================
-
-* feat: selective response for admin and search api
-* feat: multiple values support for fields and with_field methods in search api
-
-2.1.0 / 2024-03-29
-==================
-
- * feat: added support for new api in beta - analyze api
- * chore: added state to datasource entry type
- * fix: metadata field api response datasource type improved
- * feat: notification-url for rename and destroy methods
-
-2.0.3 / 2024-03-05
-==================
-
-* fix: file and field encoding fixed for next.js production build
-
-2.0.2 / 2024-03-01
-==================
-
-* fix: custom regions
-
-2.0.1 / 2024-02-07
-==================
-
- * fix: search expression not required
- * chore: proxy-agent not needed any more
- * chore: cleanup
- * feat: supporting new analytics options, changed analytics algorithm
-
-2.0.0 / 2024-01-29
-==================
-
-
-
-2.0.0-rc.1 / 2024-01-18
-==================
-
-
-
-2.0.0-rc / 2024-01-08
-==================
-
-* feat!: secure option from config set to true by default
-* feat!: url analytics enabled by default
-* feat!: dropped Node@6 and Node@8
-
-1.41.1 / 2023-12-18
-==================
-
- * fix: sending restrictions when creating or updating metadata fields
-
-1.41.0 / 2023-09-26
-==================
-
-* fix: improved calculation of the signature in url
-* fix: improved ResourceApiResponse interface
-* fix: fetch overlay video creates correct transformation
-* feat: added support for on_success script for uploader_spec.js
-
-1.40.0 / 2023-07-31
-==================
-
-* feat: visual search api
-* fix: adding clear_invalid only when not null
-
-1.39.0 / 2023-07-24
-==================
-
-* feat: basic asset relations api
-
-1.38.0 / 2023-07-20
-==================
-
- * feat: new method to_url added to support cached search feature
-
-1.37.3 / 2023-06-26
-==================
-
-* fix: native http agent used instead of an external dependency
-
-1.37.2 / 2023-06-19
-==================
-
-* chore: bumped npm override for vm2 to latest
-
-1.37.1 / 2023-06-09
-==================
-
- * chore: removing ts installed with dtslint to prevent fails on older node.js
- * fix: only explicit require used
- * fix: upgrade core-js from 3.30.1 to 3.30.2
-
-1.37.0 / 2023-05-16
-==================
-
-* feat: exposing structured metadata rules api
-
-1.36.4 / 2023-05-02
-==================
-
-fix: isRemoteUrl check improved to reduce false positives
-
-1.36.3 / 2023-05-02
-==================
-
- * fix: smd number field allows both numbers and string when uploading
- * fix: isRemoteUrl not working on big files sometimes
-
-1.36.2 / 2023-04-24
-==================
-
-fix: bumped vm2 override to latest
-
-1.36.1 / 2023-04-13
-==================
-
-chore: overriding vulnerable transitive dependency
-
-1.36.0 / 2023-04-13
-==================
-
-* feat: add support for `media_metadata` param for `upload` and `explicit`
-* feat: passing context and metadata when using rename
-
-1.35.0 / 2023-03-03
-==================
-
- * fix: removing nested nulls from options passed to api, closes #581
- * feat: add option to configure tracked analytics
-
-1.34.0 / 2023-02-13
-==================
-
- * fix: resource_type is not optional
- * feat: search for folders
- * feat: support for extra_headers in upload request
-
-1.33.0 / 2022-12-15
-==================
-
- * feat: start and end offset normalized in a transformation string
- * feat: new config option for hiding sensitive data when logging errors
- * feat: multiple ACLs for generate_auth_token
- * fix: improved TS typing
-
-1.32.0 / 2022-09-14
-==================
-
-* Add dynamic folder feature (#559)
-
-
-1.31.0 / 2022-08-28
-==================
-
- * Update core-js package (#558)
- * Add download_backedup_asset typings (#557)
-
-
-1.30.1 / 2022-07-21
-==================
-
-* Bump lodash version to 4.17.21 (#551)
-* Add types for verifyNotificationSignature (#555)
-
-
-1.30.0 / 2022-05-15
-==================
-
- * Add filename_override option to types (#548)
-
-
-1.29.1 / 2022-04-17
-==================
-
- * Fix support of the lowercase response headers (#545)
- * Fix tags function type definition (#544)
-
-
-1.29.0 / 2022-03-24
-==================
-
-New functionality
------------------
-* Add support for `resources_by_asset_ids` Admin API (#529)
-* Add support for `reorder_metadata_fields` Admin API (#526)
-
-Other changes
------------------
- * bump bson version (#541)
- * bumbed ejs version in photo_album (#540)
- * Add Travis configuration for node 16 (#535)
- * Stabilize OCR tests (#533)
- * update README (#528)
- * Stabilize metadata tests (#530)
-
-
-1.28.1 / 2022-01-06
-==================
-
-* Bump proxy-agent version to ^5.0.0 due to vulnerability
-
-1.28.0 / 2022-01-02
-==================
-
-New functionality
------------------
- * Add support for folder decoupling (#523)
- * Add support for `resource_by_asset_id` Admin API (#522)
- * Add proxy support (#518)
-
-Other changes
------------------
- * Add tests for expression normalization (#521)
-
-1.27.1 / 2021-10-11
-==================
-
- * Add node version to user agent (#519)
-
-
-1.27.0 / 2021-09-12
-==================
-
-* Fix: `verifyNotificationSignature` timestamps are in seconds (#515)
- * Allow multi and sprite with urls, add download_generated_sprite and download_multi methods (#493)
- * Prevent preview:duration from being normalized (#513)
- * Prevent duplicate search fields in search api (#510)
- * Add support for create_slideshow Upload API (#508)
- * Add support for variables in text style (#507)
-
-
-1.26.3 / 2021-08-01
-==================
-
- * Add update_metada type to upload api (#500)
- * Return structured metadata in resources APIs (#503)
-
-1.26.2 / 2021-07-04
-==================
-
- * fixed font_family encoding (#498)
-
-
-1.26.1 / 2021-06-22
-==================
-
- * updated sent upload params (#497)
- * Improve the return type of cloudinary.v2.config() in TypeScript (#494)
-
-
-1.26.0 / 2021-06-06
-==================
-
-Add support for oauth authorization (#489)
-
-
-1.25.2 / 2021-05-30
-==================
-
-Other Changes
- * Fix - Remove file extensions from require statements (#490)
- * Fix - Add support for complex variable names (aheight) (#488)
- * Fix - #486 - upload_prefix configuration retrieval (#487)
-
-
-
-1.25.1 / 2021-03-22
-==================
-
- * Fix/unhandled promise rejection call api (#481)
- * Fix return type of api_url function(return String instead of Promise) (#483)
- * Add SHA-256 support for auth signatures (#479)
-
-1.25.0 / 2021-02-22
-==================
-
-New functionality
------------------
-* Add sort by metadata field (#474)
-* Add filename override param (#471)
-
-Other changes
--------------
-* Add safe base64 to all url generation (#477)
-* Fix config backup in sign requests test (#476)
-* Add missing types to create/delete_folder and private_download_url (#473)
-* Add validation to genreate_auth_token to enforce url or acl (#472)
-
-
-
- 1.24.0 / 2021-01-31
-=============
-
-New functionality and features
-------------------------------
- * Add `accessibility_analysis` parameter support (#463)
- * Add support for date parameter in usage API (#467)
-
-Other Changes
--------------
- * Change test for `eval` upload parameter (#468)
- * Update docstring for normalize_expression (#461)
- * Fix secure_distribution has type (#462)
- * Remove unused parameter from archive_params (#454)
- * Fix type of generate_auth_token options (#448)
- * Set the provisioning API config as optional (#451)
- * Encode all URI components when building a URL in base_api_url() (#447)
- * Generate url-safe base64 strings in remote custom functions (#446)
-
-1.23.0 / 2020-08-26
-===================
-New functionality and features
-------------------------------
-* Add support for pending, prefix, and sub_account_id to users method (#417)
-* Add support for metadata array value (#433)
-* Detect data URLs with suffix in mime type (#418)
-* Add support for download backedup asset function (#415)
-* Add support `max_results` and `next_cursor` in `root_folders` and `sub_folders` (#411)
-* Add download_folder method (#404)
-
-Other Changes
--------------
-* Added linter rules (#423)
-* Fix docstring for pending parameter of the users method (#436)
-* Fix invalid detection failing test (#439)
-* Test: Ignore URL in AuthToken generation if ACL is provided (#431)
-* Add pull_request_template.md (#435)
-* Fix and improve docstring for download_folder() (#434)
-* Refactor `pickOnlyExistingValues()` function (#432)
-* Add tests for new OCR features (#385)
-
-
-1.22.0 / 2020-06-08
-==================
-
-
-New functionality and features
-------------------------------
- * Feature encode sdk version (#371)
- * Add support for cinemagraph_analysis parameter in upload, explicit, and resource (#391)
- * Support for creating folders using Admin API (#370)
- * Add support for pow operator in expressions (#386)
- * Feature/support download backup version api (#380)
- * Fix normalize_expression when variable is named like a keyword (e.g., ) (#367)
- * Add support for 32 char SHA-256 signatures (#368)
-
- Other Changes
- -------------
- * Add missing types for sign-request (#398)
- * Add deprecation warning for node 6, add tests for node 14 (#389)
- * Add linter (#388)
- * Fix incorrect text implementation for list resources(#382)
- * Update issue templates (#365)
-
-
-
-
-
-
-1.21.0 / 2020-03-29
-==================
-
-New functionality and features
-------------------------------
- * Add types for Structured Metadata functions (#359)
- * Added types for upload response callback (#360)
- * Updated promise types for resources methods (#358)
-
-Other Changes
--------------
- * Add back to responses sent from Admin API (#361)
- * Align all structured metadata tests with reference implementation (#351)
- * Improve provisioning api tests (#354)
- * Refactor in a wait period for eager uploads (#355)
-
-
-1.20.0 / 2020-03-11
-==================
-
-New functionality and features
-------------------------------
- * Add support for sources in video tag (#265)
- * Add support multiple resource_types in ZIP generation (#348)
- * Add API support for account/provisioning (#343)
- * Add filename options (#273)
- * Add use_filename option (#274)
- * Support quality_override param for update and explicit api (#242)
-
- Other Changes
- -------------
- * Refactor out a duplicate test (#353)
- * Refactor the order of the assertions in account_spec (#352)
- * Fix type defs for stream upload methods (#336)
- * Remove typings spec and config from npm package
- * Add automation to delete the es5-lib dir when npm run compile is run
- * Move typescript to devDependencies and update version
- * Refactor out utils functions
-
-1.19.0 / 2020-01-20
-==================
-
-New functionality and features
-------------------------------
- * Add structured metadata support
- * Add verifyNotificationSignature()
-
-Other Changes
--------------
- * Fix isRemoteUrl to correctly detect docx files
- * Fix named transformations with spaces
- * Fix/fixed type def for upload stream
- * Add name to errors in uploader.js
-
-1.18.1 / 2019-12-11
-==================
-
-* Fix acl and url escaping in auth_token generation
-
-1.18.0 / 2019-12-09
-===================
-
- New functionality
- -----------------
- * Add live parameter to create_upload_preset and update_upload_preset
-
- Other changes
- -------------
- * Fixed tests on Utils and Cloudinary_spec and removed a duplicate one
-
-
-1.17.0 / 2019-11-11
-===================
-
- * Update ejs dependency in photo album
- * Add Type Script declaration file
-
-1.16.0 / 2019-10-15
-===================
-
- * Support different radius for each corner (containing images and overlays) (#260)
- * Add feature to allow override on timestamp and signature (#295)
- * remove package-lock (#303)
- * Fixed open linting issues (#279)
- * Feature/publish script (#289)
- * Fix parameters sent when creating a text image (#298)
- * Add custom pre function support (#302)
- * Escape quotes in HTML attributes (#259)
-
-1.15.0 / 2019-09-08
-===================
-
-New functionality
------------------
-
-* Add 'derived_next_resource' to api.resource method
-* Add support for 'delete folder' API
-* Add support for remote/local function invocation (fn:remote and fn:wasm) (#261)
-* Add antialiasing and hinting
-* Add `force_version` transformation parameterAdd automatic JavaScript linting and fix existing code conflicts (#262)
-* Add automatic JavaScript linting and fix existing code conflicts (#262)
-
-Other changes
--------------
- * Mock upload preset listing test
- * Feature/duration to condition video
- * Update test for change moderation status
- * Simplified error assertions in a few test specs
- * Fix base64 URL validation
- * Rearrange util tests
- * Test support of `async` option in explicit api
- * Remove unnecessary return statements and options from tests
- * Remove unnecessary use of options and API in access_control_spec.js
- * Merge pull request #239 from tornqvist/remove-coffeescript-transform
- * Remove coffee script deps and transform
-
-1.14.0 / 2019-03-26
-===================
-
-New functionality
------------------
-
- * Support format in transformation API
- * Add support for `start_offset` value `auto`
- * Add support for gs:// urls in uploader
- * Add support for the `quality_analysis` upload parameter. Fixes #171
- * Add `fps` transformation parameter (#230)
-
-Other changes
--------------
-
- * Update code samples in the README file. Fixes #135
- * Reject deferred on request error. Fixes #136
- * Refactor test code after conversion from CoffeeScript
- * Convert test code from CoffeeScript to JavaScript
- * Merge pull request #208 from cloudinary/fix_update_samples_readme
- * Fix the "upload large" test for node 4
- * Remove bower from the sample code
- * Add timeout to search integration tests
- * Fix detection test
- * Fix broken links in node sample project readme
-
-1.13.2 / 2018-11-14
-===================
-
- * Use a new timestamp for each chunk in `upload_large` API
-
-1.13.1 / 2018-11-13
-===================
-
- * Filter files in the npm package
- * Add polyfill for `Object.entries`
- * Add `update_version` script
-
-1.13.0 / 2018-11-13
-===================
-
- * Support listing of named transformations using the `named` parameter
- * Fix Node version check. Fixes #217
-
-1.12.0 / 2018-11-08
-===================
-
-New functionality
------------------
-
- * Add Responsive Breakpoints cache
- * Add `picture` and `source` tags
- * Add fetch support to overlay/underlay (#189)
- * Add async param to uploader (#193)
-
-Other changes
--------------
-
- * Convert CoffeeScript source to JavaScript
- * Refactor compiled coffee to proper JS
- * Remove old lib files
- * Move all sources from `src` to `lib`
- * Move `cloudinary.js` inside the src folder
- * Setup library and tests to run with either es6 or es5
- * Apply babel to support older Node versions
- * Refactor tests to use promises
- * Fix Tests
- * Refactor utils
- * Move utils.js to utils folder
- * Add `ensurePresenceOf` and `rimraf` utility functions
- * Add `nyc` for coverage and update sinon
- * Add "Join the Community" (#201)
- * Use upload params in explicit API
- * Fix raw convert test
-
-1.11.0 / 2018-03-19
-===================
-
-New functionality
------------------
-
- * Add `access_control` parameter to `upload` and `update`
-
-Other changes
--------------
-
- * Mock `delete_all_resources` test
- * Add `compileTests` script to `package.json`
- * Add http/https handling to spec helper
- * Mock moderation tests
- * Fix `categorization` test
- * Remove `similiarity_search` test
- * Add test helper functions
- * Add utility functions to `utils`
- * Replace lodash's `_` with explicitly requiring methods
-
-1.10.0 / 2018-02-13
-===================
-
-New functionality
------------------
-
- * Support url suffix for shared CDN
- * Add Node 8 to Travis CI tests and remove secure variables
- * Fix breakpoints format parameter
- * Extend support of url_suffix for different resource types
- * Add support for URLs in upload_large
- * Add support for transformations parameter in delete_resources api
- * Add support for delete_derived_by_transformation
- * Add format parameter support to responsive-breakpoints encoder
- * Add expires_at parameter to archive_params
- * Add `faces` parameter to the `explicit` API
-
-Other changes
--------------
-
- * Fix typos
- * Test transformations api with next_cursor
- * add test cases of ocr for upload and url generation
- * add test case of conditional tags
- * Update dependencies
- * Fix tests
- * Remove tests for `auto_tagging`
-
-1.9.1 / 2017-10-24
-==================
-
- * Decode string to sign before creating the signature (#167)
- * Update Readme to point to HTTPS URLs of cloudinary.com
- * Update lib files
- * Ignore error when `.env` file is missing.
- * Remove CoffeeScript header
- * Add `lib\v2\search.js` to git.
-
-1.9.0 / 2017-04-30
-==================
-
-New functionality
------------------
-
- * Add Search API
- * Add support for `type` parameter in publish-resources api
- * Add support for `keyframe-interval` (ki) video manipulation parameter
- * Added parameters `allow_missing` and `skip_transformation_name` to generate-archive api
- * Add support for `notification-url` parameter to update API
- * Support = and | characters within context values using escaping + test (#143)
-
-Other changes
--------------
-
- * Test/upgrade mocha (#142)
- * fix bad escaping of special characters in certain scenarios + tests (#140) Fixes #138
- * Don't normalize negative numbers.
- * Fix typo: rename `min` to `sub`
-
-1.8.0 / 2017-03-09
-==================
-
- * Add User Defined Variables
-
-1.7.1 / 2017-02-23
-==================
-
- * Refactor `generate_auth_token`
- * Update utils documentation.
- * Add URL authorization token.
- * Rename token function.
- * Support nested keys in CLOUDINARY_URL
- * Allow tests to run concurrently
-
-1.7.0 / 2017-02-08
-==================
-
-New functionality
------------------
-
- * Add access mode API
-
-Other changes
--------------
-
- * Rework tests cleanup
- * Use TRAVIS_JOB_ID to make test tags unique
-
-1.6.0 / 2017-01-30
-==================
-
-New functionality
------------------
-
- * Add Akamai token generator
- * Add Search resource by context
-
-Other changes
--------------
-
- * Use http library when api protocol is set to http patch
- * Added timeouts to spec in order to force consistency
- * Fix publish API test cleanup
- * Use random suffix in api tests
- * Use binary encoding for signature
- * Add coffee watch
- * Fixed async issues with before queue
- * Add missing options to explicit api call
-
-1.5.0 / 2016-12-29
-==================
-
-New functionality
------------------
-
- * `add_context` & `remove_all_context` API
- * Add `data-max-chunk-size` to input created by `image_upload_tag`
- * Add `moderation` and `phash` parameters to explicit API
-
-
-Other changes
--------------
-
- * Modify Travis configuration to test NodeJS v4 and v6 only.
- * Modify `TEST_TAG`
- * Use Sinon spy in `start_at` test
- * Support context as hash argument in context API
- * Delete streaming profiles after tests
- * Fix signing URL tests, Fixes #89
- * Add timeout to delete streaming profile test
- * add tests for add_context & remove_all_context
- * add add_context & remove_all_context methods
- * fix test description
- * add test to phash in an explicit call
- * add test to moderation parameter in an explicit call
- * Add test to accepts {effect: art:incognito}
- * support phash in explicit call
- * Fix missing moderation parameter in an explicit call
- * Fix `nil` to `null`. Call `config()` with parameter name.
-
-1.4.6 / 2016-11-25
-==================
-
- * Merge pull request #118 from cloudinary/explicit-eager-transformations
- * Support multiple eager transformations with explicit api
-
-1.4.5 / 2016-11-25
-==================
-
-New functionality
------------------
-
- * Add `remove_all_tags` API
- * Add `streaming_profile` transformation parameter.
-
-Other changes
--------------
-
- * Fix face coordinates test
- * Sort parameters
- * Support `http` mode for tests.
- * Add tests for gravity modes
-
-1.4.4 / 2016-10-27
-==================
-
-New functionality
------------------
-
- * Add streaming profiles API
-
-Other changes
--------------
-
- * Change email address in sample project's bower.json
- * Add files to `.npmignore`
-
-1.4.3 / 2016-10-27
-==================
-
-1.4.2 / 2016-09-14
-==================
-
-New functionality
------------------
-
- * Add publish API: `publish_by_prefix`, `publish_by_public_ids`, `publish_by_tag`.
- * Add `to_type` to `rename`.
-
-Other changes
--------------
-
- * Get version in `utils` from `package.json`
- * Fix tests.
-
-1.4.1 / 2016-06-22
-==================
-
-Other changes
--------------
-
- * Fix #105 #106 - url generation broken width numeric width parameter
-
-1.4.0 / 2016-06-22
-==================
-
-New functionality
------------------
-
- * New configuration parameter `:client_hints`
- * Enhanced auto `width` values
- * Enhanced `quality` values
- * Add `next_cursor` to `transformation`
-
-Other changes
--------------
-
- * Remove redundant `max_results` from `upload_preset`
- * Add tests for `max_results` and `next_cursor`
- * Refactor explicit with invalidate test
- * Fix double slash replacement
- * Fix "should allow listing resources by start date" test
-
-1.3.1 / 2016-04-04
-==================
-
-New functionality
------------------
-
- * Conditional transformations
-
-Other changes
--------------
-
- * Add error handling to test
- * Fix categorization test
- * Update sample project to use the new cloudinary_js library.
- * Change explicit test to simple eager instead of twitter
- * Add `*.js` and `*.map` to gitignore.
- * Merge pull request #87 from bompus/util-speedup-2
- * optimized speed of generate_transformation_string, removed js/map files.
- * optimized speed of generate_transformation_string
- * Replace `_.include` with `_.includes` - It was removed in lodash 4.0. PR #83
- * Merge pull request #1 from cloudinary/master
- * Merge pull request #76 from joneslee85/renaming-tests
- * Use snakecase naming for spec files
- * Fix dependency of sample projects on cloudinary. Fixes #80.
- * Remove `promised-jugglingdb` - it has been deprecated. Fixes #81.
-
-1.3.0 / 2016-01-08
-==================
-
-New functionality
------------------
-
- * Add Archive functionality
- * Add responsive breakpoints.
- * Add structured text layers
- * Add upload mapping API
- * Add Restore API
- * Add new USER_AGENT format - CloudinaryNodeJS/ver
- * Add Support for `aspect_ratio` transformation parameter
- * Add invalidate to explicit. Encode public_ids array with `[]` in URL. Replace cleanup code with TEST_TAG.
- * Add "invalidate" flag to rename
- * Add support invalidate=>true in explicit for social resources
- * Support uploading large files using the new Content-Range based upload API.
-
-Other changes
--------------
- * Use `target_tags` instead of `tags` in tests.
- * Utilize spechelper
- * Add license to package, add Sinon.JS, update mocha
- * Increase timeout in tests.
- * Merge pull request #77 from joneslee85/consolidate-test-runner
- * get rid of Cakefile
-
-1.2.6 / 2015-11-19
-==================
-
- * Fix API timeout from 60ms to 60000ms
-
-1.2.5 / 2015-10-14
-==================
-
- * Add timeout to test. Compiled CoffeeScript and whitespace changes
- * Add dev dependency on `coffee-script`
- * Updated upload_large_stream tols return a stream and let the caller control the piping to it, similar to upload_stream.
- * fixes #65 - upload_large using chunk_size is corrupting data - also adds the very useful upload_large_stream function. upload_large tests now verify data integrity.
- * Add bower to the photo_album sample project.
- * Add CHANGELOG.md
-
-1.2.4 / 2015-08-09
-==================
-
- * Fix npmignore entries
-
-1.2.3 / 2015-08-09
-==================
-
- * Adding samples and test to .npmignore
-
-1.2.2 / 2015-07-19
-==================
-
- * Fix upload_large, change api signature to v2, update dependencies
- * Fix typo
- * Add tests to see if options are mutated
- * Update cloudinary.js to copy over options instead of mutating
-
-1.2.1 / 2015-04-16
-==================
-
- * Add and arrange `var` keywords. Edit video() documentation.
- * Better error handling of read stream errors
-
-1.2.0 / 2015-04-07
-==================
-
- * return delete token on direct upload in sample project
- * Reapply node 0.12 compatibility fix. Test minor cleanup
- * Correct use of _.extend
- * Support video tag generation. Support html5 attributes
- * Video support, underscore -> lodash, tests, zoom parameter, eager
- * Spelling, Tag fixes
- * Add video support
- * Fix issue with admin api on node >= 0.12
- * Override lodash's _.first to maintain compatibility with underscore version.
- * Change underscore to lodash
- * added lodash to package.json
- * compile changes after migrating from underscore to lodash
- * remove underscore from pacakge.json
- * update from underscore to lodash
-
-1.1.2 / 2015-02-26
-==================
-
- * Test fixes - resilient to test order change. Cleanup
- * Update coffeescript configuration
- * remove duplicate object key
- * remove duplicate object key
- * Support root path for shared CDN
- * added failed http.Agent test
- * override https agent
- * Allow request agent to be customized
- * fixed issue #42 Bug in samples/basic , api fully supports node.js stream api
- * Add method to generate a webhook signature.
-
-1.1.1 / 2014-12-22
-==================
-
- * invalidate in bulk deltes
- * after code review
- * precompiling coffeescript
- * all tests pass
- * fixed default type and public_id
- * utils cloudinary_url supports new signature & dns sharding
- * upload supports tags
-
-1.1.0 / 2014-12-02
-==================
-
- * Update README.md
- * Update README.md
- * fix #34 Upload stream does not support pipe
-
-1.0.13 / 2014-11-09
-===================
-
- * fixed #32 Reject promise for error codes https://github.com/cloudinary/cloudinary_npm/issues/32
- * bug fix
- * fixed #27 cloudinary.utils.sign_request doesn't read config properly
-
-1.0.12 / 2014-08-28
-===================
-
- * Skipping folder listing test in default
- * - support unsigned upload - redirect to upload form when no image was provided
- * comments
- * set explicit format (jpg)
- * moved image_upload_tag & cloudinary_js_config to view (ejs)
- * case fix
- * using Cloudinary gem to generate images and urls
- * - added cloudinary to response locals - added cloudinary configuration logging
- * ignoring bin directories (support node_monules .bin symlinks)
- * fixed v2 missing methods
- * - added root_folders & sub_folders management api + tests - fixed v2 module (requiring v2 would override v1) - fixed api promises reject a result with error attribute - added dotenv for test environment
- * ignoring bin folder
- * updated demo
- * node photo album
- * fix: changed to public api cloudinary.url
- * Fix mis-spell of deferred
- * added promise support
- * 2space indent
- * package description
- * basic samples + fix to v2 api
- * git ignore
-
-1.0.11 / 2014-07-17
-===================
-
- * Support custom_coordinates in upload, explicit and update, coordinates flag in resource details
- * Support return_delete_token flag in upload
- * Encode utf-8 when signing requests. Issue #20
- * Correctly encode parameters as utf8 in uploader API
- * Support node style callbacks and parameter order in cloudinary.v2.uploader and cloudinary.v2.api - issue #18
- * Support browserify via coffeeify.
diff --git a/server/node_modules/cloudinary/README.md b/server/node_modules/cloudinary/README.md
deleted file mode 100644
index d776cdb..0000000
--- a/server/node_modules/cloudinary/README.md
+++ /dev/null
@@ -1,103 +0,0 @@
-Cloudinary Node SDK
-=========================
-## About
-The Cloudinary Node SDK allows you to quickly and easily integrate your application with Cloudinary.
-Effortlessly optimize, transform, upload and manage your cloud's assets.
-
-
-#### Note
-This Readme provides basic installation and usage information.
-For the complete documentation, see the [Node SDK Guide](https://cloudinary.com/documentation/node_integration).
-
-## Table of Contents
-- [Key Features](#key-features)
-- [Version Support](#Version-Support)
-- [Installation](#installation)
-- [Usage](#usage)
- - [Setup](#Setup)
- - [Transform and Optimize Assets](#Transform-and-Optimize-Assets)
- - [Generate Image and HTML Tags](#Generate-Image-and-Video-HTML-Tags)
-
-
-## Key Features
-- [Transform](https://cloudinary.com/documentation/node_video_manipulation#video_transformation_examples) and
- [optimize](https://cloudinary.com/documentation/node_image_manipulation#image_optimizations) assets.
-- Generate [image](https://cloudinary.com/documentation/node_image_manipulation#deliver_and_transform_images) and
- [video](https://cloudinary.com/documentation/node_video_manipulation#video_element) tags.
-- [Asset Management](https://cloudinary.com/documentation/node_asset_administration).
-- [Secure URLs](https://cloudinary.com/documentation/video_manipulation_and_delivery#generating_secure_https_urls_using_sdks).
-
-
-
-## Version Support
-| SDK Version | Node version |
-|-------------|--------------|
-| 1.x.x | Node@6 & up |
-| 2.x.x | Node@9 & up |
-
-## Installation
-```bash
-npm install cloudinary
-```
-
-# Usage
-### Setup
-```js
-// Require the Cloudinary library
-const cloudinary = require('cloudinary').v2
-```
-
-### Transform and Optimize Assets
-- [See full documentation](https://cloudinary.com/documentation/node_image_manipulation).
-
-```js
-cloudinary.url("sample.jpg", {width: 100, height: 150, crop: "fill", fetch_format: "auto"})
-```
-
-### Upload
-- [See full documentation](https://cloudinary.com/documentation/node_image_and_video_upload).
-- [Learn more about configuring your uploads with upload presets](https://cloudinary.com/documentation/upload_presets).
-```js
-cloudinary.v2.uploader.upload("/home/my_image.jpg", {upload_preset: "my_preset"}, (error, result)=>{
- console.log(result, error);
-});
-```
-### Large/Chunked Upload
-- [See full documentation](https://cloudinary.com/documentation/node_image_and_video_upload#node_js_video_upload).
-```js
- cloudinary.v2.uploader.upload_large(LARGE_RAW_FILE, {
- chunk_size: 7000000
- }, (error, result) => {console.log(error)});
-```
-### Security options
-- [See full documentation](https://cloudinary.com/documentation/solution_overview#security).
-
-## Contributions
-- Ensure tests run locally (add test command)
-- Open a PR and ensure Travis tests pass
-
-
-## Get Help
-If you run into an issue or have a question, you can either:
-- Issues related to the SDK: [Open a Github issue](https://github.com/cloudinary/cloudinary_npm/issues).
-- Issues related to your account: [Open a support ticket](https://cloudinary.com/contact)
-
-
-## About Cloudinary
-Cloudinary is a powerful media API for websites and mobile apps alike, Cloudinary enables developers to efficiently manage, transform, optimize, and deliver images and videos through multiple CDNs. Ultimately, viewers enjoy responsive and personalized visual-media experiences—irrespective of the viewing device.
-
-
-## Additional Resources
-- [Cloudinary Transformation and REST API References](https://cloudinary.com/documentation/cloudinary_references): Comprehensive references, including syntax and examples for all SDKs.
-- [MediaJams.dev](https://mediajams.dev/): Bite-size use-case tutorials written by and for Cloudinary Developers
-- [DevJams](https://www.youtube.com/playlist?list=PL8dVGjLA2oMr09amgERARsZyrOz_sPvqw): Cloudinary developer podcasts on YouTube.
-- [Cloudinary Academy](https://training.cloudinary.com/): Free self-paced courses, instructor-led virtual courses, and on-site courses.
-- [Code Explorers and Feature Demos](https://cloudinary.com/documentation/code_explorers_demos_index): A one-stop shop for all code explorers, Postman collections, and feature demos found in the docs.
-- [Cloudinary Roadmap](https://cloudinary.com/roadmap): Your chance to follow, vote, or suggest what Cloudinary should develop next.
-- [Cloudinary Facebook Community](https://www.facebook.com/groups/CloudinaryCommunity): Learn from and offer help to other Cloudinary developers.
-- [Cloudinary Account Registration](https://cloudinary.com/users/register/free): Free Cloudinary account registration.
-- [Cloudinary Website](https://cloudinary.com): Learn about Cloudinary's products, partners, customers, pricing, and more.
-
-
-## Licence
-Released under the MIT license.
diff --git a/server/node_modules/cloudinary/babel.config.js b/server/node_modules/cloudinary/babel.config.js
deleted file mode 100644
index d9defe8..0000000
--- a/server/node_modules/cloudinary/babel.config.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const presets = [
- [
- [
- "env",
- {
- targets: { node: "4" }
- }
- ],
- "stage-0"
- ]
-];
-const plugins = ["transform-object-rest-spread"];
-
-module.exports = { presets, plugins };
diff --git a/server/node_modules/cloudinary/cloudinary.js b/server/node_modules/cloudinary/cloudinary.js
deleted file mode 100644
index f13597a..0000000
--- a/server/node_modules/cloudinary/cloudinary.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('./lib/cloudinary');
diff --git a/server/node_modules/cloudinary/lib/analysis/index.js b/server/node_modules/cloudinary/lib/analysis/index.js
deleted file mode 100644
index 3a42551..0000000
--- a/server/node_modules/cloudinary/lib/analysis/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const utils = require("../utils");
-const {call_analysis_api} = require('../api_client/call_analysis_api');
-
-function analyze_uri(uri, analysis_type, options = {}, callback) {
- const params = {
- uri,
- analysis_type
- }
-
- if (analysis_type === 'custom') {
- if (!('model_name' in options) || !('model_version' in options)) {
- throw new Error('Setting analysis_type to "custom" requires additional params: "model_name" and "model_version"');
- }
- params.parameters = {
- custom: {
- model_name: options.model_name,
- model_version: options.model_version
- }
- }
- }
-
- let api_uri = ['analysis', 'analyze', 'uri'];
- return call_analysis_api('POST', api_uri, params, callback, options);
-}
-
-module.exports = {
- analyze_uri
-};
diff --git a/server/node_modules/cloudinary/lib/api.js b/server/node_modules/cloudinary/lib/api.js
deleted file mode 100644
index f5a598d..0000000
--- a/server/node_modules/cloudinary/lib/api.js
+++ /dev/null
@@ -1,719 +0,0 @@
-const utils = require("./utils");
-const call_api = require("./api_client/call_api");
-
-const {
- extend,
- pickOnlyExistingValues
-} = utils;
-
-const TRANSFORMATIONS_URI = "transformations";
-
-function deleteResourcesParams(options, params = {}) {
- return extend(params, pickOnlyExistingValues(options, "keep_original", "invalidate", "next_cursor", "transformations"));
-}
-
-function getResourceParams(options) {
- return pickOnlyExistingValues(options, "exif", "cinemagraph_analysis", "colors", "derived_next_cursor", "faces", "image_metadata", "media_metadata", "pages", "phash", "coordinates", "max_results", "versions", "accessibility_analysis", 'related', 'related_next_cursor');
-}
-
-exports.ping = function ping(callback, options = {}) {
- return call_api("get", ["ping"], {}, callback, options);
-};
-
-exports.usage = function usage(callback, options = {}) {
- const uri = ["usage"];
-
- if (options.date) {
- uri.push(options.date);
- }
-
- return call_api("get", uri, {}, callback, options);
-};
-
-exports.resource_types = function resource_types(callback, options = {}) {
- return call_api("get", ["resources"], {}, callback, options);
-};
-
-exports.resources = function resources(callback, options = {}) {
- let resource_type, type, uri;
- resource_type = options.resource_type || "image";
- type = options.type;
- uri = ["resources", resource_type];
- if (type != null) {
- uri.push(type);
- }
- if ((options.start_at != null) && Object.prototype.toString.call(options.start_at) === '[object Date]') {
- options.start_at = options.start_at.toUTCString();
- }
- return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "prefix", "tags", "context", "direction", "moderations", "start_at", "metadata", "fields"), callback, options);
-};
-
-exports.resources_by_tag = function resources_by_tag(tag, callback, options = {}) {
- let resource_type, uri;
- resource_type = options.resource_type || "image";
- uri = ["resources", resource_type, "tags", tag];
- return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations", "metadata", "fields"), callback, options);
-};
-
-exports.resources_by_context = function resources_by_context(key, value, callback, options = {}) {
- let params, resource_type, uri;
- resource_type = options.resource_type || "image";
- uri = ["resources", resource_type, "context"];
- params = pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations", "metadata", "fields");
- params.key = key;
- if (value != null) {
- params.value = value;
- }
- return call_api("get", uri, params, callback, options);
-};
-
-exports.resources_by_moderation = function resources_by_moderation(kind, status, callback, options = {}) {
- let resource_type, uri;
- resource_type = options.resource_type || "image";
- uri = ["resources", resource_type, "moderations", kind, status];
- return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations", "metadata", "fields"), callback, options);
-};
-
-exports.resource_by_asset_id = function resource_by_asset_id(asset_id, callback, options = {}) {
- const uri = ["resources", asset_id];
- return call_api("get", uri, getResourceParams(options), callback, options);
-}
-
-exports.resources_by_asset_folder = function resources_by_asset_folder(asset_folder, callback, options = {}) {
- let params, uri;
- uri = ["resources", 'by_asset_folder'];
- params = pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "moderations", "fields");
- params.asset_folder = asset_folder;
- return call_api("get", uri, params, callback, options);
-};
-
-exports.resources_by_asset_ids = function resources_by_asset_ids(asset_ids, callback, options = {}) {
- let params, uri;
- uri = ["resources", "by_asset_ids"];
- params = pickOnlyExistingValues(options, "tags", "context", "moderations", "fields");
- params["asset_ids[]"] = asset_ids;
- return call_api("get", uri, params, callback, options);
-}
-
-exports.resources_by_ids = function resources_by_ids(public_ids, callback, options = {}) {
- let params, resource_type, type, uri;
- resource_type = options.resource_type || "image";
- type = options.type || "upload";
- uri = ["resources", resource_type, type];
- params = pickOnlyExistingValues(options, "tags", "context", "moderations", "fields");
- params["public_ids[]"] = public_ids;
- return call_api("get", uri, params, callback, options);
-};
-
-exports.resource = function resource(public_id, callback, options = {}) {
- let resource_type, type, uri;
- resource_type = options.resource_type || "image";
- type = options.type || "upload";
- uri = ["resources", resource_type, type, public_id];
- return call_api("get", uri, getResourceParams(options), callback, options);
-};
-
-exports.restore = function restore(public_ids, callback, options = {}) {
- options.content_type = 'json';
- let resource_type, type, uri;
- resource_type = options.resource_type || "image";
- type = options.type || "upload";
- uri = ["resources", resource_type, type, "restore"];
- return call_api("post", uri, {
- public_ids: public_ids,
- versions: options.versions
- }, callback, options);
-};
-
-exports.update = function update(public_id, callback, options = {}) {
- let params, resource_type, type, uri;
- resource_type = options.resource_type || "image";
- type = options.type || "upload";
- uri = ["resources", resource_type, type, public_id];
- params = utils.updateable_resource_params(options);
- if (options.moderation_status != null) {
- params.moderation_status = options.moderation_status;
- }
- if (options.clear_invalid != null) {
- params.clear_invalid = options.clear_invalid;
- }
- return call_api("post", uri, params, callback, options);
-};
-
-exports.delete_resources = function delete_resources(public_ids, callback, options = {}) {
- let resource_type, type, uri;
- resource_type = options.resource_type || "image";
- type = options.type || "upload";
- uri = ["resources", resource_type, type];
- return call_api("delete", uri, deleteResourcesParams(options, {
- "public_ids[]": public_ids
- }), callback, options);
-};
-
-exports.delete_resources_by_prefix = function delete_resources_by_prefix(prefix, callback, options = {}) {
- let resource_type, type, uri;
- resource_type = options.resource_type || "image";
- type = options.type || "upload";
- uri = ["resources", resource_type, type];
- return call_api("delete", uri, deleteResourcesParams(options, {
- prefix: prefix
- }), callback, options);
-};
-
-exports.delete_resources_by_tag = function delete_resources_by_tag(tag, callback, options = {}) {
- let resource_type, uri;
- resource_type = options.resource_type || "image";
- uri = ["resources", resource_type, "tags", tag];
- return call_api("delete", uri, deleteResourcesParams(options), callback, options);
-};
-
-exports.delete_all_resources = function delete_all_resources(callback, options = {}) {
- let resource_type, type, uri;
-
- resource_type = options.resource_type || "image";
- type = options.type || "upload";
- uri = ["resources", resource_type, type];
- return call_api("delete", uri, deleteResourcesParams(options, {
- all: true
- }), callback, options);
-};
-
-exports.delete_backed_up_assets = (assetId, versionIds, callback, options = {}) => {
- const params = deleteBackupParams(versionIds);
-
- return call_api('delete', ['resources', 'backup', assetId], params, callback, options);
-}
-
-const deleteBackupParams = (versionIds = []) => {
- return {
- "version_ids[]": Array.isArray(versionIds) ? versionIds : [versionIds]
- };
-};
-
-const createRelationParams = (publicIds = []) => {
- return {
- assets_to_relate: Array.isArray(publicIds) ? publicIds : [publicIds]
- };
-};
-
-const deleteRelationParams = (publicIds = []) => {
- return {
- assets_to_unrelate: Array.isArray(publicIds) ? publicIds : [publicIds]
- };
-};
-
-exports.add_related_assets = (publicId, assetsToRelate, callback, options = {}) => {
- const params = createRelationParams(assetsToRelate);
- const resourceType = options.resource_type || 'image';
- const type = options.type || 'upload';
- options.content_type = 'json';
- return call_api('post', ['resources', 'related_assets', resourceType, type, publicId], params, callback, options);
-};
-
-exports.add_related_assets_by_asset_id = (assetId, assetsToRelate, callback, options = {}) => {
- const params = createRelationParams(assetsToRelate);
- options.content_type = 'json';
- return call_api('post', ['resources', 'related_assets', assetId], params, callback, options);
-};
-
-exports.delete_related_assets = (publicId, assetsToUnrelate, callback, options = {}) => {
- const params = deleteRelationParams(assetsToUnrelate);
- const resourceType = options.resource_type || 'image';
- const type = options.type || 'upload';
- options.content_type = 'json';
- return call_api('delete', ['resources', 'related_assets', resourceType, type, publicId], params, callback, options);
-};
-
-exports.delete_related_assets_by_asset_id = (assetId, assetsToUnrelate, callback, options = {}) => {
- const params = deleteRelationParams(assetsToUnrelate);
- options.content_type = 'json';
- return call_api('delete', ['resources', 'related_assets', assetId], params, callback, options);
-};
-
-exports.delete_derived_resources = function delete_derived_resources(derived_resource_ids, callback, options = {}) {
- let uri;
- uri = ["derived_resources"];
- return call_api("delete", uri, {
- "derived_resource_ids[]": derived_resource_ids
- }, callback, options);
-};
-
-exports.delete_derived_by_transformation = function delete_derived_by_transformation(
- public_ids,
- transformations,
- callback,
- options = {}
-) {
- let params, resource_type, type, uri;
- resource_type = options.resource_type || "image";
- type = options.type || "upload";
- uri = "resources/" + resource_type + "/" + type;
- params = extend({
- "public_ids[]": public_ids
- }, pickOnlyExistingValues(options, "invalidate"));
- params.keep_original = true;
- params.transformations = utils.build_eager(transformations);
- return call_api("delete", uri, params, callback, options);
-};
-
-exports.tags = function tags(callback, options = {}) {
- let resource_type, uri;
- resource_type = options.resource_type || "image";
- uri = ["tags", resource_type];
- return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "prefix"), callback, options);
-};
-
-exports.transformations = function transformations(callback, options = {}) {
- const params = pickOnlyExistingValues(options, "next_cursor", "max_results", "named");
- return call_api("get", TRANSFORMATIONS_URI, params, callback, options);
-};
-
-exports.transformation = function transformation(transformationName, callback, options = {}) {
- const params = pickOnlyExistingValues(options, "next_cursor", "max_results");
- params.transformation = utils.build_eager(transformationName);
- return call_api("get", TRANSFORMATIONS_URI, params, callback, options);
-};
-
-exports.delete_transformation = function delete_transformation(transformationName, callback, options = {}) {
- const params = {};
- params.transformation = utils.build_eager(transformationName);
- return call_api("delete", TRANSFORMATIONS_URI, params, callback, options);
-};
-
-exports.update_transformation = function update_transformation(transformationName, updates, callback, options = {}) {
- const params = pickOnlyExistingValues(updates, "allowed_for_strict");
- params.transformation = utils.build_eager(transformationName);
- if (updates.unsafe_update != null) {
- params.unsafe_update = utils.build_eager(updates.unsafe_update);
- }
- return call_api("put", TRANSFORMATIONS_URI, params, callback, options);
-};
-
-exports.create_transformation = function create_transformation(name, definition, callback, options = {}) {
- const params = {name};
- params.transformation = utils.build_eager(definition);
- return call_api("post", TRANSFORMATIONS_URI, params, callback, options);
-};
-
-exports.upload_presets = function upload_presets(callback, options = {}) {
- return call_api("get", ["upload_presets"], pickOnlyExistingValues(options, "next_cursor", "max_results"), callback, options);
-};
-
-exports.upload_preset = function upload_preset(name, callback, options = {}) {
- let uri;
- uri = ["upload_presets", name];
- return call_api("get", uri, {}, callback, options);
-};
-
-exports.delete_upload_preset = function delete_upload_preset(name, callback, options = {}) {
- let uri;
- uri = ["upload_presets", name];
- return call_api("delete", uri, {}, callback, options);
-};
-
-exports.update_upload_preset = function update_upload_preset(name, callback, options = {}) {
- let params, uri;
- uri = ["upload_presets", name];
- params = utils.merge(utils.clear_blank(utils.build_upload_params(options)), pickOnlyExistingValues(options, "unsigned", "disallow_public_id", "live"));
- return call_api("put", uri, params, callback, options);
-};
-
-exports.create_upload_preset = function create_upload_preset(callback, options = {}) {
- let params, uri;
- uri = ["upload_presets"];
- params = utils.merge(utils.clear_blank(utils.build_upload_params(options)), pickOnlyExistingValues(options, "name", "unsigned", "disallow_public_id", "live"));
- return call_api("post", uri, params, callback, options);
-};
-
-exports.root_folders = function root_folders(callback, options = {}) {
- let uri, params;
- uri = ["folders"];
- params = pickOnlyExistingValues(options, "next_cursor", "max_results");
- return call_api("get", uri, params, callback, options);
-};
-
-exports.sub_folders = function sub_folders(path, callback, options = {}) {
- let uri, params;
- uri = ["folders", path];
- params = pickOnlyExistingValues(options, "next_cursor", "max_results");
- return call_api("get", uri, params, callback, options);
-};
-
-/**
- * Creates an empty folder
- *
- * @param {string} path The folder path to create
- * @param {function} callback Callback function
- * @param {object} options Configuration options
- * @returns {*}
- */
-exports.create_folder = function create_folder(path, callback, options = {}) {
- let uri;
- uri = ["folders", path];
- return call_api("post", uri, {}, callback, options);
-};
-
-exports.delete_folder = function delete_folder(path, callback, options = {}) {
- let uri;
- uri = ["folders", path];
- return call_api("delete", uri, {}, callback, options);
-};
-
-exports.rename_folder = function rename_folder(old_path, new_path, callback, options = {}) {
- let uri;
- uri = ['folders', old_path];
- let rename_folder_params = {
- to_folder: new_path
- };
- options.content_type = 'json';
- return call_api('put', uri, rename_folder_params, callback, options);
-};
-
-exports.upload_mappings = function upload_mappings(callback, options = {}) {
- let params;
- params = pickOnlyExistingValues(options, "next_cursor", "max_results");
- return call_api("get", "upload_mappings", params, callback, options);
-};
-
-exports.upload_mapping = function upload_mapping(name, callback, options = {}) {
- if (name == null) {
- name = null;
- }
- return call_api("get", 'upload_mappings', {
- folder: name
- }, callback, options);
-};
-
-exports.delete_upload_mapping = function delete_upload_mapping(name, callback, options = {}) {
- return call_api("delete", 'upload_mappings', {
- folder: name
- }, callback, options);
-};
-
-exports.update_upload_mapping = function update_upload_mapping(name, callback, options = {}) {
- let params;
- params = pickOnlyExistingValues(options, "template");
- params.folder = name;
- return call_api("put", 'upload_mappings', params, callback, options);
-};
-
-exports.create_upload_mapping = function create_upload_mapping(name, callback, options = {}) {
- let params;
- params = pickOnlyExistingValues(options, "template");
- params.folder = name;
- return call_api("post", 'upload_mappings', params, callback, options);
-};
-
-function publishResource(byKey, value, callback, options = {}) {
- let params, resource_type, uri;
- params = pickOnlyExistingValues(options, "type", "invalidate", "overwrite");
- params[byKey] = value;
- resource_type = options.resource_type || "image";
- uri = ["resources", resource_type, "publish_resources"];
- options = extend({
- resource_type: resource_type
- }, options);
- return call_api("post", uri, params, callback, options);
-}
-
-exports.publish_by_prefix = function publish_by_prefix(prefix, callback, options = {}) {
- return publishResource("prefix", prefix, callback, options);
-};
-
-exports.publish_by_tag = function publish_by_tag(tag, callback, options = {}) {
- return publishResource("tag", tag, callback, options);
-};
-
-exports.publish_by_ids = function publish_by_ids(public_ids, callback, options = {}) {
- return publishResource("public_ids", public_ids, callback, options);
-};
-
-exports.list_streaming_profiles = function list_streaming_profiles(callback, options = {}) {
- return call_api("get", "streaming_profiles", {}, callback, options);
-};
-
-exports.get_streaming_profile = function get_streaming_profile(name, callback, options = {}) {
- return call_api("get", "streaming_profiles/" + name, {}, callback, options);
-};
-
-exports.delete_streaming_profile = function delete_streaming_profile(name, callback, options = {}) {
- return call_api("delete", "streaming_profiles/" + name, {}, callback, options);
-};
-
-exports.update_streaming_profile = function update_streaming_profile(name, callback, options = {}) {
- let params;
- params = utils.build_streaming_profiles_param(options);
- return call_api("put", "streaming_profiles/" + name, params, callback, options);
-};
-
-exports.create_streaming_profile = function create_streaming_profile(name, callback, options = {}) {
- let params;
- params = utils.build_streaming_profiles_param(options);
- params.name = name;
- return call_api("post", 'streaming_profiles', params, callback, options);
-};
-
-function updateResourcesAccessMode(access_mode, by_key, value, callback, options = {}) {
- let params, resource_type, type;
- resource_type = options.resource_type || "image";
- type = options.type || "upload";
- params = {
- access_mode: access_mode
- };
- params[by_key] = value;
- return call_api("post", "resources/" + resource_type + "/" + type + "/update_access_mode", params, callback, options);
-}
-
-exports.search = function search(params, callback, options = {}) {
- options.content_type = 'json';
- return call_api("post", "resources/search", params, callback, options);
-};
-
-exports.visual_search = function visual_search(params, callback, options = {}) {
- const allowedParams = pickOnlyExistingValues(params, 'image_url', 'image_asset_id', 'text');
- return call_api('get', ['resources', 'visual_search'], allowedParams, callback, options);
-};
-
-exports.search_folders = function search_folders(params, callback, options = {}) {
- options.content_type = 'json';
- return call_api("post", "folders/search", params, callback, options);
-};
-
-exports.update_resources_access_mode_by_prefix = function update_resources_access_mode_by_prefix(
- access_mode,
- prefix,
- callback,
- options = {}
-) {
- return updateResourcesAccessMode(access_mode, "prefix", prefix, callback, options);
-};
-
-exports.update_resources_access_mode_by_tag = function update_resources_access_mode_by_tag(
- access_mode,
- tag,
- callback,
- options = {}
-) {
- return updateResourcesAccessMode(access_mode, "tag", tag, callback, options);
-};
-
-exports.update_resources_access_mode_by_ids = function update_resources_access_mode_by_ids(
- access_mode,
- ids,
- callback,
- options = {}
-) {
- return updateResourcesAccessMode(access_mode, "public_ids[]", ids, callback, options);
-};
-
-/**
- * Creates a new metadata field definition
- *
- * @see https://cloudinary.com/documentation/admin_api#create_a_metadata_field
- *
- * @param {Object} field The field to add
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options
- *
- * @return {Object}
- */
-exports.add_metadata_field = function add_metadata_field(field, callback, options = {}) {
- const params = pickOnlyExistingValues(field, "external_id", "type", "label", "mandatory", "default_value", "validation", "datasource", "restrictions");
- options.content_type = "json";
- return call_api("post", ["metadata_fields"], params, callback, options);
-};
-
-/**
- * Returns a list of all metadata field definitions
- *
- * @see https://cloudinary.com/documentation/admin_api#get_metadata_fields
- *
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options
- *
- * @return {Object}
- */
-exports.list_metadata_fields = function list_metadata_fields(callback, options = {}) {
- return call_api("get", ["metadata_fields"], {}, callback, options);
-};
-
-/**
- * Deletes a metadata field definition.
- *
- * The field should no longer be considered a valid candidate for all other endpoints
- *
- * @see https://cloudinary.com/documentation/admin_api#delete_a_metadata_field_by_external_id
- *
- * @param {String} field_external_id The external id of the field to delete
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options
- *
- * @return {Object}
- */
-exports.delete_metadata_field = function delete_metadata_field(field_external_id, callback, options = {}) {
- return call_api("delete", ["metadata_fields", field_external_id], {}, callback, options);
-};
-
-/**
- * Get a metadata field by external id
- *
- * @see https://cloudinary.com/documentation/admin_api#get_a_metadata_field_by_external_id
- *
- * @param {String} external_id The ID of the metadata field to retrieve
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options
- *
- * @return {Object}
- */
-exports.metadata_field_by_field_id = function metadata_field_by_field_id(external_id, callback, options = {}) {
- return call_api("get", ["metadata_fields", external_id], {}, callback, options);
-};
-
-/**
- * Updates a metadata field by external id
- *
- * Updates a metadata field definition (partially, no need to pass the entire object) passed as JSON data.
- * See {@link https://cloudinary.com/documentation/admin_api#generic_structure_of_a_metadata_field Generic structure of a metadata field} for details.
- *
- * @see https://cloudinary.com/documentation/admin_api#update_a_metadata_field_by_external_id
- *
- * @param {String} external_id The ID of the metadata field to update
- * @param {Object} field Updated values of metadata field
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options
- *
- * @return {Object}
- */
-exports.update_metadata_field = function update_metadata_field(external_id, field, callback, options = {}) {
- const params = pickOnlyExistingValues(field, "external_id", "type", "label", "mandatory", "default_value", "validation", "datasource", "restrictions", "default_disabled");
- options.content_type = "json";
- return call_api("put", ["metadata_fields", external_id], params, callback, options);
-};
-
-/**
- * Updates a metadata field datasource
- *
- * Updates the datasource of a supported field type (currently only enum and set), passed as JSON data. The
- * update is partial: datasource entries with an existing external_id will be updated and entries with new
- * external_id’s (or without external_id’s) will be appended.
- *
- * @see https://cloudinary.com/documentation/admin_api#update_a_metadata_field_datasource
- *
- * @param {String} field_external_id The ID of the field to update
- * @param {Object} entries_external_id Updated values for datasource
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options
- *
- * @return {Object}
- */
-exports.update_metadata_field_datasource = function update_metadata_field_datasource(field_external_id, entries_external_id, callback, options = {}) {
- const params = pickOnlyExistingValues(entries_external_id, "values");
- options.content_type = "json";
- return call_api("put", ["metadata_fields", field_external_id, "datasource"], params, callback, options);
-};
-
-/**
- * Deletes entries in a metadata field datasource
- *
- * Deletes (blocks) the datasource entries for a specified metadata field definition. Sets the state of the
- * entries to inactive. This is a soft delete, the entries still exist under the hood and can be activated again
- * with the restore datasource entries method.
- *
- * @see https://cloudinary.com/documentation/admin_api#delete_entries_in_a_metadata_field_datasource
- *
- * @param {String} field_external_id The ID of the metadata field
- * @param {Array} entries_external_id An array of IDs of datasource entries to delete
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options
- *
- * @return {Object}
- */
-exports.delete_datasource_entries = function delete_datasource_entries(field_external_id, entries_external_id, callback, options = {}) {
- options.content_type = "json";
- const params = {external_ids: entries_external_id};
- return call_api("delete", ["metadata_fields", field_external_id, "datasource"], params, callback, options);
-};
-
-/**
- * Restores entries in a metadata field datasource
- *
- * Restores (unblocks) any previously deleted datasource entries for a specified metadata field definition.
- * Sets the state of the entries to active.
- *
- * @see https://cloudinary.com/documentation/admin_api#restore_entries_in_a_metadata_field_datasource
- *
- * @param {String} field_external_id The ID of the metadata field
- * @param {Array} entries_external_id An array of IDs of datasource entries to delete
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options
- *
- * @return {Object}
- */
-exports.restore_metadata_field_datasource = function restore_metadata_field_datasource(field_external_id, entries_external_id, callback, options = {}) {
- options.content_type = "json";
- const params = {external_ids: entries_external_id};
- return call_api("post", ["metadata_fields", field_external_id, "datasource_restore"], params, callback, options);
-};
-
-/**
- * Sorts metadata field datasource. Currently supports only value
- * @param {String} field_external_id The ID of the metadata field
- * @param {String} sort_by Criteria for the sort. Currently supports only value
- * @param {String} direction Optional (gets either asc or desc)
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options
- *
- * @return {Object}
- */
-exports.order_metadata_field_datasource = function order_metadata_field_datasource(field_external_id, sort_by, direction, callback, options = {}) {
- options.content_type = "json";
- const params = {
- order_by: sort_by,
- direction: direction
- };
- return call_api("post", ["metadata_fields", field_external_id, "datasource", "order"], params, callback, options);
-};
-
-/**
- * Reorders metadata fields.
- *
- * @param {String} order_by Criteria for the order (one of the fields 'label', 'external_id', 'created_at').
- * @param {String} direction Optional (gets either asc or desc).
- * @param {Function} callback Callback function.
- * @param {Object} options Configuration options.
- *
- * @return {Object}
- */
-exports.reorder_metadata_fields = function reorder_metadata_fields(order_by, direction, callback, options = {}) {
- options.content_type = "json";
- const params = {
- order_by,
- direction
- };
- return call_api("put", ["metadata_fields", "order"], params, callback, options);
-};
-
-exports.list_metadata_rules = function list_metadata_rules(callback, options = {}) {
- return call_api('get', ['metadata_rules'], {}, callback, options);
-};
-
-exports.add_metadata_rule = function add_metadata_rule(metadata_rule, callback, options = {}) {
- options.content_type = 'json';
- const params = pickOnlyExistingValues(metadata_rule, 'metadata_field_id', 'condition', 'result', 'name');
- return call_api('post', ['metadata_rules'], params, callback, options);
-};
-
-exports.update_metadata_rule = function update_metadata_rule(field_external_id, updated_metadata_rule, callback, options = {}) {
- options.content_type = 'json';
- const params = pickOnlyExistingValues(updated_metadata_rule, 'metadata_field_id', 'condition', 'result', 'name', 'state');
- return call_api('put', ['metadata_rules', field_external_id], params, callback, options);
-};
-
-exports.delete_metadata_rule = function delete_metadata_rule(field_external_id, callback, options = {}) {
- return call_api('delete', ['metadata_rules', field_external_id], {}, callback, options);
-};
-
-exports.config = function config(callback, options = {}) {
- const params = pickOnlyExistingValues(options, 'settings');
- return call_api('get', ['config'], params, callback, options);
-}
diff --git a/server/node_modules/cloudinary/lib/api_client/call_account_api.js b/server/node_modules/cloudinary/lib/api_client/call_account_api.js
deleted file mode 100644
index 1df492a..0000000
--- a/server/node_modules/cloudinary/lib/api_client/call_account_api.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// eslint-disable-next-line import/order
-const config = require("../config");
-const utils = require("../utils");
-const ensureOption = require('../utils/ensureOption').defaults(config());
-const execute_request = require('./execute_request');
-
-const { ensurePresenceOf } = utils;
-
-function call_account_api(method, uri, params, callback, options) {
- ensurePresenceOf({ method, uri });
- const cloudinary = ensureOption(options, "upload_prefix", "https://api.cloudinary.com");
- const account_id = ensureOption(options, "account_id");
- const api_url = [cloudinary, "v1_1", "provisioning", "accounts", account_id].concat(uri).join("/");
- const auth = {
- key: ensureOption(options, "provisioning_api_key"),
- secret: ensureOption(options, "provisioning_api_secret")
- };
-
- return execute_request(method, params, auth, api_url, callback, options);
-}
-
-module.exports = call_account_api;
diff --git a/server/node_modules/cloudinary/lib/api_client/call_analysis_api.js b/server/node_modules/cloudinary/lib/api_client/call_analysis_api.js
deleted file mode 100644
index 073068e..0000000
--- a/server/node_modules/cloudinary/lib/api_client/call_analysis_api.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const utils = require("../utils");
-const config = require("../config");
-const ensureOption = require('../utils/ensureOption').defaults(config());
-const execute_request = require("./execute_request");
-
-const {ensurePresenceOf} = utils;
-
-function call_analysis_api(method, uri, params, callback, options) {
- ensurePresenceOf({
- method,
- uri
- });
- const api_url = utils.base_api_url_v2()(uri, options);
- let auth = {};
- if (options.oauth_token || config().oauth_token) {
- auth = {
- oauth_token: ensureOption(options, "oauth_token")
- };
- } else {
- auth = {
- key: ensureOption(options, "api_key"),
- secret: ensureOption(options, "api_secret")
- };
- }
- options.content_type = 'json';
-
- return execute_request(method, params, auth, api_url, callback, options);
-}
-
-module.exports = {
- call_analysis_api
-};
diff --git a/server/node_modules/cloudinary/lib/api_client/call_api.js b/server/node_modules/cloudinary/lib/api_client/call_api.js
deleted file mode 100644
index 11c4e5f..0000000
--- a/server/node_modules/cloudinary/lib/api_client/call_api.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// eslint-disable-next-line import/order
-const config = require("../config");
-const utils = require("../utils");
-const ensureOption = require('../utils/ensureOption').defaults(config());
-const execute_request = require('./execute_request');
-
-const { ensurePresenceOf } = utils;
-
-function call_api(method, uri, params, callback, options) {
- ensurePresenceOf({ method, uri });
- const api_url = utils.base_api_url_v1()(uri, options);
- let auth = {};
- if (options.oauth_token || config().oauth_token){
- auth = {
- oauth_token: ensureOption(options, "oauth_token")
- };
- } else {
- auth = {
- key: ensureOption(options, "api_key"),
- secret: ensureOption(options, "api_secret")
- };
- }
- return execute_request(method, params, auth, api_url, callback, options);
-}
-
-module.exports = call_api;
diff --git a/server/node_modules/cloudinary/lib/api_client/execute_request.js b/server/node_modules/cloudinary/lib/api_client/execute_request.js
deleted file mode 100644
index 9c0418d..0000000
--- a/server/node_modules/cloudinary/lib/api_client/execute_request.js
+++ /dev/null
@@ -1,169 +0,0 @@
-// eslint-disable-next-line import/order
-const config = require("../config");
-const https = /^http:/.test(config().upload_prefix) ? require('http') : require('https');
-const querystring = require("querystring");
-const Q = require('q');
-const url = require('url');
-const utils = require("../utils");
-const ensureOption = require('../utils/ensureOption').defaults(config());
-
-const { extend, includes, isEmpty } = utils;
-
-const agent = config.api_proxy ? new https.Agent(config.api_proxy) : null;
-
-function execute_request(method, params, auth, api_url, callback, options = {}) {
- method = method.toUpperCase();
- const deferred = Q.defer();
-
- let query_params, handle_response; // declare to user later
- let key = auth.key;
- let secret = auth.secret;
- let oauth_token = auth.oauth_token;
- let content_type = 'application/x-www-form-urlencoded';
-
- if (options.content_type === 'json') {
- query_params = JSON.stringify(params);
- content_type = 'application/json';
- } else {
- query_params = querystring.stringify(params);
- }
-
- if (method === "GET") {
- api_url += "?" + query_params;
- }
-
- let request_options = url.parse(api_url);
-
- request_options = extend(request_options, {
- method: method,
- headers: {
- 'Content-Type': content_type,
- 'User-Agent': utils.getUserAgent()
- }
- });
-
- if (oauth_token) {
- request_options.headers.Authorization = `Bearer ${oauth_token}`;
- } else {
- request_options.auth = key + ":" + secret
- }
-
- if (options.agent != null) {
- request_options.agent = options.agent;
- }
-
- let proxy = options.api_proxy || config().api_proxy;
- if (!isEmpty(proxy)) {
- if (!request_options.agent && agent) {
- request_options.agent = agent;
- } else if (!request_options.agent) {
- request_options.agent = new https.Agent(proxy);
- } else {
- console.warn("Proxy is set, but request uses a custom agent, proxy is ignored.");
- }
- }
- if (method !== "GET") {
- request_options.headers['Content-Length'] = Buffer.byteLength(query_params);
- }
- handle_response = function (res) {
- const {hide_sensitive = false} = config();
- const sanitizedOptions = {...request_options};
-
- if (hide_sensitive === true){
- if ("auth" in sanitizedOptions) { delete sanitizedOptions.auth; }
- if ("Authorization" in sanitizedOptions.headers) { delete sanitizedOptions.headers.Authorization; }
- }
-
- if (includes([200, 400, 401, 403, 404, 409, 420, 500], res.statusCode)) {
- let buffer = "";
- let error = false;
- res.on("data", function (d) {
- buffer += d;
- return buffer;
- });
- res.on("end", function () {
- let result;
- if (error) {
- return;
- }
- try {
- result = JSON.parse(buffer);
- } catch (e) {
- result = {
- error: {
- message: "Server return invalid JSON response. Status Code " + res.statusCode
- }
- };
- }
-
- if (result.error) {
- result.error.http_code = res.statusCode;
- } else {
- if (res.headers["x-featureratelimit-limit"]) {
- result.rate_limit_allowed = parseInt(res.headers["x-featureratelimit-limit"]);
- }
- if (res.headers["x-featureratelimit-reset"]) {
- result.rate_limit_reset_at = new Date(res.headers["x-featureratelimit-reset"]);
- }
- if (res.headers["x-featureratelimit-remaining"]) {
- result.rate_limit_remaining = parseInt(res.headers["x-featureratelimit-remaining"]);
- }
- }
-
- if (result.error) {
- deferred.reject(Object.assign({
- request_options: sanitizedOptions,
- query_params
- }, result));
- } else {
- deferred.resolve(result);
- }
- if (typeof callback === "function") {
- callback(result);
- }
- });
- res.on("error", function (e) {
- error = true;
- let err_obj = {
- error: {
- message: e,
- http_code: res.statusCode,
- request_options: sanitizedOptions,
- query_params
- }
- };
- deferred.reject(err_obj.error);
- if (typeof callback === "function") {
- callback(err_obj);
- }
- });
- } else {
- let err_obj = {
- error: {
- message: "Server returned unexpected status code - " + res.statusCode,
- http_code: res.statusCode,
- request_options: sanitizedOptions,
- query_params
- }
- };
- deferred.reject(err_obj.error);
- if (typeof callback === "function") {
- callback(err_obj);
- }
- }
- };
-
- const request = https.request(request_options, handle_response);
- request.on("error", function (e) {
- deferred.reject(e);
- return typeof callback === "function" ? callback({ error: e }) : void 0;
- });
- request.setTimeout(ensureOption(options, "timeout", 60000));
- if (method !== "GET") {
- request.write(query_params);
- }
- request.end();
- return deferred.promise;
-}
-
-module.exports = execute_request;
diff --git a/server/node_modules/cloudinary/lib/auth_token.js b/server/node_modules/cloudinary/lib/auth_token.js
deleted file mode 100644
index 39694b5..0000000
--- a/server/node_modules/cloudinary/lib/auth_token.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * Authorization Token
- * @module auth_token
- */
-
-const crypto = require('crypto');
-const smart_escape = require('./utils/encoding/smart_escape');
-
-const unsafe = /([ "#%&'/:;<=>?@[\]^`{|}~]+)/g;
-
-function digest(message, key) {
- return crypto.createHmac("sha256", Buffer.from(key, "hex")).update(message).digest('hex');
-}
-
-/**
- * Escape url using lowercase hex code
- * @param {string} url a url string
- * @return {string} escaped url
- */
-function escapeToLower(url) {
- const safeUrl = smart_escape(url, unsafe);
- return safeUrl.replace(/%../g, function (match) {
- return match.toLowerCase();
- });
-}
-
-/**
- * Auth token options
- * @typedef {object} authTokenOptions
- * @property {string} [token_name="__cld_token__"] The name of the token.
- * @property {string} key The secret key required to sign the token.
- * @property {string} ip The IP address of the client.
- * @property {number} start_time=now The start time of the token in seconds from epoch.
- * @property {string} expiration The expiration time of the token in seconds from epoch.
- * @property {string} duration The duration of the token (from start_time).
- * @property {string|Array} acl The ACL(s) for the token.
- * @property {string} url The URL to authentication in case of a URL token.
- *
- */
-
-/**
- * Generate an authorization token
- * @param {authTokenOptions} options
- * @returns {string} the authorization token
- */
-module.exports = function (options) {
- const tokenName = options.token_name ? options.token_name : "__cld_token__";
- const tokenSeparator = "~";
- if (options.expiration == null) {
- if (options.duration != null) {
- let start = options.start_time != null ? options.start_time : Math.round(Date.now() / 1000);
- options.expiration = start + options.duration;
- } else {
- throw new Error("Must provide either expiration or duration");
- }
- }
- let tokenParts = [];
- if (options.ip != null) {
- tokenParts.push(`ip=${options.ip}`);
- }
- if (options.start_time != null) {
- tokenParts.push(`st=${options.start_time}`);
- }
- tokenParts.push(`exp=${options.expiration}`);
- if (options.acl != null) {
- if (Array.isArray(options.acl) === true) {
- options.acl = options.acl.join("!");
- }
- tokenParts.push(`acl=${escapeToLower(options.acl)}`);
- }
- let toSign = [...tokenParts];
- if (options.url != null && options.acl == null) {
- let url = escapeToLower(options.url);
- toSign.push(`url=${url}`);
- }
- let auth = digest(toSign.join(tokenSeparator), options.key);
- tokenParts.push(`hmac=${auth}`);
-
- if (!options.url && !options.acl) {
- throw 'authToken must contain either an acl or a url property'
- }
-
- return `${tokenName}=${tokenParts.join(tokenSeparator)}`;
-};
diff --git a/server/node_modules/cloudinary/lib/cache.js b/server/node_modules/cloudinary/lib/cache.js
deleted file mode 100644
index 6e40272..0000000
--- a/server/node_modules/cloudinary/lib/cache.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/* eslint-disable class-methods-use-this */
-
-const CACHE = Symbol.for("com.cloudinary.cache");
-const CACHE_ADAPTER = Symbol.for("com.cloudinary.cacheAdapter");
-const { ensurePresenceOf, generate_transformation_string } = require('./utils');
-
-/**
- * The adapter used to communicate with the underlying cache storage
- */
-class CacheAdapter {
- /**
- * Get a value from the cache
- * @param {string} publicId
- * @param {string} type
- * @param {string} resourceType
- * @param {string} transformation
- * @param {string} format
- * @return {*} the value associated with the provided arguments
- */
- get(publicId, type, resourceType, transformation, format) {}
-
- /**
- * Set a new value in the cache
- * @param {string} publicId
- * @param {string} type
- * @param {string} resourceType
- * @param {string} transformation
- * @param {string} format
- * @param {*} value
- */
- set(publicId, type, resourceType, transformation, format, value) {}
-
- /**
- * Delete all values in the cache
- */
- flushAll() {}
-}
-/**
- * @class Cache
- * Stores and retrieves values identified by publicId / options pairs
- */
-const Cache = {
- /**
- * The adapter interface. Extend this class to implement a specific adapter.
- * @type CacheAdapter
- */
- CacheAdapter,
- /**
- * Set the cache adapter
- * @param {CacheAdapter} adapter The cache adapter
- */
- setAdapter(adapter) {
- if (this.adapter) {
- console.warn("Overriding existing cache adapter");
- }
- this.adapter = adapter;
- },
- /**
- * Get the adapter the Cache is using
- * @return {CacheAdapter} the current cache adapter
- */
- getAdapter() {
- return this.adapter;
- },
- /**
- * Get an item from the cache
- * @param {string} publicId
- * @param {object} options
- * @return {*}
- */
- get(publicId, options) {
- if (!this.adapter) { return undefined; }
- ensurePresenceOf({ publicId });
- let transformation = generate_transformation_string({ ...options });
- return this.adapter.get(
- publicId, options.type || 'upload',
- options.resource_type || 'image',
- transformation,
- options.format
- );
- },
- /**
- * Set a new value in the cache
- * @param {string} publicId
- * @param {object} options
- * @param {*} value
- * @return {*}
- */
- set(publicId, options, value) {
- if (!this.adapter) { return undefined; }
- ensurePresenceOf({ publicId, value });
- let transformation = generate_transformation_string({ ...options });
- return this.adapter.set(
- publicId,
- options.type || 'upload',
- options.resource_type || 'image',
- transformation,
- options.format,
- value
- );
- },
- /**
- * Clear all items in the cache
- * @return {*} Returns the value from the adapter's flushAll() method
- */
- flushAll() {
- if (!this.adapter) { return undefined; }
- return this.adapter.flushAll();
- }
-
-};
-
-// Define singleton property
-Object.defineProperty(Cache, "instance", {
- get() {
- return global[CACHE];
- }
-});
-Object.defineProperty(Cache, "adapter", {
- /**
- *
- * @return {CacheAdapter} The current cache adapter
- */
- get() {
- return global[CACHE_ADAPTER];
- },
- /**
- * Set the cache adapter to be used by Cache
- * @param {CacheAdapter} adapter Cache adapter
- */
- set(adapter) {
- global[CACHE_ADAPTER] = adapter;
- }
-});
-Object.freeze(Cache);
-
-// Instantiate the singleton
-let symbols = Object.getOwnPropertySymbols(global);
-if (symbols.indexOf(CACHE) < 0) {
- global[CACHE] = Cache;
-}
-
-/**
- * Store key value pairs
-
- */
-module.exports = Cache;
diff --git a/server/node_modules/cloudinary/lib/cache/FileKeyValueStorage.js b/server/node_modules/cloudinary/lib/cache/FileKeyValueStorage.js
deleted file mode 100644
index 319067e..0000000
--- a/server/node_modules/cloudinary/lib/cache/FileKeyValueStorage.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-const rimraf = require('../utils/rimraf');
-
-class FileKeyValueStorage {
- constructor({ baseFolder } = {}) {
- this.init(baseFolder);
- }
-
- init(baseFolder) {
- if (baseFolder) {
- try {
- fs.accessSync(baseFolder);
- this.baseFolder = baseFolder;
- } catch (err) {
- throw err;
- }
- } else {
- if (!fs.existsSync('test_cache')) {
- fs.mkdirSync('test_cache');
- }
- this.baseFolder = fs.mkdtempSync('test_cache/cloudinary_cache_');
- console.info("Created temporary cache folder at " + this.baseFolder);
- }
- }
-
- get(key) {
- let value = fs.readFileSync(this.getFilename(key));
- try {
- return JSON.parse(value);
- } catch (e) {
- throw "Cannot parse cache value";
- }
- }
-
- set(key, value) {
- fs.writeFileSync(this.getFilename(key), JSON.stringify(value));
- }
-
- clear() {
- let files = fs.readdirSync(this.baseFolder);
- files.forEach(file => fs.unlinkSync(path.join(this.baseFolder, file)));
- }
-
- deleteBaseFolder() {
- rimraf(this.baseFolder);
- }
-
- getFilename(key) {
- return path.format({ name: key, base: key, ext: '.json', dir: this.baseFolder });
- }
-}
-
-module.exports = FileKeyValueStorage;
diff --git a/server/node_modules/cloudinary/lib/cache/KeyValueCacheAdapter.js b/server/node_modules/cloudinary/lib/cache/KeyValueCacheAdapter.js
deleted file mode 100644
index f49531c..0000000
--- a/server/node_modules/cloudinary/lib/cache/KeyValueCacheAdapter.js
+++ /dev/null
@@ -1,62 +0,0 @@
-const crypto = require('crypto');
-const CacheAdapter = require('../cache').CacheAdapter;
-
-/**
- *
- */
-class KeyValueCacheAdapter extends CacheAdapter {
- constructor(storage) {
- super();
- this.storage = storage;
- }
-
- /** @inheritDoc */
- get(publicId, type, resourceType, transformation, format) {
- let key = KeyValueCacheAdapter.generateCacheKey(publicId, type, resourceType, transformation, format);
- return KeyValueCacheAdapter.extractData(this.storage.get(key));
- }
-
- /** @inheritDoc */
- set(publicId, type, resourceType, transformation, format, value) {
- let key = KeyValueCacheAdapter.generateCacheKey(publicId, type, resourceType, transformation, format);
- this.storage.set(
- key,
- KeyValueCacheAdapter.prepareData(
- publicId,
- type,
- resourceType,
- transformation,
- format,
- value
- )
- );
- }
-
- /** @inheritDoc */
- flushAll() {
- this.storage.clear();
- }
-
- /** @inheritDoc */
- delete(publicId, type, resourceType, transformation, format) {
- let key = KeyValueCacheAdapter.generateCacheKey(publicId, type, resourceType, transformation, format);
- return this.storage.delete(key);
- }
-
- static generateCacheKey(publicId, type, resourceType, transformation, format) {
- type = type || "upload";
- resourceType = resourceType || "image";
- let sha1 = crypto.createHash('sha1');
- return sha1.update([publicId, type, resourceType, transformation, format].filter(i => i).join('/')).digest('hex');
- }
-
- static prepareData(publicId, type, resourceType, transformation, format, data) {
- return { publicId, type, resourceType, transformation, format, breakpoints: data };
- }
-
- static extractData(data) {
- return data ? data.breakpoints : null;
- }
-}
-
-module.exports = KeyValueCacheAdapter;
diff --git a/server/node_modules/cloudinary/lib/cloudinary.js b/server/node_modules/cloudinary/lib/cloudinary.js
deleted file mode 100644
index f3b9767..0000000
--- a/server/node_modules/cloudinary/lib/cloudinary.js
+++ /dev/null
@@ -1,239 +0,0 @@
-const _ = require('lodash');
-exports.config = require("./config");
-exports.utils = require("./utils");
-exports.uploader = require("./uploader");
-exports.api = require("./api");
-exports.analysis = require('./analysis');
-
-const account = require("./provisioning/account");
-
-exports.provisioning = {
- account: account
-};
-exports.PreloadedFile = require("./preloaded_file");
-exports.Cache = require('./cache');
-
-const cloudinary = module.exports;
-
-const optionConsume = cloudinary.utils.option_consume;
-
-exports.url = function url(public_id, options) {
- options = _.extend({}, options);
- return cloudinary.utils.url(public_id, options);
-};
-
-const { generateImageResponsiveAttributes, generateMediaAttr } = require('./utils/srcsetUtils');
-
-/**
- * Helper function, allows chaining transformation to the end of transformation list
- *
- * @private
- * @param {object} options Original options
- * @param {object|object[]} transformation Transformations to chain at the end
- *
- * @return {object} Resulting options
- */
-function chainTransformations(options, transformation = []) {
- // preserve url options
- let urlOptions = cloudinary.utils.extractUrlParams(options);
- let currentTransformation = cloudinary.utils.extractTransformationParams(options);
- transformation = cloudinary.utils.build_array(transformation);
- urlOptions.transformation = [currentTransformation, ...transformation];
- return urlOptions;
-}
-
-/**
- * Generate an HTML img tag with a Cloudinary URL
- * @param {string} source A Public ID or a URL
- * @param {object} options Configuration options
- * @param {srcset} options.srcset srcset options
- * @param {object} options.attributes HTML attributes
- * @param {number} options.html_width (deprecated) The HTML tag width
- * @param {number} options.html_height (deprecated) The HTML tag height
- * @param {boolean} options.client_hints Don't implement the client side responsive function.
- * This argument can override the the same option in the global configuration.
- * @param {boolean} options.responsive Setup the tag for the client side responsive function.
- * @param {boolean} options.hidpi Setup the tag for the client side auto dpr function.
- * @param {boolean} options.responsive_placeholder A place holder image URL to use with.
- * the client side responsive function
- * @return {string} An HTML img tag
- */
-exports.image = function image(source, options) {
- let localOptions = _.extend({}, options);
- let srcsetParam = optionConsume(localOptions, 'srcset');
- let attributes = optionConsume(localOptions, 'attributes', {});
- let src = cloudinary.utils.url(source, localOptions);
- if ("html_width" in localOptions) localOptions.width = optionConsume(localOptions, "html_width");
- if ("html_height" in localOptions) localOptions.height = optionConsume(localOptions, "html_height");
-
- let client_hints = optionConsume(localOptions, "client_hints", cloudinary.config().client_hints);
- let responsive = optionConsume(localOptions, "responsive");
- let hidpi = optionConsume(localOptions, "hidpi");
-
- if ((responsive || hidpi) && !client_hints) {
- localOptions["data-src"] = src;
- let classes = [responsive ? "cld-responsive" : "cld-hidpi"];
- let current_class = optionConsume(localOptions, "class");
- if (current_class) classes.push(current_class);
- localOptions.class = classes.join(" ");
- src = optionConsume(localOptions, "responsive_placeholder", cloudinary.config().responsive_placeholder);
- if (src === "blank") {
- src = cloudinary.BLANK;
- }
- }
- let html = "
";
- return html;
-};
-
-/**
- * Creates an HTML video tag for the provided public_id
- * @param {String} public_id the resource public ID
- * @param {Object} [options] options for the resource and HTML tag
- * @param {(String|Array)} [options.source_types] Specify which
- * source type the tag should include. defaults to webm, mp4 and ogv.
- * @param {String} [options.source_transformation] specific transformations
- * to use for a specific source type.
- * @param {(String|Object)} [options.poster] image URL or
- * poster options that may include a public_id key and
- * poster-specific transformations
- * @example Example of generating a video tag:
- * cloudinary.video("mymovie.mp4");
- * cloudinary.video("mymovie.mp4", {source_types: 'webm'});
- * cloudinary.video("mymovie.ogv", {poster: "myspecialplaceholder.jpg"});
- * cloudinary.video("mymovie.webm", {source_types: ['webm', 'mp4'], poster: {effect: 'sepia'}});
- * @return {string} HTML video tag
- */
-exports.video = function video(public_id, options) {
- options = _.extend({}, options);
- public_id = public_id.replace(/\.(mp4|ogv|webm)$/, '');
- let source_types = optionConsume(options, 'source_types', []);
- let source_transformation = optionConsume(options, 'source_transformation', {});
- let sources = optionConsume(options, 'sources', []);
- let fallback = optionConsume(options, 'fallback_content', '');
-
- if (source_types.length === 0) source_types = cloudinary.utils.DEFAULT_VIDEO_SOURCE_TYPES;
- let video_options = _.cloneDeep(options);
-
- if (video_options.hasOwnProperty('poster')) {
- if (_.isPlainObject(video_options.poster)) {
- if (video_options.poster.hasOwnProperty('public_id')) {
- video_options.poster = cloudinary.utils.url(video_options.poster.public_id, video_options.poster);
- } else {
- video_options.poster = cloudinary.utils.url(public_id, _.extend({}, cloudinary.utils.DEFAULT_POSTER_OPTIONS, video_options.poster));
- }
- }
- } else {
- video_options.poster = cloudinary.utils.url(public_id, _.extend({}, cloudinary.utils.DEFAULT_POSTER_OPTIONS, options));
- }
-
- if (!video_options.poster) delete video_options.poster;
-
- let html = '`;
-};
-
-
-/**
- * Generate a source tag.
- * @param {string} public_id
- * @param {object} options
- * @param {srcset} options.srcset arguments required to generate the srcset attribute.
- * @param {object} options.attributes HTML tag attributes
- * @return {string}
- */
-exports.source = function source(public_id, options = {}) {
- let srcsetParam = cloudinary.utils.extend({}, options.srcset, cloudinary.config().srcset);
- let attributes = options.attributes || {};
-
- cloudinary.utils.extend(attributes, generateImageResponsiveAttributes(public_id, attributes, srcsetParam, options));
- if (!attributes.srcset) {
- attributes.srcset = cloudinary.url(public_id, options);
- }
- if (!attributes.media && options.media) {
- attributes.media = generateMediaAttr(options.media);
- }
- return ``;
-};
-
-/**
- * Generate a picture HTML tag.
- * The sources argument defines different transformations to apply for each
- * media query.
- * @param {string}public_id
- * @param {object} options
- * @param {object[]} options.sources a list of source arguments. A source tag will be rendered for each item
- * @param {number} options.sources.min_width a minimum width query
- * @param {number} options.sources.max_width a maximum width query
- * @param {number} options.sources.transformation the transformation to apply to the source tag.
- * @return {string} A picture HTML tag
- * @example
- *
- * cloudinary.picture("sample", {
- * sources: [
- * {min_width: 1600, transformation: {crop: 'fill', width: 800, aspect_ratio: 2}},
- * {min_width: 500, transformation: {crop: 'fill', width: 600, aspect_ratio: 2.3}},
- * {transformation: {crop: 'crop', width: 400, gravity: 'auto'}},
- * ]}
- * );
- */
-exports.picture = function picture(public_id, options = {}) {
- let sources = options.sources || [];
- options = cloudinary.utils.clone(options);
- delete options.sources;
- cloudinary.utils.patchFetchFormat(options);
- return ""
- + sources.map((source) => {
- let sourceOptions = chainTransformations(options, source.transformation);
- sourceOptions.media = source;
- return cloudinary.source(public_id, sourceOptions);
- }).join('')
- + cloudinary.image(public_id, options)
- + "";
-};
-
-exports.cloudinary_js_config = cloudinary.utils.cloudinary_js_config;
-exports.CF_SHARED_CDN = cloudinary.utils.CF_SHARED_CDN;
-exports.AKAMAI_SHARED_CDN = cloudinary.utils.AKAMAI_SHARED_CDN;
-exports.SHARED_CDN = cloudinary.utils.SHARED_CDN;
-exports.BLANK = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
-exports.v2 = require('./v2');
diff --git a/server/node_modules/cloudinary/lib/config.js b/server/node_modules/cloudinary/lib/config.js
deleted file mode 100644
index 1de579d..0000000
--- a/server/node_modules/cloudinary/lib/config.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * Assign a value to a nested object
- * @function putNestedValue
- * @param params the parent object - this argument will be modified!
- * @param key key in the form nested[innerkey]
- * @param value the value to assign
- * @return the modified params object
- */
-const url = require('url');
-const extend = require("lodash/extend");
-const isObject = require("lodash/isObject");
-const isString = require("lodash/isString");
-const isUndefined = require("lodash/isUndefined");
-const isEmpty = require("lodash/isEmpty");
-const entries = require('./utils/entries');
-
-let cloudinary_config = void 0;
-
-/**
- * Sets a value in an object using a nested key
- * @param {object} params The object to assign the value in.
- * @param {string} key The key of the value. A period is used to denote inner keys.
- * @param {*} value The value to set.
- * @returns {object} The params argument.
- * @example
- * let o = {foo: {bar: 1}};
- * putNestedValue(o, 'foo.bar', 2); // {foo: {bar: 2}}
- * putNestedValue(o, 'foo.inner.key', 'this creates an inner object');
- * // {{foo: {bar: 2}, inner: {key: 'this creates an inner object'}}}
- */
-function putNestedValue(params, key, value) {
- let chain = key.split(/[\[\]]+/).filter(i => i.length);
- let outer = params;
- let lastKey = chain.pop();
- for (let j = 0; j < chain.length; j++) {
- let innerKey = chain[j];
- let inner = outer[innerKey];
- if (inner == null) {
- inner = {};
- outer[innerKey] = inner;
- }
- outer = inner;
- }
- outer[lastKey] = value;
- return params;
-}
-
-function parseCloudinaryConfigFromEnvURL(ENV_STR) {
- let conf = {};
-
- let uri = url.parse(ENV_STR, true);
-
- if (uri.protocol === 'cloudinary:') {
- conf = Object.assign({}, conf, {
- cloud_name: uri.host,
- api_key: uri.auth && uri.auth.split(":")[0],
- api_secret: uri.auth && uri.auth.split(":")[1],
- private_cdn: uri.pathname != null,
- secure_distribution: uri.pathname && uri.pathname.substring(1)
- });
- } else if (uri.protocol === 'account:') {
- conf = Object.assign({}, conf, {
- account_id: uri.host,
- provisioning_api_key: uri.auth && uri.auth.split(":")[0],
- provisioning_api_secret: uri.auth && uri.auth.split(":")[1]
- });
- }
-
- return conf;
-}
-
-function extendCloudinaryConfigFromQuery(ENV_URL, confToExtend = {}) {
- let uri = url.parse(ENV_URL, true);
- if (uri.query != null) {
- entries(uri.query).forEach(([key, value]) => putNestedValue(confToExtend, key, value));
- }
-}
-
-function extendCloudinaryConfig(parsedConfig, confToExtend = {}) {
- entries(parsedConfig).forEach(([key, value]) => {
- if (value !== undefined) {
- confToExtend[key] = value;
- }
- });
-
- return confToExtend;
-}
-
-module.exports = function (new_config, new_value) {
- if ((cloudinary_config == null) || new_config === true) {
- if (cloudinary_config == null) {
- cloudinary_config = {};
- } else {
- Object.keys(cloudinary_config).forEach(key => delete cloudinary_config[key]);
- }
-
- let CLOUDINARY_ENV_URL = process.env.CLOUDINARY_URL;
- let CLOUDINARY_ENV_ACCOUNT_URL = process.env.CLOUDINARY_ACCOUNT_URL;
- let CLOUDINARY_API_PROXY = process.env.CLOUDINARY_API_PROXY;
-
- if (CLOUDINARY_ENV_URL && !CLOUDINARY_ENV_URL.toLowerCase().startsWith('cloudinary://')) {
- throw new Error("Invalid CLOUDINARY_URL protocol. URL should begin with 'cloudinary://'");
- }
- if (CLOUDINARY_ENV_ACCOUNT_URL && !CLOUDINARY_ENV_ACCOUNT_URL.toLowerCase().startsWith('account://')) {
- throw new Error("Invalid CLOUDINARY_ACCOUNT_URL protocol. URL should begin with 'account://'");
- }
- if (!isEmpty(CLOUDINARY_API_PROXY)) {
- extendCloudinaryConfig({ api_proxy: CLOUDINARY_API_PROXY }, cloudinary_config);
- }
-
- [CLOUDINARY_ENV_URL, CLOUDINARY_ENV_ACCOUNT_URL].forEach((ENV_URL) => {
- if (ENV_URL) {
- let parsedConfig = parseCloudinaryConfigFromEnvURL(ENV_URL);
- extendCloudinaryConfig(parsedConfig, cloudinary_config);
- // Provide Query support in ENV url cloudinary://key:secret@test123?foo[bar]=value
- // expect(cloudinary_config.foo.bar).to.eql('value')
- extendCloudinaryConfigFromQuery(ENV_URL, cloudinary_config);
- }
- });
- }
- if (!isUndefined(new_value)) {
- cloudinary_config[new_config] = new_value;
- } else if (isString(new_config)) {
- return cloudinary_config[new_config];
- } else if (isObject(new_config)) {
- extend(cloudinary_config, new_config);
- }
- return cloudinary_config;
-};
diff --git a/server/node_modules/cloudinary/lib/preloaded_file.js b/server/node_modules/cloudinary/lib/preloaded_file.js
deleted file mode 100644
index 1733bf8..0000000
--- a/server/node_modules/cloudinary/lib/preloaded_file.js
+++ /dev/null
@@ -1,61 +0,0 @@
-let PRELOADED_CLOUDINARY_PATH, config, utils;
-
-utils = require("./utils");
-
-config = require("./config");
-
-PRELOADED_CLOUDINARY_PATH = /^([^\/]+)\/([^\/]+)\/v(\d+)\/([^#]+)#([^\/]+)$/;
-
-class PreloadedFile {
- constructor(file_info) {
- let matches, public_id_and_format;
- matches = file_info.match(PRELOADED_CLOUDINARY_PATH);
- if (!matches) {
- throw "Invalid preloaded file info";
- }
- this.resource_type = matches[1];
- this.type = matches[2];
- this.version = matches[3];
- this.filename = matches[4];
- this.signature = matches[5];
- public_id_and_format = PreloadedFile.split_format(this.filename);
- this.public_id = public_id_and_format[0];
- this.format = public_id_and_format[1];
- }
-
- is_valid() {
- return utils.verify_api_response_signature(this.public_id, this.version, this.signature);
- }
-
- static split_format(identifier) {
- let format, last_dot, public_id;
- last_dot = identifier.lastIndexOf(".");
- if (last_dot === -1) {
- return [identifier, null];
- }
- public_id = identifier.substr(0, last_dot);
- format = identifier.substr(last_dot + 1);
- return [public_id, format];
- }
-
- identifier() {
- return `v${this.version}/${this.filename}`;
- }
-
- toString() {
- return `${this.resource_type}/${this.type}/v${this.version}/${this.filename}#${this.signature}`;
- }
-
- toJSON() {
- let result = {};
- Object.getOwnPropertyNames(this).forEach((key) => {
- let val = this[key];
- if (typeof val !== 'function') {
- result[key] = val;
- }
- });
- return result;
- }
-}
-
-module.exports = PreloadedFile;
diff --git a/server/node_modules/cloudinary/lib/provisioning/account.js b/server/node_modules/cloudinary/lib/provisioning/account.js
deleted file mode 100644
index f2c8566..0000000
--- a/server/node_modules/cloudinary/lib/provisioning/account.js
+++ /dev/null
@@ -1,390 +0,0 @@
-const utils = require("../utils");
-const call_account_api = require('../api_client/call_account_api');
-
-const { pickOnlyExistingValues } = utils;
-
-/**
- * @desc Lists sub-accounts.
- * @param [enabled] {boolean} - Whether to only return enabled sub-accounts (true) or disabled accounts (false).
- * Default: all accounts are returned (both enabled and disabled).
- * @param [ids] {number[]} - A list of up to 100 sub-account IDs. When provided, other parameters are ignored.
- * @param [prefix] {string} - Returns accounts where the name begins with the specified case-insensitive string.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function sub_accounts(enabled, ids = [], prefix, options = {}, callback) {
- let params = {
- enabled,
- ids,
- prefix
- };
-
- let uri = ['sub_accounts'];
- return call_account_api('GET', uri, params, callback, options);
-}
-
-
-/**
- * @desc Retrieves the details of the specified sub-account.
- * @param sub_account_id {string} - The ID of the sub-account.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function sub_account(sub_account_id, options = {}, callback) {
- let uri = ['sub_accounts', sub_account_id];
- return call_account_api('GET', uri, {}, callback, options);
-}
-
-
-/**
- * @desc Creates a new sub-account. Any users that have access to all sub-accounts will also automatically have access
- * to the new sub-account.
- * @param name {string} The display name as shown in the management console.
- * @param cloud_name {string} A case-insensitive cloud name comprised of alphanumeric and underscore characters.
- * Generates an error if the specified cloud name is not unique across all Cloudinary
- * accounts. Note: Once created, the name can only be changed for accounts with fewer than
- * 1000 assets.
- * @param custom_attributes {object} Any custom attributes you want to associate with the sub-account, as a map/hash of
- * key/value pairs.
- * @param enabled {boolean} Whether the sub-account is enabled. Default: true
- * @param base_account {string} The ID of another sub-account, from which to copy all of the following settings:
- * Size limits, Timed limits, and Flags.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param callback
- */
-function create_sub_account(name, cloud_name, custom_attributes, enabled, base_account, options = {}, callback) {
- let params = {
- cloud_name: cloud_name,
- name,
- custom_attributes: custom_attributes,
- enabled,
- base_sub_account_id: base_account
- };
-
- options.content_type = "json";
- let uri = ['sub_accounts'];
- return call_account_api('POST', uri, params, callback, options);
-}
-
-/**
- * @desc Deletes the specified sub-account. Supported only for accounts with fewer than 1000 assets.
- * @param sub_account_id {string} - The ID of the sub-account to delete.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function delete_sub_account(sub_account_id, options = {}, callback) {
- let uri = ['sub_accounts', sub_account_id];
- return call_account_api('DELETE', uri, {}, callback, options);
-}
-
-/**
- * @desc Updates the specified details of the sub-account.
- * @param sub_account_id {string} - The ID of the sub-account.
- * @param [name] {string} - The display name as shown in the management console.
- * @param [cloud_name] {string} - A new cloud name for the account.
- * Notes:
- * - Can only be changed for accounts with fewer than 1000 assets.
- * - generates an error if the cloud name is not unique across all Cloudinary accounts.
- * @param [custom_attributes] {object} - Any custom attributes you want to associate with the sub-account, as a map/hash
- * of key/value pairs.
- * @param [enabled] {boolean} - Whether the sub-account is enabled.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function update_sub_account(sub_account_id, name, cloud_name, custom_attributes, enabled, options = {}, callback) {
- let params = {
- cloud_name: cloud_name,
- name,
- custom_attributes: custom_attributes,
- enabled
- };
-
- options.content_type = "json";
- let uri = ['sub_accounts', sub_account_id];
- return call_account_api('PUT', uri, params, callback, options);
-}
-
-/**
- * @desc Returns the user with the specified ID.
- * @param user_id {string} - The ID of the user.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function user(user_id, options = {}, callback) {
- let uri = ['users', user_id];
- return call_account_api('GET', uri, {}, callback, options);
-}
-
-/**
- * @desc Lists users in the account.
- * @param [pending] {boolean} - Limit results to pending users (true), users that are not pending (false), or all users (undefined, the default)
- * @param [user_ids] {string[]} - A list of up to 100 user IDs. When provided, other parameters are ignored.
- * @param [prefix] {string} - Returns users where the name or email address begins with the specified case-insensitive
- * string.
- * @param [sub_account_id[ {string} - Only returns users who have access to the specified account.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function users(pending, user_ids, prefix, sub_account_id, options = {}, callback) {
- let uri = ['users'];
- let params = {
- ids: user_ids,
- pending,
- prefix,
- sub_account_id
- };
- return call_account_api('GET', uri, pickOnlyExistingValues(params, "ids", "pending", "prefix", "sub_account_id"), callback, options);
-}
-
-/**
- * @desc Creates a new user in the account.
- * @param name {string} - The name of the user.
- * @param email {string} - A unique email address, which serves as the login name and notification address.
- * @param role {string} - The role to assign. Possible values: master_admin, admin, billing, technical_admin, reports,
- * media_library_admin, media_library_user
- * @param [sub_account_ids] {string[]} - The list of sub-account IDs that this user can access.
- * Note: This parameter is ignored if the role is specified as master_admin.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function create_user(name, email, role, sub_account_ids, options = {}, callback) {
- let uri = ['users'];
- let params = {
- name,
- email,
- role,
- sub_account_ids: sub_account_ids
- };
- options.content_type = 'json';
- return call_account_api('POST', uri, params, callback, options);
-}
-
-/**
- * @desc Updates the details of the specified user.
- * @param user_id {string} - The ID of the user to update.
- * @param [name] {string} - The name of the user.
- * @param [email] {string} - A unique email address, which serves as the login name and notification address.
- * @param [role] {string} - The role to assign. Possible values: master_admin, admin, billing, technical_admin, reports,
- * media_library_admin, media_library_user
- * @param [sub_account_ids] {string[]} - The list of sub-account IDs that this user can access.
- * Note: This parameter is ignored if the role is specified as master_admin.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function update_user(user_id, name, email, role, sub_account_ids, options = {}, callback) {
- let uri = ['users', user_id];
- let params = {
- name,
- email,
- role,
- sub_account_ids: sub_account_ids
- };
- options.content_type = 'json';
- return call_account_api('PUT', uri, params, callback, options);
-}
-
-/**
- * @desc Deletes an existing user.
- * @param user_id {string} - The ID of the user to delete.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function delete_user(user_id, options = {}, callback) {
- let uri = ['users', user_id];
- return call_account_api('DELETE', uri, {}, callback, options);
-}
-
-/**
- * @desc Creates a new user group.
- * @param name {string} - The name for the user group.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function create_user_group(name, options = {}, callback) {
- let uri = ['user_groups'];
- options.content_type = 'json';
- let params = {
- name
- };
- return call_account_api('POST', uri, params, callback, options);
-}
-
-/**
- * @desc Updates the specified user group.
- * @param group_id {string} The ID of the user group to update.
- * @param name {string} - The name for the user group.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function update_user_group(group_id, name, options = {}, callback) {
- let uri = ['user_groups', group_id];
- let params = {
- name
- };
- return call_account_api('PUT', uri, params, callback, options);
-}
-
-/**
- * @desc Deletes the user group with the specified ID.
- * @param group_id {string} The ID of the user group to delete.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function delete_user_group(group_id, options = {}, callback) {
- let uri = ['user_groups', group_id];
- return call_account_api('DELETE', uri, {}, callback, options);
-}
-
-/**
- * @desc Adds a user to a group with the specified ID.
- * @param group_id {string} - The ID of the user group.
- * @param user_id {string} - The ID of the user.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function add_user_to_group(group_id, user_id, options = {}, callback) {
- let uri = ['user_groups', group_id, 'users', user_id];
- return call_account_api('POST', uri, {}, callback, options);
-}
-
-/**
- * @desc Removes a user from a group with the specified ID.
- * @param group_id {string} - The ID of the user group.
- * @param user_id {string} - The ID of the user.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function remove_user_from_group(group_id, user_id, options = {}, callback) {
- let uri = ['user_groups', group_id, 'users', user_id];
- return call_account_api('DELETE', uri, {}, callback, options);
-}
-
-/**
- * @desc Retrieves the details of the specified user group.
- * @param group_id {string} - The ID of the user group to retrieve.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function user_group(group_id, options = {}, callback) {
- let uri = ['user_groups', group_id];
- return call_account_api('GET', uri, {}, callback, options);
-}
-
-/**
- * @desc Lists user groups in the account.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function user_groups(options = {}, callback) {
- let uri = ['user_groups'];
- return call_account_api('GET', uri, {}, callback, options);
-}
-
-/**
- * @desc Lists users in the specified user group.
- * @param group_id {string} - The ID of the user group.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/cloudinary_sdks#configuration_parameters|Configuration parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function user_group_users(group_id, options = {}, callback) {
- let uri = ['user_groups', group_id, 'users'];
- return call_account_api('GET', uri, {}, callback, options);
-}
-
-/**
- * @desc Lists access keys in the given subaccount.
- * @param sub_account_id {string} - The ID of the subaccount.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/provisioning_api#tag/access-keys/GET/sub_accounts/{{sub_account_id}}/access_keys|get access keys optional parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function access_keys(sub_account_id, options = {}, callback) {
- const params = pickOnlyExistingValues({
- page_size: options.page_size,
- page: options.page,
- sort_by: options.sort_by,
- sort_order: options.sort_order
- }, 'page_size', 'page', 'sort_by', 'sort_order');
- const uri = ['sub_accounts', sub_account_id, 'access_keys'];
- return call_account_api('GET', uri, params, callback, options);
-}
-
-/**
- * @desc Generate a new access key pair in the given subaccount.
- * @param sub_account_id {string} - The ID of the subaccount.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/provisioning_api#tag/access-keys/POST/sub_accounts/{{sub_account_id}}/access_keys|generate access key optional parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function generate_access_key(sub_account_id, options = {}, callback) {
- const params = pickOnlyExistingValues({
- name: options.name,
- enabled: options.enabled
- }, 'name', 'enabled');
- options.content_type = "json";
- const uri = ['sub_accounts', sub_account_id, 'access_keys'];
- return call_account_api('POST', uri, params, callback, options);
-}
-
-/**
- * @desc Update an existing access key pair in the given subaccount.
- * @param sub_account_id {string} - The ID of the subaccount.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/provisioning_api#tag/access-keys/PUT/sub_accounts/{sub_account_id}/access_keys/{key}|update access key optional parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function update_access_key(sub_account_id, api_key, options = {}, callback) {
- const params = pickOnlyExistingValues({
- name: options.name,
- enabled: options.enabled
- }, 'name', 'enabled');
- options.content_type = "json";
- const uri = ['sub_accounts', sub_account_id, 'access_keys', api_key];
- return call_account_api('PUT', uri, params, callback, options);
-}
-
-/**
- * @desc Delete an existing access key pair in the given subaccount.
- * @param sub_account_id {string} - The ID of the subaccount.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/provisioning_api#tag/access-keys/DELETE/sub_accounts/{sub_account_id}/access_keys|delete access key optional parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function delete_access_key(sub_account_id, api_key, options = {}, callback) {
- const uri = ['sub_accounts', sub_account_id, 'access_keys', api_key];
- return call_account_api('DELETE', uri, {}, callback, options);
-}
-
-/**
- * @desc Delete an existing access key pair in the given subaccount by its name.
- * @param sub_account_id {string} - The ID of the subaccount.
- * @param [options] {object} - See {@link https://cloudinary.com/documentation/provisioning_api#tag/access-keys/DELETE/sub_accounts/{sub_account_id}/access_keys|delete access key optional parameters} in the SDK documentation.
- * @param [callback] {function}
- */
-function delete_access_key_by_name(sub_account_id, options = {}, callback) {
- const params = { name: options.name };
- const uri = ['sub_accounts', sub_account_id, 'access_keys'];
- return call_account_api('DELETE', uri, params, callback, options);
-}
-
-module.exports = {
- sub_accounts,
- create_sub_account,
- delete_sub_account,
- sub_account,
- update_sub_account,
- user,
- users,
- user_group,
- user_groups,
- user_group_users,
- remove_user_from_group,
- delete_user,
- update_user_group,
- update_user,
- create_user,
- create_user_group,
- add_user_to_group,
- delete_user_group,
- access_keys,
- generate_access_key,
- update_access_key,
- delete_access_key,
- delete_access_key_by_name
-};
diff --git a/server/node_modules/cloudinary/lib/upload_stream.js b/server/node_modules/cloudinary/lib/upload_stream.js
deleted file mode 100644
index de946a9..0000000
--- a/server/node_modules/cloudinary/lib/upload_stream.js
+++ /dev/null
@@ -1,23 +0,0 @@
-
-const Transform = require("stream").Transform;
-
-class UploadStream extends Transform {
- constructor(options) {
- super();
- this.boundary = options.boundary;
- }
-
- _transform(data, encoding, next) {
- let buffer = ((Buffer.isBuffer(data)) ? data : Buffer.from(data, encoding));
- this.push(buffer);
- next();
- }
-
- _flush(next) {
- this.push(Buffer.from("\r\n", 'ascii'));
- this.push(Buffer.from("--" + this.boundary + "--", 'ascii'));
- return next();
- }
-}
-
-module.exports = UploadStream;
diff --git a/server/node_modules/cloudinary/lib/uploader.js b/server/node_modules/cloudinary/lib/uploader.js
deleted file mode 100644
index 93318f0..0000000
--- a/server/node_modules/cloudinary/lib/uploader.js
+++ /dev/null
@@ -1,725 +0,0 @@
-const fs = require('fs');
-const { extname, basename } = require('path');
-const Q = require('q');
-const Writable = require("stream").Writable;
-const urlLib = require('url');
-
-// eslint-disable-next-line import/order
-const { upload_prefix } = require("./config")();
-
-const isSecure = !(upload_prefix && upload_prefix.slice(0, 5) === 'http:');
-const https = isSecure ? require('https') : require('http');
-
-const Cache = require('./cache');
-const utils = require("./utils");
-const UploadStream = require('./upload_stream');
-const config = require("./config");
-const ensureOption = require('./utils/ensureOption').defaults(config());
-
-const agent = config.api_proxy ? new https.Agent(config.api_proxy) : null;
-
-const {
- build_upload_params,
- extend,
- includes,
- isEmpty,
- isObject,
- isRemoteUrl,
- merge,
- pickOnlyExistingValues
-} = utils;
-
-exports.unsigned_upload_stream = function unsigned_upload_stream(upload_preset, callback, options = {}) {
- return exports.upload_stream(callback, merge(options, {
- unsigned: true,
- upload_preset: upload_preset
- }));
-};
-
-exports.upload_stream = function upload_stream(callback, options = {}) {
- return exports.upload(null, callback, extend({
- stream: true
- }, options));
-};
-
-exports.unsigned_upload = function unsigned_upload(file, upload_preset, callback, options = {}) {
- return exports.upload(file, callback, merge(options, {
- unsigned: true,
- upload_preset: upload_preset
- }));
-};
-
-exports.upload = function upload(file, callback, options = {}) {
- return call_api("upload", callback, options, function () {
- let params = build_upload_params(options);
- return isRemoteUrl(file) ? [params, { file: file }] : [params, {}, file];
- });
-};
-
-exports.upload_large = function upload_large(path, callback, options = {}) {
- if ((path != null) && isRemoteUrl(path)) {
- // upload a remote file
- return exports.upload(path, callback, options);
- }
- if (path != null && !options.filename) {
- options.filename = path.split(/(\\|\/)/g).pop().replace(/\.[^/.]+$/, "");
- }
- return exports.upload_chunked(path, callback, extend({
- resource_type: 'raw'
- }, options));
-};
-
-exports.upload_chunked = function upload_chunked(path, callback, options) {
- let file_reader = fs.createReadStream(path);
- let out_stream = exports.upload_chunked_stream(callback, options);
- return file_reader.pipe(out_stream);
-};
-
-class Chunkable extends Writable {
- constructor(options) {
- super(options);
- this.chunk_size = options.chunk_size != null ? options.chunk_size : 20000000;
- this.buffer = Buffer.alloc(0);
- this.active = true;
- this.on('finish', () => {
- if (this.active) {
- this.emit('ready', this.buffer, true, function () {
- });
- }
- });
- }
-
- _write(data, encoding, done) {
- if (!this.active) {
- done();
- }
- if (this.buffer.length + data.length <= this.chunk_size) {
- this.buffer = Buffer.concat([this.buffer, data], this.buffer.length + data.length);
- done();
- } else {
- const grab = this.chunk_size - this.buffer.length;
- this.buffer = Buffer.concat([this.buffer, data.slice(0, grab)], this.buffer.length + grab);
- this.emit('ready', this.buffer, false, (active) => {
- this.active = active;
- if (this.active) {
- // Start processing the remaining data
- const remaining = data.slice(grab);
- this.buffer = Buffer.alloc(0); // Reset the buffer
- this._write(remaining, encoding, done); // Process the remaining data
- }
- });
- }
- }
-}
-
-exports.upload_large_stream = function upload_large_stream(_unused_, callback, options = {}) {
- return exports.upload_chunked_stream(callback, extend({
- resource_type: 'raw'
- }, options));
-};
-
-exports.upload_chunked_stream = function upload_chunked_stream(callback, options = {}) {
- options = extend({}, options, {
- stream: true
- });
- options.x_unique_upload_id = utils.random_public_id();
- let params = build_upload_params(options);
- let chunk_size = options.chunk_size != null ? options.chunk_size : options.part_size;
- let chunker = new Chunkable({
- chunk_size: chunk_size
- });
- let sent = 0;
- chunker.on('ready', function (buffer, is_last, done) {
- let chunk_start = sent;
- sent += buffer.length;
- options.content_range = `bytes ${chunk_start}-${sent - 1}/${(is_last ? sent : -1)}`;
- params.timestamp = utils.timestamp();
- let finished_part = function (result) {
- const errorOrLast = (result.error != null) || is_last;
- if (errorOrLast && typeof callback === "function") {
- callback(result);
- }
- return done(!errorOrLast);
- };
- let stream = call_api("upload", finished_part, options, function () {
- return [params, {}, buffer];
- });
- return stream.write(buffer, 'buffer', function () {
- return stream.end();
- });
- });
- return chunker;
-};
-
-exports.explicit = function explicit(public_id, callback, options = {}) {
- return call_api("explicit", callback, options, function () {
- return utils.build_explicit_api_params(public_id, options);
- });
-};
-
-// Creates a new archive in the server and returns information in JSON format
-exports.create_archive = function create_archive(callback, options = {}, target_format = null) {
- return call_api("generate_archive", callback, options, function () {
- let opt = utils.archive_params(options);
- if (target_format) {
- opt.target_format = target_format;
- }
- return [opt];
- });
-};
-
-// Creates a new zip archive in the server and returns information in JSON format
-exports.create_zip = function create_zip(callback, options = {}) {
- return exports.create_archive(callback, options, "zip");
-};
-
-
-exports.create_slideshow = function create_slideshow(options, callback) {
- options.resource_type = ensureOption(options, "resource_type", "video");
- return call_api("create_slideshow", callback, options, function () {
- // Generate a transformation from the manifest_transformation key, which should be a valid transformation
- const manifest_transformation = utils.generate_transformation_string(extend({}, options.manifest_transformation));
-
- // Try to use {options.transformation} to generate a transformation (Example: options.transformation.width, options.transformation.height)
- const transformation = utils.generate_transformation_string(extend({}, ensureOption(options, 'transformation', {})));
-
- return [
- {
- timestamp: utils.timestamp(),
- manifest_transformation: manifest_transformation,
- upload_preset: options.upload_preset,
- overwrite: options.overwrite,
- public_id: options.public_id,
- notification_url: options.notification_url,
- manifest_json: options.manifest_json,
- tags: options.tags,
- transformation: transformation
- }
- ];
- });
-};
-
-
-exports.destroy = function destroy(public_id, callback, options = {}) {
- return call_api("destroy", callback, options, function () {
- return [
- {
- timestamp: utils.timestamp(),
- type: options.type,
- invalidate: options.invalidate,
- public_id: public_id,
- notification_url: options.notification_url
- }
- ];
- });
-};
-
-exports.rename = function rename(from_public_id, to_public_id, callback, options = {}) {
- return call_api("rename", callback, options, function () {
- return [
- {
- timestamp: utils.timestamp(),
- type: options.type,
- from_public_id: from_public_id,
- to_public_id: to_public_id,
- overwrite: options.overwrite,
- invalidate: options.invalidate,
- to_type: options.to_type,
- context: options.context,
- metadata: options.metadata,
- notification_url: options.notification_url
- }
- ];
- });
-};
-
-const TEXT_PARAMS = ["public_id", "font_family", "font_size", "font_color", "text_align", "font_weight", "font_style", "background", "opacity", "text_decoration", "font_hinting", "font_antialiasing"];
-
-exports.text = function text(content, callback, options = {}) {
- return call_api("text", callback, options, function () {
- let textParams = pickOnlyExistingValues(options, ...TEXT_PARAMS);
- let params = {
- timestamp: utils.timestamp(),
- text: content,
- ...textParams
- };
-
- return [params];
- });
-};
-
-/**
- * Generate a sprite by merging multiple images into a single large image for reducing network overhead and bypassing
- * download limitations.
- *
- * The process produces 2 files as follows:
- * - A single image file containing all the images with the specified tag (PNG by default).
- * - A CSS file that includes the style class names and the location of the individual images in the sprite.
- *
- * @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
- * which includes options and image URLs.
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
- * should be empty
- *
- * @return {Object}
- */
-exports.generate_sprite = function generate_sprite(tag, callback, options = {}) {
- return call_api("sprite", callback, options, function () {
- return [utils.build_multi_and_sprite_params(tag, options)];
- });
-};
-
-
-/**
- * Returns a signed url to download a sprite
- *
- * @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
- * which includes options and image URLs.
- * @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
- * should be empty
- *
- * @returns {string}
- */
-exports.download_generated_sprite = function download_generated_sprite(tag, options = {}) {
- return utils.api_download_url("sprite", utils.build_multi_and_sprite_params(tag, options), options);
-}
-
-/**
- * Returns a signed url to download a single animated image (GIF, PNG or WebP), video (MP4 or WebM) or a single PDF from
- * multiple image assets.
- *
- * @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
- * which includes options and image URLs.
- * @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
- * should be empty
- *
- * @returns {string}
- */
-exports.download_multi = function download_multi(tag, options = {}) {
- return utils.api_download_url("multi", utils.build_multi_and_sprite_params(tag, options), options);
-}
-
-/**
- * Creates either a single animated image (GIF, PNG or WebP), video (MP4 or WebM) or a single PDF from multiple image
- * assets.
- *
- * Each asset is included as a single frame of the resulting animated image/video, or a page of the PDF (sorted
- * alphabetically by their Public ID).
- *
- * @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
- * which includes options and image URLs.
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
- * should be empty
- *
- * @return {Object}
- */
-exports.multi = function multi(tag, callback, options = {}) {
- return call_api("multi", callback, options, function () {
- return [utils.build_multi_and_sprite_params(tag, options)];
- });
-};
-
-exports.explode = function explode(public_id, callback, options = {}) {
- return call_api("explode", callback, options, function () {
- const transformation = utils.generate_transformation_string(extend({}, options));
- return [
- {
- timestamp: utils.timestamp(),
- public_id: public_id,
- transformation: transformation,
- format: options.format,
- type: options.type,
- notification_url: options.notification_url
- }
- ];
- });
-};
-
-/**
- *
- * @param {String} tag The tag or tags to assign. Can specify multiple
- * tags in a single string, separated by commas - "t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11".
- *
- * @param {Array} public_ids A list of public IDs (up to 1000) of assets uploaded to Cloudinary.
- *
- * @param {Function} callback Callback function
- *
- * @param {Object} options Configuration options may include 'exclusive' (boolean) which causes
- * clearing this tag from all other resources
- * @return {Object}
- */
-exports.add_tag = function add_tag(tag, public_ids = [], callback, options = {}) {
- const exclusive = utils.option_consume("exclusive", options);
- const command = exclusive ? "set_exclusive" : "add";
- return call_tags_api(tag, command, public_ids, callback, options);
-};
-
-
-/**
- * @param {String} tag The tag or tags to remove. Can specify multiple
- * tags in a single string, separated by commas - "t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11".
- *
- * @param {Array} public_ids A list of public IDs (up to 1000) of assets uploaded to Cloudinary.
- *
- * @param {Function} callback Callback function
- *
- * @param {Object} options Configuration options may include 'exclusive' (boolean) which causes
- * clearing this tag from all other resources
- * @return {Object}
- */
-exports.remove_tag = function remove_tag(tag, public_ids = [], callback, options = {}) {
- return call_tags_api(tag, "remove", public_ids, callback, options);
-};
-
-exports.remove_all_tags = function remove_all_tags(public_ids = [], callback, options = {}) {
- return call_tags_api(null, "remove_all", public_ids, callback, options);
-};
-
-exports.replace_tag = function replace_tag(tag, public_ids = [], callback, options = {}) {
- return call_tags_api(tag, "replace", public_ids, callback, options);
-};
-
-function call_tags_api(tag, command, public_ids = [], callback, options = {}) {
- return call_api("tags", callback, options, function () {
- let params = {
- timestamp: utils.timestamp(),
- public_ids: utils.build_array(public_ids),
- command: command,
- type: options.type
- };
- if (tag != null) {
- params.tag = tag;
- }
- return [params];
- });
-}
-
-exports.add_context = function add_context(context, public_ids = [], callback, options = {}) {
- return call_context_api(context, 'add', public_ids, callback, options);
-};
-
-exports.remove_all_context = function remove_all_context(public_ids = [], callback, options = {}) {
- return call_context_api(null, 'remove_all', public_ids, callback, options);
-};
-
-function call_context_api(context, command, public_ids = [], callback, options = {}) {
- return call_api('context', callback, options, function () {
- let params = {
- timestamp: utils.timestamp(),
- public_ids: utils.build_array(public_ids),
- command: command,
- type: options.type
- };
- if (context != null) {
- params.context = utils.encode_context(context);
- }
- return [params];
- });
-}
-
-/**
- * Cache (part of) the upload results.
- * @param result
- * @param {object} options
- * @param {string} options.type
- * @param {string} options.resource_type
- */
-function cacheResults(result, { type, resource_type }) {
- if (result.responsive_breakpoints) {
- result.responsive_breakpoints.forEach(
- ({ transformation,
- url,
- breakpoints }) => Cache.set(
- result.public_id,
- { type, resource_type, raw_transformation: transformation, format: extname(breakpoints[0].url).slice(1) },
- breakpoints.map(i => i.width)
- )
- );
- }
-}
-
-
-function parseResult(buffer, res) {
- let result = '';
- try {
- result = JSON.parse(buffer);
- if (result.error && !result.error.name) {
- result.error.name = "Error";
- }
- } catch (jsonError) {
- result = {
- error: {
- message: `Server return invalid JSON response. Status Code ${res.statusCode}. ${jsonError}`,
- name: "Error"
- }
- };
- }
- return result;
-}
-
-function call_api(action, callback, options, get_params) {
- if (typeof callback !== "function") {
- callback = function () {};
- }
-
- const USE_PROMISES = !options.disable_promises;
-
- let deferred = Q.defer();
- if (options == null) {
- options = {};
- }
- let [params, unsigned_params, file] = get_params.call();
- params = utils.process_request_params(params, options);
- params = extend(params, unsigned_params);
- let api_url = utils.api_url(action, options);
- let boundary = utils.random_public_id();
- let errorRaised = false;
- let handle_response = function (res) {
- // let buffer;
- if (errorRaised) {
-
- // Already reported
- } else if (res.error) {
- errorRaised = true;
-
- if (USE_PROMISES) {
- deferred.reject(res);
- }
- callback(res);
- } else if (includes([200, 400, 401, 404, 420, 500], res.statusCode)) {
- let buffer = "";
- res.on("data", (d) => {
- buffer += d;
- return buffer;
- });
- res.on("end", () => {
- let result;
- if (errorRaised) {
- return;
- }
- result = parseResult(buffer, res);
- if (result.error) {
- result.error.http_code = res.statusCode;
- if (USE_PROMISES) {
- deferred.reject(result.error);
- }
- } else {
- cacheResults(result, options);
- if (USE_PROMISES) {
- deferred.resolve(result);
- }
- }
- callback(result);
- });
- res.on("error", (error) => {
- errorRaised = true;
- if (USE_PROMISES) {
- deferred.reject(error);
- }
- callback({ error });
- });
- } else {
- let error = {
- message: `Server returned unexpected status code - ${res.statusCode}`,
- http_code: res.statusCode,
- name: "UnexpectedResponse"
- };
- if (USE_PROMISES) {
- deferred.reject(error);
- }
- callback({ error });
- }
- };
- let post_data = utils.hashToParameters(params)
- .filter(([key, value]) => value != null)
- .map(
- ([key, value]) => Buffer.from(encodeFieldPart(boundary, key, value), 'utf8')
- );
- let result = post(api_url, post_data, boundary, file, handle_response, options);
- if (isObject(result)) {
- return result;
- }
-
- if (USE_PROMISES) {
- return deferred.promise;
- }
-}
-
-function post(url, post_data, boundary, file, callback, options) {
- let file_header;
- let finish_buffer = Buffer.from("--" + boundary + "--", 'ascii');
- let oauth_token = options.oauth_token || config().oauth_token;
- if ((file != null) || options.stream) {
- // eslint-disable-next-line no-nested-ternary
- let filename = options.stream ? options.filename ? options.filename : "file" : basename(file);
- file_header = Buffer.from(encodeFilePart(boundary, 'application/octet-stream', 'file', filename), 'binary');
- }
- let post_options = urlLib.parse(url);
- let headers = {
- 'Content-Type': `multipart/form-data; boundary=${boundary}`,
- 'User-Agent': utils.getUserAgent()
- };
- if (options.content_range != null) {
- headers['Content-Range'] = options.content_range;
- }
- if (options.x_unique_upload_id != null) {
- headers['X-Unique-Upload-Id'] = options.x_unique_upload_id;
- }
- if (options.extra_headers !== null) {
- headers = merge(headers, options.extra_headers);
- }
- if (oauth_token != null) {
- headers.Authorization = `Bearer ${oauth_token}`;
- }
-
- post_options = extend(post_options, {
- method: 'POST',
- headers: headers
- });
- if (options.agent != null) {
- post_options.agent = options.agent;
- }
- let proxy = options.api_proxy || config().api_proxy;
- if (!isEmpty(proxy)) {
- if (!post_options.agent && agent) {
- post_options.agent = agent;
- } else if (!post_options.agent) {
- post_options.agent = new https.Agent(proxy);
- } else {
- console.warn("Proxy is set, but request uses a custom agent, proxy is ignored.");
- }
- }
-
- let post_request = https.request(post_options, callback);
- let upload_stream = new UploadStream({ boundary });
- upload_stream.pipe(post_request);
- let timeout = false;
- post_request.on("error", function (error) {
- if (timeout) {
- error = {
- message: "Request Timeout",
- http_code: 499,
- name: "TimeoutError"
- };
- }
- return callback({ error });
- });
- post_request.setTimeout(options.timeout != null ? options.timeout : 60000, function () {
- timeout = true;
- return post_request.abort();
- });
- post_data.forEach(postDatum => post_request.write(postDatum));
- if (options.stream) {
- post_request.write(file_header);
- return upload_stream;
- }
- if (file != null) {
- post_request.write(file_header);
- fs.createReadStream(file).on('error', function (error) {
- callback({
- error: error
- });
- return post_request.abort();
- }).pipe(upload_stream);
- } else {
- post_request.write(finish_buffer);
- post_request.end();
- }
- return true;
-}
-
-function encodeFieldPart(boundary, name, value) {
- return [
- `--${boundary}\r\n`,
- `Content-Disposition: form-data; name="${name}"\r\n`,
- '\r\n',
- `${value}\r\n`,
- ''
- ].join('');
-}
-
-function encodeFilePart(boundary, type, name, filename) {
- return [
- `--${boundary}\r\n`,
- `Content-Disposition: form-data; name="${name}"; filename="${filename}"\r\n`,
- `Content-Type: ${type}\r\n`,
- '\r\n',
- ''
- ].join('');
-}
-
-exports.direct_upload = function direct_upload(callback_url, options = {}) {
- let params = build_upload_params(extend({
- callback: callback_url
- }, options));
- params = utils.process_request_params(params, options);
- let api_url = utils.api_url("upload", options);
- return {
- hidden_fields: params,
- form_attrs: {
- action: api_url,
- method: "POST",
- enctype: "multipart/form-data"
- }
- };
-};
-
-exports.upload_tag_params = function upload_tag_params(options = {}) {
- let params = build_upload_params(options);
- params = utils.process_request_params(params, options);
- return JSON.stringify(params);
-};
-
-exports.upload_url = function upload_url(options = {}) {
- if (options.resource_type == null) {
- options.resource_type = "auto";
- }
- return utils.api_url("upload", options);
-};
-
-exports.image_upload_tag = function image_upload_tag(field, options = {}) {
- let html_options = options.html || {};
- let tag_options = extend({
- type: "file",
- name: "file",
- "data-url": exports.upload_url(options),
- "data-form-data": exports.upload_tag_params(options),
- "data-cloudinary-field": field,
- "data-max-chunk-size": options.chunk_size,
- "class": [html_options.class, "cloudinary-fileupload"].join(" ")
- }, html_options);
- return ``;
-};
-
-exports.unsigned_image_upload_tag = function unsigned_image_upload_tag(field, upload_preset, options = {}) {
- return exports.image_upload_tag(field, merge(options, {
- unsigned: true,
- upload_preset: upload_preset
- }));
-};
-
-
-/**
- * Populates metadata fields with the given values. Existing values will be overwritten.
- *
- * @param {Object} metadata A list of custom metadata fields (by external_id) and the values to assign to each
- * @param {Array} public_ids The public IDs of the resources to update
- * @param {Function} callback Callback function
- * @param {Object} options Configuration options
- *
- * @return {Object}
- */
-exports.update_metadata = function update_metadata(metadata, public_ids, callback, options = {}) {
- return call_api("metadata", callback, options, function () {
- let params = {
- metadata: utils.encode_context(metadata),
- public_ids: utils.build_array(public_ids),
- timestamp: utils.timestamp(),
- type: options.type,
- clear_invalid: options.clear_invalid
- };
- return [params];
- });
-};
diff --git a/server/node_modules/cloudinary/lib/utils/analytics/encodeVersion.js b/server/node_modules/cloudinary/lib/utils/analytics/encodeVersion.js
deleted file mode 100644
index 89ee463..0000000
--- a/server/node_modules/cloudinary/lib/utils/analytics/encodeVersion.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const reverseVersion = require('./reverseVersion');
-const stringPad = require('./stringPad');
-const base64Map = require('../encoding/base64Map');
-
-/**
- * @private
- * @description Encodes a semVer-like version string
- * @param {string} semVer Input can be either x.y.z or x.y
- * @return {string} A string built from 3 characters of the base64 table that encode the semVer
- */
-module.exports = (semVer) => {
- let strResult = '';
-
- // support x.y or x.y.z by using 'parts' as a variable
- let parts = semVer.split('.').length;
- let paddedStringLength = parts * 6; // we pad to either 12 or 18 characters
-
- // reverse (but don't mirror) the version. 1.5.15 -> 15.5.1
- // Pad to two spaces, 15.5.1 -> 15.05.01
- let paddedReversedSemver = reverseVersion(semVer);
-
- // turn 15.05.01 to a string '150501' then to a number 150501
- let num = parseInt(paddedReversedSemver.split('.').join(''));
-
- // Represent as binary, add left padding to 12 or 18 characters.
- // 150,501 -> 100100101111100101
-
- let paddedBinary = num.toString(2);
- paddedBinary = stringPad(paddedBinary, paddedStringLength, '0');
-
- // Stop in case an invalid version number was provided
- // paddedBinary must be built from sections of 6 bits
- if (paddedBinary.length % 6 !== 0) {
- throw 'Version must be smaller than 43.21.26)';
- }
-
- // turn every 6 bits into a character using the base64Map
- paddedBinary.match(/.{1,6}/g).forEach((bitString) => {
- // console.log(bitString);
- strResult += base64Map[bitString];
- });
-
- return strResult;
-};
diff --git a/server/node_modules/cloudinary/lib/utils/analytics/getSDKVersions.js b/server/node_modules/cloudinary/lib/utils/analytics/getSDKVersions.js
deleted file mode 100644
index 14daeb2..0000000
--- a/server/node_modules/cloudinary/lib/utils/analytics/getSDKVersions.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-const sdkCode = 'M'; // Constant per SDK
-
-function readSdkSemver() {
- const pkgJsonPath = path.join(__dirname, '../../../package.json');
- try {
- const pkgJSONFile = fs.readFileSync(pkgJsonPath, 'utf-8');
- return JSON.parse(pkgJSONFile).version
- } catch (e) {
- if (e.code === 'ENOENT') {
- return '0.0.0'
- }
- return 'n/a';
- }
-}
-
-/**
- * @description Gets the relevant versions of the SDK(package version, node version and sdkCode)
- * @param {'default' | 'x.y.z' | 'x.y' | string} useSDKVersion Default uses package.json version
- * @param {'default' | 'x.y.z' | 'x.y' | string} useNodeVersion Default uses process.versions.node
- * @return {{sdkSemver:string, techVersion:string, sdkCode:string}} A map of relevant versions and codes
- */
-function getSDKVersions(useSDKVersion = 'default', useNodeVersion = 'default') {
- // allow to pass a custom SDKVersion
- const sdkSemver = useSDKVersion === 'default' ? readSdkSemver() : useSDKVersion;
-
- // allow to pass a custom techVersion (Node version)
- const version = process.version.slice(1);
- const techVersion = useNodeVersion === 'default' ? version : useNodeVersion;
-
- const product = 'A';
-
- return {
- sdkSemver,
- techVersion,
- sdkCode,
- product
- };
-}
-
-module.exports = getSDKVersions;
diff --git a/server/node_modules/cloudinary/lib/utils/analytics/index.js b/server/node_modules/cloudinary/lib/utils/analytics/index.js
deleted file mode 100644
index 08bca7c..0000000
--- a/server/node_modules/cloudinary/lib/utils/analytics/index.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const removePatchFromSemver = require('./removePatchFromSemver');
-const encodeVersion = require('./encodeVersion');
-
-/**
- * @description Gets the SDK signature by encoding the SDK version and tech version
- * @param {{
- * [techVersion]:string,
- * [sdkSemver]: string,
- * [sdkCode]: string,
- * [product]: string,
- * [feature]: string
- * }} analyticsOptions
- * @return {string} sdkAnalyticsSignature
- */
-function getSDKAnalyticsSignature(analyticsOptions = {}) {
- try {
- const twoPartVersion = removePatchFromSemver(analyticsOptions.techVersion);
- const encodedSDKVersion = encodeVersion(analyticsOptions.sdkSemver);
- const encodedTechVersion = encodeVersion(twoPartVersion);
- const featureCode = analyticsOptions.feature;
- const SDKCode = analyticsOptions.sdkCode;
- const product = analyticsOptions.product;
- const algoVersion = 'B'; // The algo version is determined here, it should not be an argument
-
- return `${algoVersion}${product}${SDKCode}${encodedSDKVersion}${encodedTechVersion}${featureCode}`;
- } catch (e) {
- // Either SDK or Node versions were unparsable
- return 'E';
- }
-}
-
-/**
- * @description Gets the analyticsOptions from options - should include sdkSemver, techVersion, sdkCode, and feature
- * @param options
- * @returns {{sdkSemver: (string), sdkCode, product, feature: string, techVersion: (string)} || {}}
- */
-function getAnalyticsOptions(options) {
- let analyticsOptions = {
- sdkSemver: options.sdkSemver,
- techVersion: options.techVersion,
- sdkCode: options.sdkCode,
- product: options.product,
- feature: '0'
- };
- if (options.urlAnalytics) {
- if (options.accessibility) {
- analyticsOptions.feature = 'D';
- }
- if (options.loading === 'lazy') {
- analyticsOptions.feature = 'C';
- }
- if (options.responsive) {
- analyticsOptions.feature = 'A';
- }
- if (options.placeholder) {
- analyticsOptions.feature = 'B';
- }
- return analyticsOptions;
- } else {
- return {};
- }
-}
-
-module.exports = {
- getSDKAnalyticsSignature,
- getAnalyticsOptions
-};
diff --git a/server/node_modules/cloudinary/lib/utils/analytics/removePatchFromSemver.js b/server/node_modules/cloudinary/lib/utils/analytics/removePatchFromSemver.js
deleted file mode 100644
index b282836..0000000
--- a/server/node_modules/cloudinary/lib/utils/analytics/removePatchFromSemver.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * @description Removes patch version from the semver if it exists
- * Turns x.y.z OR x.y into x.y
- * @param {'x.y.z' || 'x.y' || string} semVerStr
- */
-module.exports = (semVerStr) => {
- let parts = semVerStr.split('.');
- return `${parts[0]}.${parts[1]}`;
-}
diff --git a/server/node_modules/cloudinary/lib/utils/analytics/reverseVersion.js b/server/node_modules/cloudinary/lib/utils/analytics/reverseVersion.js
deleted file mode 100644
index c26ba1c..0000000
--- a/server/node_modules/cloudinary/lib/utils/analytics/reverseVersion.js
+++ /dev/null
@@ -1,20 +0,0 @@
-const stringPad = require('./stringPad');
-
-/**
- * @description A semVer like string, x.y.z or x.y is allowed
- * Reverses the version positions, x.y.z turns to z.y.x
- * Pads each segment with '0' so they have length of 2
- * Example: 1.2.3 -> 03.02.01
- * @param {string} semVer Input can be either x.y.z or x.y
- * @return {string} in the form of zz.yy.xx (
- */
-module.exports = (semVer) => {
- if (semVer.split('.').length < 2) {
- throw new Error('invalid semVer, must have at least two segments');
- }
-
- // Split by '.', reverse, create new array with padded values and concat it together
- return semVer.split('.').reverse().map((segment) => {
- return stringPad(segment, 2, '0');
- }).join('.');
-};
diff --git a/server/node_modules/cloudinary/lib/utils/analytics/stringPad.js b/server/node_modules/cloudinary/lib/utils/analytics/stringPad.js
deleted file mode 100644
index df83466..0000000
--- a/server/node_modules/cloudinary/lib/utils/analytics/stringPad.js
+++ /dev/null
@@ -1,22 +0,0 @@
-function repeatStringNumTimes(string, times) {
- let repeatedString = "";
- while (times > 0) {
- repeatedString += string;
- times--;
- }
- return repeatedString;
-}
-
-module.exports = (value, targetLength, padString) => {
- targetLength = targetLength >> 0; // truncate if number or convert non-number to 0;
- padString = String((typeof padString !== 'undefined' ? padString : ' '));
- if (value.length > targetLength) {
- return String(value);
- } else {
- targetLength = targetLength - value.length;
- if (targetLength > padString.length) {
- padString += repeatStringNumTimes(padString, targetLength / padString.length);
- }
- return padString.slice(0, targetLength) + String(value);
- }
-}
diff --git a/server/node_modules/cloudinary/lib/utils/consts.js b/server/node_modules/cloudinary/lib/utils/consts.js
deleted file mode 100644
index 90f7449..0000000
--- a/server/node_modules/cloudinary/lib/utils/consts.js
+++ /dev/null
@@ -1,149 +0,0 @@
-const DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION = {
- width: "auto",
- crop: "limit"
-};
-
-const DEFAULT_POSTER_OPTIONS = {
- format: 'jpg',
- resource_type: 'video'
-};
-
-const DEFAULT_VIDEO_SOURCE_TYPES = ['webm', 'mp4', 'ogv'];
-
-const CONDITIONAL_OPERATORS = {
- "=": 'eq',
- "!=": 'ne',
- "<": 'lt',
- ">": 'gt',
- "<=": 'lte',
- ">=": 'gte',
- "&&": 'and',
- "||": 'or',
- "*": "mul",
- "/": "div",
- "+": "add",
- "-": "sub",
- "^": "pow"
-};
-
-let SIMPLE_PARAMS = [
- ["audio_codec", "ac"],
- ["audio_frequency", "af"],
- ["bit_rate", 'br'],
- ["color_space", "cs"],
- ["default_image", "d"],
- ["delay", "dl"],
- ["density", "dn"],
- ["duration", "du"],
- ["end_offset", "eo"],
- ["fetch_format", "f"],
- ["gravity", "g"],
- ["page", "pg"],
- ["prefix", "p"],
- ["start_offset", "so"],
- ["streaming_profile", "sp"],
- ["video_codec", "vc"],
- ["video_sampling", "vs"]
-];
-
-const PREDEFINED_VARS = {
- "aspect_ratio": "ar",
- "aspectRatio": "ar",
- "current_page": "cp",
- "currentPage": "cp",
- "duration": "du",
- "face_count": "fc",
- "faceCount": "fc",
- "height": "h",
- "initial_aspect_ratio": "iar",
- "initial_height": "ih",
- "initial_width": "iw",
- "initialAspectRatio": "iar",
- "initialHeight": "ih",
- "initialWidth": "iw",
- "initial_duration": "idu",
- "initialDuration": "idu",
- "page_count": "pc",
- "page_x": "px",
- "page_y": "py",
- "pageCount": "pc",
- "pageX": "px",
- "pageY": "py",
- "tags": "tags",
- "width": "w"
-};
-
-const TRANSFORMATION_PARAMS = [
- 'angle',
- 'aspect_ratio',
- 'audio_codec',
- 'audio_frequency',
- 'background',
- 'bit_rate',
- 'border',
- 'color',
- 'color_space',
- 'crop',
- 'default_image',
- 'delay',
- 'density',
- 'dpr',
- 'duration',
- 'effect',
- 'end_offset',
- 'fetch_format',
- 'flags',
- 'fps',
- 'gravity',
- 'height',
- 'if',
- 'keyframe_interval',
- 'offset',
- 'opacity',
- 'overlay',
- 'page',
- 'prefix',
- 'quality',
- 'radius',
- 'raw_transformation',
- 'responsive_width',
- 'size',
- 'start_offset',
- 'streaming_profile',
- 'transformation',
- 'underlay',
- 'variables',
- 'video_codec',
- 'video_sampling',
- 'width',
- 'x',
- 'y',
- 'zoom' // + any key that starts with '$'
-];
-
-const LAYER_KEYWORD_PARAMS = {
- font_weight: "normal",
- font_style: "normal",
- text_decoration: "none",
- text_align: null,
- stroke: "none"
-};
-
-const UPLOAD_PREFIX = "https://api.cloudinary.com";
-
-const SUPPORTED_SIGNATURE_ALGORITHMS = ["sha1", "sha256"];
-const DEFAULT_SIGNATURE_ALGORITHM = "sha1";
-
-module.exports = {
- DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION,
- DEFAULT_POSTER_OPTIONS,
- DEFAULT_VIDEO_SOURCE_TYPES,
- CONDITIONAL_OPERATORS,
- PREDEFINED_VARS,
- LAYER_KEYWORD_PARAMS,
- TRANSFORMATION_PARAMS,
- SIMPLE_PARAMS,
- UPLOAD_PREFIX,
- SUPPORTED_SIGNATURE_ALGORITHMS,
- DEFAULT_SIGNATURE_ALGORITHM
-};
diff --git a/server/node_modules/cloudinary/lib/utils/crc32.js b/server/node_modules/cloudinary/lib/utils/crc32.js
deleted file mode 100644
index e8c21d3..0000000
--- a/server/node_modules/cloudinary/lib/utils/crc32.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* eslint-disable no-bitwise */
-// http://kevin.vanzonneveld.net
-// + original by: Webtoolkit.info (http://www.webtoolkit.info/)
-// + improved by: T0bsn
-// + improved by: http://stackoverflow.com/questions/2647935/javascript-crc32-function-and-php-crc32-not-matching
-// - depends on: utf8_encode
-// * example 1: crc32('Kevin van Zonneveld')
-// * returns 1: 1249991249
-
-const utf8_encode = require('./utf8_encode');
-
-/**
- * Compute the crc32 checksum if the given string
- * @private
- * @param {string} str
- * @return {number|*}
- */
-function crc32(str) {
- let crc, i, iTop, table, x, y;
- str = utf8_encode(str);
- table = "00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D";
- crc = 0;
- x = 0;
- y = 0;
- crc = crc ^ (-1);
- i = 0;
- iTop = str.length;
- while (i < iTop) {
- y = (crc ^ str.charCodeAt(i)) & 0xFF;
- x = "0x" + table.substr(y * 9, 8);
- crc = (crc >>> 8) ^ x;
- i++;
- }
- crc = crc ^ (-1);
- if (crc < 0) {
- crc += 4294967296;
- }
- return crc;
-}
-
-module.exports = crc32;
diff --git a/server/node_modules/cloudinary/lib/utils/encoding/base64Encode.js b/server/node_modules/cloudinary/lib/utils/encoding/base64Encode.js
deleted file mode 100644
index e3aa190..0000000
--- a/server/node_modules/cloudinary/lib/utils/encoding/base64Encode.js
+++ /dev/null
@@ -1,8 +0,0 @@
-function base64Encode(input) {
- if (!(input instanceof Buffer)) {
- input = Buffer.from(String(input), 'binary');
- }
- return input.toString('base64');
-}
-
-module.exports.base64Encode = base64Encode;
diff --git a/server/node_modules/cloudinary/lib/utils/encoding/base64EncodeURL.js b/server/node_modules/cloudinary/lib/utils/encoding/base64EncodeURL.js
deleted file mode 100644
index 738a789..0000000
--- a/server/node_modules/cloudinary/lib/utils/encoding/base64EncodeURL.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const { base64Encode } = require('./base64Encode')
-
-function base64EncodeURL(sourceUrl) {
- try {
- sourceUrl = decodeURI(sourceUrl);
- } catch (error) {
- // ignore errors
- }
- sourceUrl = encodeURI(sourceUrl);
- return base64Encode(sourceUrl)
- .replace(/\+/g, '-') // Convert '+' to '-'
- .replace(/\//g, '_') // Convert '/' to '_'
- .replace(/=+$/, ''); // Remove ending '=';
-}
-
-
-module.exports.base64EncodeURL = base64EncodeURL;
diff --git a/server/node_modules/cloudinary/lib/utils/encoding/base64Map.js b/server/node_modules/cloudinary/lib/utils/encoding/base64Map.js
deleted file mode 100644
index 58b3767..0000000
--- a/server/node_modules/cloudinary/lib/utils/encoding/base64Map.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const stringPad = require('../analytics/stringPad');
-
-const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
-let num = 0;
-
-/**
- * Map of six-bit binary codes to Base64 characters
- */
-let base64Map = {};
-
-[...chars].forEach((char) => {
- let key = num.toString(2);
- key = stringPad(key, 6, '0');
- base64Map[key] = char;
- num++;
-});
-
-module.exports = base64Map;
diff --git a/server/node_modules/cloudinary/lib/utils/encoding/encodeDoubleArray.js b/server/node_modules/cloudinary/lib/utils/encoding/encodeDoubleArray.js
deleted file mode 100644
index 9251b92..0000000
--- a/server/node_modules/cloudinary/lib/utils/encoding/encodeDoubleArray.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const isArray = require('lodash/isArray');
-const toArray = require('../parsing/toArray');
-
-/**
- * Serialize an array of arrays into a string
- * @param {string[] | Array.>} array - An array of arrays.
- * If the first element is not an array the argument is wrapped in an array.
- * @returns {string} A string representation of the arrays.
- */
-function encodeDoubleArray(array) {
- array = toArray(array);
- if (!isArray(array[0])) {
- array = [array];
- }
- return array.map(e => toArray(e).join(",")).join("|");
-}
-
-module.exports = encodeDoubleArray;
diff --git a/server/node_modules/cloudinary/lib/utils/encoding/smart_escape.js b/server/node_modules/cloudinary/lib/utils/encoding/smart_escape.js
deleted file mode 100644
index e3e9fc9..0000000
--- a/server/node_modules/cloudinary/lib/utils/encoding/smart_escape.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Based on CGI::unescape. In addition does not escape / :
-// smart_escape = (string) => encodeURIComponent(string).replace(/%3A/g, ":").replace(/%2F/g, "/")
-function smart_escape(string, unsafe = /([^a-zA-Z0-9_.\-\/:]+)/g) {
- return string.replace(unsafe, function (match) {
- return match.split("").map(function (c) {
- return "%" + c.charCodeAt(0).toString(16).toUpperCase();
- }).join("");
- });
-}
-
-module.exports = smart_escape;
diff --git a/server/node_modules/cloudinary/lib/utils/ensureOption.js b/server/node_modules/cloudinary/lib/utils/ensureOption.js
deleted file mode 100644
index 16d1473..0000000
--- a/server/node_modules/cloudinary/lib/utils/ensureOption.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Returns an ensureOption function that relies on the provided `defaultOptions` argument
- * for default values.
- * @private
- * @param {object} defaultOptions
- * @return {function(*, *, *=): *}
- */
-function defaults(defaultOptions) {
- return function ensureOption(options, name, defaultValue) {
- let value;
-
- if (typeof options[name] !== 'undefined') {
- value = options[name];
- } else if (typeof defaultOptions[name] !== 'undefined') {
- value = defaultOptions[name];
- } else if (typeof defaultValue !== 'undefined') {
- value = defaultValue;
- } else {
- throw new Error(`Must supply ${name}`);
- }
-
- return value;
- };
-}
-
-/**
- * Get the option `name` from options, the global config, or the default value.
- * If the value is not defined and no default value was provided,
- * the method will throw an error.
- * @private
- * @param {object} options
- * @param {string} name
- * @param {*} [defaultValue]
- * @return {*} the value associated with the provided `name` or the default.
- *
- */
-module.exports = defaults({});
-
-module.exports.defaults = defaults;
diff --git a/server/node_modules/cloudinary/lib/utils/ensurePresenceOf.js b/server/node_modules/cloudinary/lib/utils/ensurePresenceOf.js
deleted file mode 100644
index 15adff8..0000000
--- a/server/node_modules/cloudinary/lib/utils/ensurePresenceOf.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Validate that the given values are defined
- * @private
- * @param {object} parameters where each key value pair is the name and value of the argument to validate.
- *
- * @example
- *
- * function foo(bar){
- * ensurePresenceOf({bar});
- * // ...
- * }
- */
-function ensurePresenceOf(parameters) {
- let missing = Object.keys(parameters).filter(key => parameters[key] === undefined);
- if (missing.length) {
- console.error(missing.join(',') + " cannot be undefined");
- }
-}
-
-module.exports = ensurePresenceOf;
diff --git a/server/node_modules/cloudinary/lib/utils/entries.js b/server/node_modules/cloudinary/lib/utils/entries.js
deleted file mode 100644
index 6bf8e19..0000000
--- a/server/node_modules/cloudinary/lib/utils/entries.js
+++ /dev/null
@@ -1,10 +0,0 @@
-module.exports = Object.entries ? Object.entries : function (obj) {
- let ownProps = Object.keys(obj),
- i = ownProps.length,
- resArray = new Array(i); // preallocate the Array
- while (i--) {
- resArray[i] = [ownProps[i], obj[ownProps[i]]];
- }
-
- return resArray;
-};
diff --git a/server/node_modules/cloudinary/lib/utils/generateBreakpoints.js b/server/node_modules/cloudinary/lib/utils/generateBreakpoints.js
deleted file mode 100644
index f81453e..0000000
--- a/server/node_modules/cloudinary/lib/utils/generateBreakpoints.js
+++ /dev/null
@@ -1,41 +0,0 @@
-
-/**
- * Helper function. Gets or populates srcset breakpoints using provided parameters
- * Either the breakpoints or min_width, max_width, max_images must be provided.
- *
- * @module utils
- * @private
- * @param {srcset} srcset Options with either `breakpoints` or `min_width`, `max_width`, and `max_images`
- *
- * @return {number[]} Array of breakpoints
- *
- */
-function generateBreakpoints(srcset) {
- let breakpoints = srcset.breakpoints || [];
- if (breakpoints.length) {
- return breakpoints;
- }
- let [min_width, max_width, max_images] = [srcset.min_width, srcset.max_width, srcset.max_images].map(Number);
- if ([min_width, max_width, max_images].some(Number.isNaN)) {
- throw 'Either (min_width, max_width, max_images) '
- + 'or breakpoints must be provided to the image srcset attribute';
- }
-
- if (min_width > max_width) {
- throw 'min_width must be less than max_width';
- }
-
- if (max_images <= 0) {
- throw 'max_images must be a positive integer';
- } else if (max_images === 1) {
- min_width = max_width;
- }
-
- let stepSize = Math.ceil((max_width - min_width) / Math.max(max_images - 1, 1));
- for (let current = min_width; current < max_width; current += stepSize) {
- breakpoints.push(current);
- }
- breakpoints.push(max_width);
- return breakpoints;
-}
-module.exports = generateBreakpoints;
diff --git a/server/node_modules/cloudinary/lib/utils/index.js b/server/node_modules/cloudinary/lib/utils/index.js
deleted file mode 100644
index 5b1fa73..0000000
--- a/server/node_modules/cloudinary/lib/utils/index.js
+++ /dev/null
@@ -1,1751 +0,0 @@
-/**
- * Utilities
- * @module utils
- * @borrows module:auth_token as generate_auth_token
- */
-
-const crypto = require("crypto");
-const querystring = require("querystring");
-const urlParse = require("url").parse;
-
-// Functions used internally
-const compact = require("lodash/compact");
-const first = require("lodash/first");
-const isFunction = require("lodash/isFunction");
-const isPlainObject = require("lodash/isPlainObject");
-const last = require("lodash/last");
-const map = require("lodash/map");
-const take = require("lodash/take");
-const at = require("lodash/at");
-
-// Exposed by the module
-const clone = require("lodash/clone");
-const extend = require("lodash/extend");
-const filter = require("lodash/filter");
-const includes = require("lodash/includes");
-const isArray = require("lodash/isArray");
-const isEmpty = require("lodash/isEmpty");
-const isNumber = require("lodash/isNumber");
-const isObject = require("lodash/isObject");
-const isString = require("lodash/isString");
-const isUndefined = require("lodash/isUndefined");
-
-const smart_escape = require("./encoding/smart_escape");
-const consumeOption = require('./parsing/consumeOption');
-const toArray = require('./parsing/toArray');
-let {base64EncodeURL} = require('./encoding/base64EncodeURL');
-const encodeDoubleArray = require('./encoding/encodeDoubleArray');
-
-const config = require("../config");
-const generate_token = require("../auth_token");
-const crc32 = require('./crc32');
-const ensurePresenceOf = require('./ensurePresenceOf');
-const ensureOption = require('./ensureOption').defaults(config());
-const entries = require('./entries');
-const isRemoteUrl = require('./isRemoteUrl');
-
-const getSDKVersions = require('./analytics/getSDKVersions');
-const {
- getAnalyticsOptions,
- getSDKAnalyticsSignature
-} = require('./analytics');
-
-exports = module.exports;
-const utils = module.exports;
-
-try {
- // eslint-disable-next-line global-require
- utils.VERSION = require('../../package.json').version;
-} catch (error) {
- utils.VERSION = '';
-}
-
-function generate_auth_token(options) {
- let token_options = Object.assign({}, config().auth_token, options);
- return generate_token(token_options);
-}
-
-exports.CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net";
-exports.OLD_AKAMAI_SHARED_CDN = "cloudinary-a.akamaihd.net";
-exports.AKAMAI_SHARED_CDN = "res.cloudinary.com";
-exports.SHARED_CDN = exports.AKAMAI_SHARED_CDN;
-exports.USER_AGENT = `CloudinaryNodeJS/${exports.VERSION} (Node ${process.versions.node})`;
-
-// Add platform information to the USER_AGENT header
-// This is intended for platform information and not individual applications!
-exports.userPlatform = "";
-
-function getUserAgent() {
- return isEmpty(utils.userPlatform) ? `${utils.USER_AGENT}` : `${utils.userPlatform} ${utils.USER_AGENT}`;
-}
-
-const {
- DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION,
- DEFAULT_POSTER_OPTIONS,
- DEFAULT_VIDEO_SOURCE_TYPES,
- CONDITIONAL_OPERATORS,
- PREDEFINED_VARS,
- LAYER_KEYWORD_PARAMS,
- TRANSFORMATION_PARAMS,
- SIMPLE_PARAMS,
- UPLOAD_PREFIX,
- SUPPORTED_SIGNATURE_ALGORITHMS,
- DEFAULT_SIGNATURE_ALGORITHM
-} = require('./consts');
-
-function textStyle(layer) {
- let keywords = [];
- let style = "";
-
- if (!isEmpty(layer.text_style)) {
- return layer.text_style;
- }
- Object.keys(LAYER_KEYWORD_PARAMS).forEach((attr) => {
- let default_value = LAYER_KEYWORD_PARAMS[attr];
- let attr_value = layer[attr] || default_value;
- if (attr_value !== default_value) {
- keywords.push(attr_value);
- }
- });
-
- Object.keys(layer).forEach((attr) => {
- if (attr === "letter_spacing" || attr === "line_spacing") {
- keywords.push(`${attr}_${layer[attr]}`);
- }
- if (attr === "font_hinting") {
- keywords.push(`${attr.split("_").pop()}_${layer[attr]}`);
- }
- if (attr === "font_antialiasing") {
- keywords.push(`antialias_${layer[attr]}`);
- }
- });
-
- if (layer.hasOwnProperty("font_size" || "font_family") || !isEmpty(keywords)) {
- if (!layer.font_size) throw new Error('Must supply font_size for text in overlay/underlay');
- if (!layer.font_family) throw new Error('Must supply font_family for text in overlay/underlay');
- keywords.unshift(layer.font_size);
- keywords.unshift(layer.font_family);
- style = compact(keywords).join("_");
- }
- return style;
-}
-
-/**
- * Normalize an expression string, replace "nice names" with their coded values and spaces with "_"
- * e.g. `width > 0` => `w_lt_0`
- *
- * @param {String} expression An expression to be normalized
- * @return {Object|String} A normalized String of the input value if possible otherwise the value itself
- */
-function normalize_expression(expression) {
- if (!isString(expression) || expression.length === 0 || expression.match(/^!.+!$/)) {
- return expression;
- }
-
- const operators = "\\|\\||>=|<=|&&|!=|>|=|<|/|-|\\^|\\+|\\*";
- const operatorsPattern = "((" + operators + ")(?=[ _]))";
- const operatorsReplaceRE = new RegExp(operatorsPattern, "g");
- expression = expression.replace(operatorsReplaceRE, match => CONDITIONAL_OPERATORS[match]);
-
- // Duplicate PREDEFINED_VARS to also include :{var_name} as well as {var_name}
- // Example:
- // -- PREDEFINED_VARS = ['foo']
- // -- predefinedVarsPattern = ':foo|foo'
- // It is done like this because node 6 does not support regex lookbehind
- const predefinedVarsPattern = "(" + Object.keys(PREDEFINED_VARS).map(v => `:${v}|${v}`).join("|") + ")";
- const userVariablePattern = '(\\$_*[^_ ]+)';
- const variablesReplaceRE = new RegExp(`${userVariablePattern}|${predefinedVarsPattern}`, "g");
- expression = expression.replace(variablesReplaceRE, (match) => (PREDEFINED_VARS[match] || match));
-
- return expression.replace(/[ _]+/g, '_');
-}
-
-/**
- * Parse custom_function options
- * @private
- * @param {object|*} customFunction a custom function object containing function_type and source values
- * @return {string|*} custom_function transformation string
- */
-function process_custom_function(customFunction) {
- if (!isObject(customFunction)) {
- return customFunction;
- }
- if (customFunction.function_type === "remote") {
- const encodedSource = base64EncodeURL(customFunction.source);
-
- return [customFunction.function_type, encodedSource].join(":");
- }
- return [customFunction.function_type, customFunction.source].join(":");
-}
-
-/**
- * Parse custom_pre_function options
- * @private
- * @param {object|*} customPreFunction a custom function object containing function_type and source values
- * @return {string|*} custom_pre_function transformation string
- */
-function process_custom_pre_function(customPreFunction) {
- let result = process_custom_function(customPreFunction);
- return utils.isString(result) ? `pre:${result}` : null;
-}
-
-/**
- * Parse "if" parameter
- * Translates the condition if provided.
- * @private
- * @return {string} "if_" + ifValue
- */
-function process_if(ifValue) {
- return ifValue ? "if_" + normalize_expression(ifValue) : ifValue;
-}
-
-/**
- * Parse layer options
- * @private
- * @param {object|*} layer The layer to parse.
- * @return {string} layer transformation string
- */
-function process_layer(layer) {
- if (isString(layer)) {
- let resourceType = null;
- let layerUrl = '';
-
- let fetchLayerBegin = 'fetch:';
- if (layer.startsWith(fetchLayerBegin)) {
- layerUrl = layer.substring(fetchLayerBegin.length);
- } else if (layer.indexOf(':fetch:', 0) !== -1) {
- const parts = layer.split(':', 3);
- resourceType = parts[0];
- layerUrl = parts[2];
- } else {
- return layer;
- }
-
- layer = {
- url: layerUrl,
- type: 'fetch'
- };
-
- if (resourceType) {
- layer.resource_type = resourceType;
- }
- }
-
- if (typeof layer !== 'object') {
- return layer;
- }
-
- let {
- resource_type,
- text,
- type,
- public_id,
- format,
- url: fetchUrl
- } = layer;
- const components = [];
-
- if (!isEmpty(text) && isEmpty(resource_type)) {
- resource_type = 'text';
- }
-
- if (!isEmpty(fetchUrl) && isEmpty(type)) {
- type = 'fetch';
- }
-
- if (!isEmpty(public_id) && !isEmpty(format)) {
- public_id = `${public_id}.${format}`;
- }
-
- if (isEmpty(public_id) && resource_type !== 'text' && type !== 'fetch') {
- throw new Error('Must supply public_id for non-text overlay');
- }
-
- if (!isEmpty(resource_type) && resource_type !== 'image') {
- components.push(resource_type);
- }
-
- if (!isEmpty(type) && type !== 'upload') {
- components.push(type);
- }
-
- if (resource_type === 'text' || resource_type === 'subtitles') {
- if (isEmpty(public_id) && isEmpty(text)) {
- throw new Error('Must supply either text or public_in in overlay');
- }
-
- const textOptions = textStyle(layer);
-
- if (!isEmpty(textOptions)) {
- components.push(textOptions);
- }
-
- if (!isEmpty(public_id)) {
- public_id = public_id.replace('/', ':');
- components.push(public_id);
- }
-
- if (!isEmpty(text)) {
- const variablesRegex = new RegExp(/(\$\([a-zA-Z]\w+\))/g);
- const textDividedByVariables = text.split(variablesRegex).filter(x => x);
- const encodedParts = textDividedByVariables.map(subText => {
- const matches = variablesRegex[Symbol.match](subText);
- const isVariable = matches ? matches.length > 0 : false;
- if (isVariable) {
- return subText;
- }
- return encodeCurlyBraces(encodeURIComponent(smart_escape(subText, new RegExp(/([,\/])/g))));
- });
- components.push(encodedParts.join(''));
- }
- } else if (type === 'fetch') {
- const encodedUrl = base64EncodeURL(fetchUrl);
- components.push(encodedUrl);
- } else {
- public_id = public_id.replace('/', ':');
- components.push(public_id);
- }
-
- return components.join(':');
-}
-
-function replaceAllSubstrings(string, search, replacement = '') {
- return string.split(search).join(replacement);
-}
-
-function encodeCurlyBraces(input) {
- return replaceAllSubstrings(replaceAllSubstrings(input, '(', '%28'), ')', '%29');
-}
-
-/**
- * Parse radius options
- * @private
- * @param {Array|string|number} radius The radius to parse
- * @return {string} radius transformation string
- */
-function process_radius(radius) {
- if (!radius) {
- return radius;
- }
- if (!isArray(radius)) {
- radius = [radius];
- }
- if (radius.length === 0 || radius.length > 4) {
- throw new Error("Radius array should contain between 1 and 4 values");
- }
- if (radius.findIndex(x => x === null) >= 0) {
- throw new Error("Corner: Cannot be null");
- }
- return radius.map(normalize_expression).join(':');
-}
-
-function build_multi_and_sprite_params(tagOrOptions, options) {
- let tag = null;
- if (typeof tagOrOptions === 'string') {
- tag = tagOrOptions;
- } else {
- if (isEmpty(options)) {
- options = tagOrOptions;
- } else {
- throw new Error('First argument must be a tag when additional options are passed');
- }
- tag = null;
- }
- if (!options && !tag) {
- throw new Error('Either tag or urls are required')
- }
- if (!options) {
- options = {}
- }
- const urls = options.urls
- const transformation = generate_transformation_string(extend({}, options, {
- fetch_format: options.format
- }));
- return {
- tag,
- transformation,
- urls,
- timestamp: utils.timestamp(),
- async: options.async,
- notification_url: options.notification_url
- };
-}
-
-function build_upload_params(options) {
- let params = {
- access_mode: options.access_mode,
- allowed_formats: options.allowed_formats && toArray(options.allowed_formats).join(","),
- asset_folder: options.asset_folder,
- async: utils.as_safe_bool(options.async),
- backup: utils.as_safe_bool(options.backup),
- callback: options.callback,
- cinemagraph_analysis: utils.as_safe_bool(options.cinemagraph_analysis),
- colors: utils.as_safe_bool(options.colors),
- display_name: options.display_name,
- discard_original_filename: utils.as_safe_bool(options.discard_original_filename),
- eager: utils.build_eager(options.eager),
- eager_async: utils.as_safe_bool(options.eager_async),
- eager_notification_url: options.eager_notification_url,
- eval: options.eval,
- exif: utils.as_safe_bool(options.exif),
- faces: utils.as_safe_bool(options.faces),
- folder: options.folder,
- format: options.format,
- filename_override: options.filename_override,
- image_metadata: utils.as_safe_bool(options.image_metadata),
- media_metadata: utils.as_safe_bool(options.media_metadata),
- invalidate: utils.as_safe_bool(options.invalidate),
- moderation: options.moderation,
- notification_url: options.notification_url,
- overwrite: utils.as_safe_bool(options.overwrite),
- phash: utils.as_safe_bool(options.phash),
- proxy: options.proxy,
- public_id: options.public_id,
- public_id_prefix: options.public_id_prefix,
- quality_analysis: utils.as_safe_bool(options.quality_analysis),
- responsive_breakpoints: utils.generate_responsive_breakpoints_string(options.responsive_breakpoints),
- return_delete_token: utils.as_safe_bool(options.return_delete_token),
- timestamp: options.timestamp || exports.timestamp(),
- transformation: decodeURIComponent(utils.generate_transformation_string(clone(options))),
- type: options.type,
- unique_filename: utils.as_safe_bool(options.unique_filename),
- upload_preset: options.upload_preset,
- use_filename: utils.as_safe_bool(options.use_filename),
- use_filename_as_display_name: utils.as_safe_bool(options.use_filename_as_display_name),
- quality_override: options.quality_override,
- accessibility_analysis: utils.as_safe_bool(options.accessibility_analysis),
- use_asset_folder_as_public_id_prefix: utils.as_safe_bool(options.use_asset_folder_as_public_id_prefix),
- visual_search: utils.as_safe_bool(options.visual_search),
- on_success: options.on_success,
- auto_transcription: options.auto_transcription,
- auto_chaptering: utils.as_safe_bool(options.auto_chaptering)
- };
-
- return utils.updateable_resource_params(options, params);
-}
-
-function encode_key_value(arg) {
- if (!isObject(arg)) {
- return arg;
- }
- return entries(arg).map(([k, v]) => `${k}=${v}`).join('|');
-}
-
-
-/**
- * @description Escape = and | with two backslashes \\
- * @param {string|number} value
- * @return {string}
- */
-function escapeMetadataValue(value) {
- return value.toString().replace(/([=|])/g, '\\$&');
-}
-
-
-/**
- *
- * @description Encode metadata fields based on incoming value.
- * If array, escape as color_id=[\"green\",\"red\"]
- * If string/number, escape as in_stock_id=50
- *
- * Joins resulting values with a pipe:
- * in_stock_id=50|color_id=[\"green\",\"red\"]
- *
- * = and | and escaped by default (this can't be turned off)
- *
- * @param metadataObj
- * @return {string}
- */
-function encode_context(metadataObj) {
- if (!isObject(metadataObj)) {
- return metadataObj;
- }
-
- return entries(metadataObj).map(([key, value]) => {
- // if string, simply parse the value and move on
- if (isString(value)) {
- return `${key}=${escapeMetadataValue(value)}`;
-
- // If array, parse each item individually
- } else if (isArray(value)) {
- let values = value.map((innerVal) => {
- return `\"${escapeMetadataValue(innerVal)}\"`
- }).join(',');
- return `${key}=[${values}]`
- // if number, convert to string
- } else if (Number.isInteger(value)) {
- return `${key}=${escapeMetadataValue(String(value))}`;
- // if unknown, return the value as string
- } else {
- return value.toString();
- }
- }).join('|');
-}
-
-function build_eager(transformations) {
- return toArray(transformations)
- .map((transformation) => {
- const transformationString = utils.generate_transformation_string(clone(transformation));
- const format = transformation.format;
- return format == null ? transformationString : `${transformationString}/${format}`;
- }).join('|');
-}
-
-/**
- * Build the custom headers for the request
- * @private
- * @param headers
- * @return {Array|object|string} An object of name and value,
- * an array of header strings, or a string of headers
- */
-function build_custom_headers(headers) {
- switch (true) {
- case headers == null:
- return void 0;
- case isArray(headers):
- return headers.join("\n");
- case isObject(headers):
- return entries(headers).map(([k, v]) => `${k}:${v}`).join("\n");
- default:
- return headers;
- }
-}
-
-function generate_transformation_string(options) {
- if (utils.isString(options)) {
- return options;
- }
- if (isArray(options)) {
- return options.map(t => utils.generate_transformation_string(clone(t))).filter(utils.present).join('/');
- }
-
- let responsive_width = consumeOption(options, "responsive_width", config().responsive_width);
- let width = options.width;
- let height = options.height;
- let size = consumeOption(options, "size");
- if (size) {
- [width, height] = size.split("x");
- [options.width, options.height] = [width, height];
- }
- let has_layer = options.overlay || options.underlay;
- let crop = consumeOption(options, "crop");
- let angle = toArray(consumeOption(options, "angle")).join(".");
- let no_html_sizes = has_layer || utils.present(angle) || crop === "fit" || crop === "limit" || responsive_width;
- if (width && (width.toString().indexOf("auto") === 0 || no_html_sizes || parseFloat(width) < 1)) {
- delete options.width;
- }
- if (height && (no_html_sizes || parseFloat(height) < 1)) {
- delete options.height;
- }
- let background = consumeOption(options, "background");
- background = background && background.replace(/^#/, "rgb:");
- let color = consumeOption(options, "color");
- color = color && color.replace(/^#/, "rgb:");
- let base_transformations = toArray(consumeOption(options, "transformation", []));
- let named_transformation = [];
- if (base_transformations.some(isObject)) {
- base_transformations = base_transformations.map(tr => utils.generate_transformation_string(isObject(tr) ? clone(tr) : {transformation: tr}));
- } else {
- named_transformation = base_transformations.join(".");
- base_transformations = [];
- }
- let effect = consumeOption(options, "effect");
- if (isArray(effect)) {
- effect = effect.join(":");
- } else if (isObject(effect)) {
- effect = entries(effect).map(([key, value]) => `${key}:${value}`);
- }
- let border = consumeOption(options, "border");
- if (isObject(border)) {
- border = `${border.width != null ? border.width : 2}px_solid_${(border.color != null ? border.color : "black").replace(/^#/, 'rgb:')}`;
- } else if (/^\d+$/.exec(border)) { // fallback to html border attributes
- options.border = border;
- border = void 0;
- }
- let flags = toArray(consumeOption(options, "flags")).join(".");
- let dpr = consumeOption(options, "dpr", config().dpr);
- if (options.offset != null) {
- [options.start_offset, options.end_offset] = split_range(consumeOption(options, "offset"));
- }
- if (options.start_offset) {
- options.start_offset = normalize_expression(options.start_offset);
- }
- if (options.end_offset) {
- options.end_offset = normalize_expression(options.end_offset);
- }
- let overlay = process_layer(consumeOption(options, "overlay"));
- let radius = process_radius(consumeOption(options, "radius"));
- let underlay = process_layer(consumeOption(options, "underlay"));
- let ifValue = process_if(consumeOption(options, "if"));
- let custom_function = process_custom_function(consumeOption(options, "custom_function"));
- let custom_pre_function = process_custom_pre_function(consumeOption(options, "custom_pre_function"));
- let fps = consumeOption(options, 'fps');
- if (isArray(fps)) {
- fps = fps.join('-');
- }
- let params = {
- a: normalize_expression(angle),
- ar: normalize_expression(consumeOption(options, "aspect_ratio")),
- b: background,
- bo: border,
- c: crop,
- co: color,
- dpr: normalize_expression(dpr),
- e: normalize_expression(effect),
- fl: flags,
- fn: custom_function || custom_pre_function,
- fps: fps,
- h: normalize_expression(height),
- ki: normalize_expression(consumeOption(options, "keyframe_interval")),
- l: overlay,
- o: normalize_expression(consumeOption(options, "opacity")),
- q: normalize_expression(consumeOption(options, "quality")),
- r: radius,
- t: named_transformation,
- u: underlay,
- w: normalize_expression(width),
- x: normalize_expression(consumeOption(options, "x")),
- y: normalize_expression(consumeOption(options, "y")),
- z: normalize_expression(consumeOption(options, "zoom"))
- };
-
- SIMPLE_PARAMS.forEach(([name, short]) => {
- let value = consumeOption(options, name);
- if (value !== undefined) {
- params[short] = value;
- }
- });
- if (params.vc != null) {
- params.vc = process_video_params(params.vc);
- }
- ["so", "eo", "du"].forEach((short) => {
- if (params[short] !== undefined) {
- params[short] = norm_range_value(params[short]);
- }
- });
-
- let variablesParam = consumeOption(options, "variables", []);
- let variables = entries(options)
- .filter(([key, value]) => key.startsWith('$'))
- .map(([key, value]) => {
- delete options[key];
- return `${key}_${normalize_expression(value)}`;
- }).sort().concat(variablesParam.map(([name, value]) => `${name}_${normalize_expression(value)}`)).join(',');
-
- let transformations = entries(params)
- .filter(([key, value]) => utils.present(value))
- .map(([key, value]) => key + '_' + value)
- .sort()
- .join(',');
-
- let raw_transformation = consumeOption(options, 'raw_transformation');
- transformations = compact([ifValue, variables, transformations, raw_transformation]).join(",");
- base_transformations.push(transformations);
- transformations = base_transformations;
- if (responsive_width) {
- let responsive_width_transformation = config().responsive_width_transformation || DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION;
-
- transformations.push(utils.generate_transformation_string(clone(responsive_width_transformation)));
- }
- if (String(width).startsWith("auto") || responsive_width) {
- options.responsive = true;
- }
- if (dpr === "auto") {
- options.hidpi = true;
- }
- return filter(transformations, utils.present).join("/");
-}
-
-function updateable_resource_params(options, params = {}) {
- if (options.access_control != null) {
- params.access_control = utils.jsonArrayParam(options.access_control);
- }
- if (options.auto_tagging != null) {
- params.auto_tagging = options.auto_tagging;
- }
- if (options.background_removal != null) {
- params.background_removal = options.background_removal;
- }
- if (options.categorization != null) {
- params.categorization = options.categorization;
- }
- if (options.context != null) {
- params.context = utils.encode_context(options.context);
- }
- if (options.metadata != null) {
- params.metadata = utils.encode_context(options.metadata);
- }
- if (options.custom_coordinates != null) {
- params.custom_coordinates = encodeDoubleArray(options.custom_coordinates);
- }
- if (options.detection != null) {
- params.detection = options.detection;
- }
- if (options.face_coordinates != null) {
- params.face_coordinates = encodeDoubleArray(options.face_coordinates);
- }
- if (options.headers != null) {
- params.headers = utils.build_custom_headers(options.headers);
- }
- if (options.notification_url != null) {
- params.notification_url = options.notification_url;
- }
- if (options.ocr != null) {
- params.ocr = options.ocr;
- }
- if (options.raw_convert != null) {
- params.raw_convert = options.raw_convert;
- }
- if (options.similarity_search != null) {
- params.similarity_search = options.similarity_search;
- }
- if (options.tags != null) {
- params.tags = toArray(options.tags).join(",");
- }
- if (options.quality_override != null) {
- params.quality_override = options.quality_override;
- }
- if (options.asset_folder != null) {
- params.asset_folder = options.asset_folder;
- }
- if (options.display_name != null) {
- params.display_name = options.display_name;
- }
- if (options.unique_display_name != null) {
- params.unique_display_name = options.unique_display_name;
- }
- if (options.visual_search != null) {
- params.visual_search = options.visual_search;
- }
- if (options.regions != null) {
- params.regions = JSON.stringify(options.regions);
- }
- const autoTranscription = options.auto_transcription;
- if (autoTranscription != null) {
- if (typeof autoTranscription === 'boolean') {
- params.auto_transcription = utils.as_safe_bool(autoTranscription);
- } else {
- const isAutoTranscriptionObject = typeof autoTranscription === 'object' && !Array.isArray(autoTranscription);
- if (isAutoTranscriptionObject && Object.keys(autoTranscription).includes('translate')) {
- params.auto_transcription = JSON.stringify(autoTranscription);
- }
- }
- }
- return params;
-}
-
-/**
- * A list of keys used by the url() function.
- * @private
- */
-const URL_KEYS = ['api_secret', 'auth_token', 'cdn_subdomain', 'cloud_name', 'cname', 'format', 'long_url_signature', 'private_cdn', 'resource_type', 'secure', 'secure_cdn_subdomain', 'secure_distribution', 'shorten', 'sign_url', 'ssl_detected', 'type', 'url_suffix', 'use_root_path', 'version'];
-
-/**
- * Create a new object with only URL parameters
- * @param {object} options The source object
- * @return {Object} An object containing only URL parameters
- */
-
-function extractUrlParams(options) {
- return pickOnlyExistingValues(options, ...URL_KEYS);
-}
-
-/**
- * Create a new object with only transformation parameters
- * @param {object} options The source object
- * @return {Object} An object containing only transformation parameters
- */
-
-function extractTransformationParams(options) {
- return pickOnlyExistingValues(options, ...TRANSFORMATION_PARAMS);
-}
-
-/**
- * Handle the format parameter for fetch urls
- * @private
- * @param options url and transformation options. This argument may be changed by the function!
- */
-
-function patchFetchFormat(options = {}) {
- if (options.type === "fetch") {
- if (options.fetch_format == null) {
- options.fetch_format = consumeOption(options, "format");
- }
- }
-}
-
-function build_distribution_domain(source, options) {
- const cloud_name = consumeOption(options, 'cloud_name', config().cloud_name);
- if (!cloud_name) {
- throw new Error('Must supply cloud_name in tag or in configuration');
- }
-
- let secure = consumeOption(options, 'secure', true);
- const ssl_detected = consumeOption(options, 'ssl_detected', config().ssl_detected);
- if (secure === null) {
- secure = ssl_detected || config().secure;
- }
-
- const private_cdn = consumeOption(options, 'private_cdn', config().private_cdn);
- const cname = consumeOption(options, 'cname', config().cname);
- const secure_distribution = consumeOption(options, 'secure_distribution', config().secure_distribution);
- const cdn_subdomain = consumeOption(options, 'cdn_subdomain', config().cdn_subdomain);
- const secure_cdn_subdomain = consumeOption(options, 'secure_cdn_subdomain', config().secure_cdn_subdomain);
-
- return unsigned_url_prefix(source, cloud_name, private_cdn, cdn_subdomain, secure_cdn_subdomain, cname, secure, secure_distribution);
-}
-
-function url(public_id, options = {}) {
- let signature, source_to_sign;
- utils.patchFetchFormat(options);
- let type = consumeOption(options, "type", null);
- let transformation = utils.generate_transformation_string(options);
-
- let resource_type = consumeOption(options, "resource_type", "image");
- let version = consumeOption(options, "version");
- let force_version = consumeOption(options, "force_version", config().force_version);
- if (force_version == null) {
- force_version = true;
- }
- let long_url_signature = !!consumeOption(options, "long_url_signature", config().long_url_signature);
- let format = consumeOption(options, "format");
- let shorten = consumeOption(options, "shorten", config().shorten);
- let sign_url = consumeOption(options, "sign_url", config().sign_url);
- let api_secret = consumeOption(options, "api_secret", config().api_secret);
- let url_suffix = consumeOption(options, "url_suffix");
- let use_root_path = consumeOption(options, "use_root_path", config().use_root_path);
- let signature_algorithm = consumeOption(options, "signature_algorithm", config().signature_algorithm || DEFAULT_SIGNATURE_ALGORITHM);
- if (long_url_signature) {
- signature_algorithm = 'sha256';
- }
- let auth_token = consumeOption(options, "auth_token");
- if (auth_token !== false) {
- auth_token = exports.merge(config().auth_token, auth_token);
- }
- let preloaded = /^(image|raw)\/([a-z0-9_]+)\/v(\d+)\/([^#]+)$/.exec(public_id);
- if (preloaded) {
- resource_type = preloaded[1];
- type = preloaded[2];
- version = preloaded[3];
- public_id = preloaded[4];
- }
- let original_source = public_id;
- if (public_id == null) {
- return original_source;
- }
- public_id = public_id.toString();
- if (type === null && public_id.match(/^https?:\//i)) {
- return original_source;
- }
- [resource_type, type] = finalize_resource_type(resource_type, type, url_suffix, use_root_path, shorten);
- [public_id, source_to_sign] = finalize_source(public_id, format, url_suffix);
-
- if (version == null && force_version && source_to_sign.indexOf("/") >= 0 && !source_to_sign.match(/^v[0-9]+/) && !source_to_sign.match(/^https?:\//)) {
- version = 1;
- }
- if (version != null) {
- version = `v${version}`;
- } else {
- version = null;
- }
-
- transformation = transformation.replace(/([^:])\/\//g, '$1/');
- if (sign_url && isEmpty(auth_token)) {
- let to_sign = [transformation, source_to_sign].filter(function (part) {
- return (part != null) && part !== '';
- }).join('/');
-
- const signatureConfig = {};
- if (long_url_signature) {
- signatureConfig.algorithm = 'sha256';
- signatureConfig.signatureLength = 32;
- } else {
- signatureConfig.algorithm = signature_algorithm;
- signatureConfig.signatureLength = 8;
- }
-
- const truncated = compute_hash(to_sign + api_secret, signatureConfig.algorithm, 'base64')
- .slice(0, signatureConfig.signatureLength)
- .replace(/\//g, '_')
- .replace(/\+/g, '-');
- signature = `s--${truncated}--`;
- }
-
- let prefix = build_distribution_domain(public_id, options);
- let resultUrl = [prefix, resource_type, type, signature, transformation, version, public_id].filter(function (part) {
- return (part != null) && part !== '';
- }).join('/').replace(/ /g, '%20');
- if (sign_url && !isEmpty(auth_token)) {
- auth_token.url = urlParse(resultUrl).path;
- let token = generate_token(auth_token);
- resultUrl += `?${token}`;
- }
-
- const urlAnalytics = ensureOption(options, 'urlAnalytics', ensureOption(options, 'analytics', true));
-
- if (urlAnalytics === true) {
- let {
- sdkCode: sdkCodeDefault,
- sdkSemver: sdkSemverDefault,
- techVersion: techVersionDefault,
- product: productDefault
- } = getSDKVersions();
- const sdkCode = ensureOption(options, 'sdkCode', ensureOption(options, 'sdk_code', sdkCodeDefault));
- const sdkSemver = ensureOption(options, 'sdkSemver', ensureOption(options, 'sdk_semver', sdkSemverDefault));
- const techVersion = ensureOption(options, 'techVersion', ensureOption(options, 'tech_version', techVersionDefault));
- const product = ensureOption(options, 'product', productDefault);
-
- let sdkVersions = {
- sdkCode: sdkCode,
- sdkSemver: sdkSemver,
- techVersion: techVersion,
- product: product,
- urlAnalytics
- };
-
- let analyticsOptions = getAnalyticsOptions(Object.assign({}, options, sdkVersions));
-
- let sdkAnalyticsSignature = getSDKAnalyticsSignature(analyticsOptions);
-
- // url might already have a '?' query param
- let appender = '?';
- if (resultUrl.indexOf('?') >= 0) {
- appender = '&';
- }
- resultUrl = `${resultUrl}${appender}_a=${sdkAnalyticsSignature}`;
- }
-
- return resultUrl;
-}
-
-function video_url(public_id, options) {
- options = extend({
- resource_type: 'video'
- }, options);
- return utils.url(public_id, options);
-}
-
-function finalize_source(source, format, url_suffix) {
- let source_to_sign;
- source = source.replace(/([^:])\/\//g, '$1/');
- if (source.match(/^https?:\//i)) {
- source = smart_escape(source);
- source_to_sign = source;
- } else {
- source = encodeURIComponent(decodeURIComponent(source)).replace(/%3A/g, ":").replace(/%2F/g, "/");
- source_to_sign = source;
- if (url_suffix) {
- if (url_suffix.match(/[\.\/]/)) {
- throw new Error('url_suffix should not include . or /');
- }
- source = source + '/' + url_suffix;
- }
- if (format != null) {
- source = source + '.' + format;
- source_to_sign = source_to_sign + '.' + format;
- }
- }
- return [source, source_to_sign];
-}
-
-function video_thumbnail_url(public_id, options) {
- options = extend({}, DEFAULT_POSTER_OPTIONS, options);
- return utils.url(public_id, options);
-}
-
-function finalize_resource_type(resource_type, type, url_suffix, use_root_path, shorten) {
- if (type == null) {
- type = 'upload';
- }
- if (url_suffix != null) {
- if (resource_type === 'image' && type === 'upload') {
- resource_type = "images";
- type = null;
- } else if (resource_type === 'image' && type === 'private') {
- resource_type = 'private_images';
- type = null;
- } else if (resource_type === 'image' && type === 'authenticated') {
- resource_type = 'authenticated_images';
- type = null;
- } else if (resource_type === 'raw' && type === 'upload') {
- resource_type = 'files';
- type = null;
- } else if (resource_type === 'video' && type === 'upload') {
- resource_type = 'videos';
- type = null;
- } else {
- throw new Error("URL Suffix only supported for image/upload, image/private, image/authenticated, video/upload and raw/upload");
- }
- }
- if (use_root_path) {
- if ((resource_type === 'image' && type === 'upload') || (resource_type === 'images' && (type == null))) {
- resource_type = null;
- type = null;
- } else {
- throw new Error("Root path only supported for image/upload");
- }
- }
- if (shorten && resource_type === 'image' && type === 'upload') {
- resource_type = 'iu';
- type = null;
- }
- return [resource_type, type];
-}
-
-// cdn_subdomain and secure_cdn_subdomain
-// 1) Customers in shared distribution (e.g. res.cloudinary.com)
-// if cdn_domain is true uses res-[1-5].cloudinary.com for both http and https.
-// Setting secure_cdn_subdomain to false disables this for https.
-// 2) Customers with private cdn
-// if cdn_domain is true uses cloudname-res-[1-5].cloudinary.com for http
-// if secure_cdn_domain is true uses cloudname-res-[1-5].cloudinary.com for https
-// (please contact support if you require this)
-// 3) Customers with cname
-// if cdn_domain is true uses a[1-5].cname for http.
-// For https, uses the same naming scheme as 1 for shared distribution and as 2 for private distribution.
-
-function unsigned_url_prefix(source, cloud_name, private_cdn, cdn_subdomain, secure_cdn_subdomain, cname, secure, secure_distribution) {
- let prefix;
- if (cloud_name.indexOf("/") === 0) {
- return '/res' + cloud_name;
- }
- let shared_domain = !private_cdn;
- if (secure) {
- if ((secure_distribution == null) || secure_distribution === exports.OLD_AKAMAI_SHARED_CDN) {
- secure_distribution = private_cdn ? cloud_name + "-res.cloudinary.com" : exports.SHARED_CDN;
- }
- if (shared_domain == null) {
- shared_domain = secure_distribution === exports.SHARED_CDN;
- }
- if ((secure_cdn_subdomain == null) && shared_domain) {
- secure_cdn_subdomain = cdn_subdomain;
- }
- if (secure_cdn_subdomain) {
- secure_distribution = secure_distribution.replace('res.cloudinary.com', 'res-' + ((crc32(source) % 5) + 1 + '.cloudinary.com'));
- }
- prefix = 'https://' + secure_distribution;
- } else if (cname) {
- let subdomain = cdn_subdomain ? 'a' + ((crc32(source) % 5) + 1) + '.' : '';
- prefix = 'http://' + subdomain + cname;
- } else {
- let cdn_part = private_cdn ? cloud_name + '-' : '';
- let subdomain_part = cdn_subdomain ? '-' + ((crc32(source) % 5) + 1) : '';
- let host = [cdn_part, 'res', subdomain_part, '.cloudinary.com'].join('');
- prefix = 'http://' + host;
- }
- if (shared_domain) {
- prefix += '/' + cloud_name;
- }
- return prefix;
-}
-
-function base_api_url_v1_1() {
- return base_api_url('v1_1');
-}
-
-function base_api_url_v2() {
- return base_api_url('v2');
-}
-
-function base_api_url(api_version) {
- if (!api_version || api_version.length === 0) {
- throw new Error('api_version needs to be a non-empty string');
- }
-
- return (path = [], options = []) => {
- let cloudinary = ensureOption(options, "upload_prefix", UPLOAD_PREFIX);
- let cloud_name = ensureOption(options, "cloud_name");
- let encode_path = unencoded_path => encodeURIComponent(unencoded_path).replace("'", '%27');
- let encoded_path = Array.isArray(path) ? path.map(encode_path) : encode_path(path);
- return [cloudinary, api_version, cloud_name].concat(encoded_path).join("/");
- };
-}
-
-function api_url(action = 'upload', options = {}) {
- let resource_type = options.resource_type || "image";
- return base_api_url_v1_1()([resource_type, action], options);
-}
-
-function random_public_id() {
- return crypto.randomBytes(12).toString('base64').replace(/[^a-z0-9]/g, "");
-}
-
-function signed_preloaded_image(result) {
- return `${result.resource_type}/upload/v${result.version}/${filter([result.public_id, result.format], utils.present).join(".")}#${result.signature}`;
-}
-
-// Encodes a parameter for safe inclusion in URL query strings (only replaces & with %26)
-function encode_param(value) {
- return String(value).replace(/&/g, '%26');
-}
-
-// Generates a string to be signed for API requests
-function api_string_to_sign(params_to_sign, signature_version = 2) {
- let params = entries(params_to_sign)
- .map(([k, v]) => [String(k), Array.isArray(v) ? v.join(",") : v])
- .filter(([k, v]) => v !== null && v !== undefined && v !== "");
- params.sort((a, b) => a[0].localeCompare(b[0]));
- let paramStrings = params.map(([k, v]) => {
- const paramString = `${k}=${v}`;
- return signature_version >= 2 ? encode_param(paramString) : paramString;
- });
- return paramStrings.join("&");
-}
-
-/**
- * Signs API request parameters
- * @param {Object} params_to_sign Parameters to sign
- * @param {string} api_secret API secret
- * @param {string|undefined|null} signature_algorithm Hash algorithm to use ('sha1' or 'sha256')
- * @param {number|undefined|null} signature_version Version of signature algorithm to use:
- * - Version 1: Original behavior without parameter encoding
- * - Version 2+ (default): Includes parameter encoding to prevent parameter smuggling
- * @return {string} Hexadecimal signature
- * @private
- */
-function api_sign_request(params_to_sign, api_secret, signature_algorithm = null, signature_version = null) {
- if (signature_version == null) {
- signature_version = config().signature_version || 2;
- }
- const to_sign = api_string_to_sign(params_to_sign, signature_version);
- const algo = signature_algorithm || config().signature_algorithm || DEFAULT_SIGNATURE_ALGORITHM;
- return compute_hash(to_sign + api_secret, algo, 'hex');
-}
-
-/**
- * Computes hash from input string using specified algorithm.
- * @private
- * @param {string} input string which to compute hash from
- * @param {string} signature_algorithm algorithm to use for computing hash
- * @param {string} encoding type of encoding
- * @return {string} computed hash value
- */
-function compute_hash(input, signature_algorithm, encoding) {
- if (!SUPPORTED_SIGNATURE_ALGORITHMS.includes(signature_algorithm)) {
- throw new Error(`Signature algorithm ${signature_algorithm} is not supported. Supported algorithms: ${SUPPORTED_SIGNATURE_ALGORITHMS.join(', ')}`);
- }
- const hash = crypto.createHash(signature_algorithm).update(input).digest();
- return Buffer.from(hash).toString(encoding);
-}
-
-function clear_blank(hash) {
- let filtered_hash = {};
- entries(hash).filter(([k, v]) => utils.present(v)).forEach(([k, v]) => {
- filtered_hash[k] = v.filter ? v.filter(x => x) : v;
- });
- return filtered_hash;
-}
-
-function sort_object_by_key(object) {
- return Object.keys(object).sort().reduce((obj, key) => {
- obj[key] = object[key];
- return obj;
- }, {});
-}
-
-function merge(hash1, hash2) {
- return {...hash1, ...hash2};
-}
-
-function sign_request(params, options = {}) {
- let apiKey = ensureOption(options, 'api_key');
- let apiSecret = ensureOption(options, 'api_secret');
- let signature_algorithm = options.signature_algorithm;
- let signature_version = options.signature_version;
- params = exports.clear_blank(params);
- params.signature = exports.api_sign_request(params, apiSecret, signature_algorithm, signature_version);
- params.api_key = apiKey;
- return params;
-}
-
-function webhook_signature(data, timestamp, options = {}) {
- ensurePresenceOf({
- data,
- timestamp
- });
-
- let api_secret = ensureOption(options, 'api_secret');
- let signature_algorithm = ensureOption(options, 'signature_algorithm', DEFAULT_SIGNATURE_ALGORITHM);
- return compute_hash(data + timestamp + api_secret, signature_algorithm, 'hex');
-}
-
-/**
- * Verifies the authenticity of a notification signature
- *
- * @param {string} body JSON of the request's body
- * @param {number} timestamp Unix timestamp in seconds. Can be retrieved from the X-Cld-Timestamp header
- * @param {string} signature Actual signature. Can be retrieved from the X-Cld-Signature header
- * @param {number} [valid_for=7200] The desired time in seconds for considering the request valid
- *
- * @return {boolean}
- */
-function verifyNotificationSignature(body, timestamp, signature, valid_for = 7200) {
- // verify that signature is valid for the given timestamp
- if (timestamp < Math.round(Date.now() / 1000) - valid_for) {
- return false;
- }
- const payload_hash = utils.webhook_signature(body, timestamp, {
- api_secret: config().api_secret,
- signature_algorithm: config().signature_algorithm
- });
- return signature === payload_hash;
-}
-
-function process_request_params(params, options) {
- if ((options.unsigned != null) && options.unsigned) {
- params = exports.clear_blank(params);
- delete params.timestamp;
- } else if (options.oauth_token || config().oauth_token) {
- params = exports.clear_blank(params);
- } else if (options.signature) {
- params = exports.clear_blank(options);
- } else {
- params = exports.sign_request(params, options);
- }
-
- return params;
-}
-
-function private_download_url(public_id, format, options = {}) {
- let params = exports.sign_request({
- timestamp: options.timestamp || exports.timestamp(),
- public_id: public_id,
- format: format,
- type: options.type,
- attachment: options.attachment,
- expires_at: options.expires_at
- }, options);
- return exports.api_url("download", options) + "?" + querystring.stringify(params);
-}
-
-/**
- * Utility method that uses the deprecated ZIP download API.
- * @deprecated Replaced by {download_zip_url} that uses the more advanced and robust archive generation and download API
- */
-
-function zip_download_url(tag, options = {}) {
- let params = exports.sign_request({
- timestamp: options.timestamp || exports.timestamp(),
- tag: tag,
- transformation: utils.generate_transformation_string(options)
- }, options);
- return exports.api_url("download_tag.zip", options) + "?" + hashToQuery(params);
-}
-
-/**
- * The returned url should allow downloading the backedup asset based on the
- * version and asset id
- * asset and version id are returned with resource(, { versions: true })
- * @param asset_id
- * @param version_id
- * @param options
- * @returns {string }
- */
-function download_backedup_asset(asset_id, version_id, options = {}) {
- let params = exports.sign_request({
- timestamp: options.timestamp || exports.timestamp(),
- asset_id: asset_id,
- version_id: version_id
- }, options);
- return exports.base_api_url_v1()(['download_backup'], options) + "?" + hashToQuery(params);
-}
-
-/**
- * Utility method to create a signed URL for specified resources.
- * @param action
- * @param params
- * @param options
- */
-function api_download_url(action, params, options) {
- const download_params = {
- ...params,
- mode: "download"
- }
- let cloudinary_params = exports.sign_request(download_params, options);
- return exports.api_url(action, options) + "?" + hashToQuery(cloudinary_params);
-}
-
-/**
- * Returns a URL that when invokes creates an archive and returns it.
- * @param {object} options
- * @param {string} [options.resource_type="image"] The resource type of files to include in the archive.
- * Must be one of :image | :video | :raw
- * @param {string} [options.type="upload"] The specific file type of resources: :upload|:private|:authenticated
- * @param {string|Array} [options.tags] list of tags to include in the archive
- * @param {string|Array} [options.public_ids] list of public_ids to include in the archive
- * @param {string|Array} [options.prefixes] list of prefixes of public IDs (e.g., folders).
- * @param {string|Array} [options.fully_qualified_public_ids] list of fully qualified public_ids to include
- * in the archive.
- * @param {string|Array} [options.transformations] list of transformations.
- * The derived images of the given transformations are included in the archive. Using the string representation of
- * multiple chained transformations as we use for the 'eager' upload parameter.
- * @param {string} [options.mode="create"] return the generated archive file or to store it as a raw resource and
- * return a JSON with URLs for accessing the archive. Possible values: :download, :create
- * @param {string} [options.target_format="zip"]
- * @param {string} [options.target_public_id] public ID of the generated raw resource.
- * Relevant only for the create mode. If not specified, random public ID is generated.
- * @param {boolean} [options.flatten_folders=false] If true, flatten public IDs with folders to be in the root
- * of the archive. Add numeric counter to the file name in case of a name conflict.
- * @param {boolean} [options.flatten_transformations=false] If true, and multiple transformations are given,
- * flatten the folder structure of derived images and store the transformation details on the file name instead.
- * @param {boolean} [options.use_original_filename] Use the original file name of included images
- * (if available) instead of the public ID.
- * @param {boolean} [options.async=false] If true, return immediately and perform archive creation in the background.
- * Relevant only for the create mode.
- * @param {string} [options.notification_url] URL to send an HTTP post request (webhook) to when the
- * archive creation is completed.
- * @param {string|Array} [options.target_tags=] Allows assigning one or more tags to the generated archive file
- * (for later housekeeping via the admin API).
- * @param {string} [options.keep_derived=false] keep the derived images used for generating the archive
- * @return {String} archive url
- */
-function download_archive_url(options = {}) {
- const params = exports.archive_params(merge(options, {
- mode: "download"
- }))
- return api_download_url("generate_archive", params, options)
-}
-
-/**
- * Returns a URL that when invokes creates an zip archive and returns it.
- * @see download_archive_url
- */
-
-function download_zip_url(options = {}) {
- return exports.download_archive_url(merge(options, {
- target_format: "zip"
- }));
-}
-
-/**
- * Creates and returns a URL that when invoked creates an archive of a folder
- * @param {string} folder_path Full path (from the root) of the folder to download
- * @param {object} options Additional options
- * @returns {string} Url for downloading an archive of a folder
- */
-function download_folder(folder_path, options = {}) {
- options.resource_type = options.resource_type || "all";
- options.prefixes = folder_path;
- let cloudinary_params = exports.sign_request(exports.archive_params(merge(options, {
- mode: "download"
- })), options);
- return exports.api_url("generate_archive", options) + "?" + hashToQuery(cloudinary_params);
-}
-
-/**
- * Render the key/value pair as an HTML tag attribute
- * @private
- * @param {string} key
- * @param {string|boolean|number} [value]
- * @return {string} A string representing the HTML attribute
- */
-function join_pair(key, value) {
- if (!value) {
- return void 0;
- }
- return value === true ? key : key + "='" + value + "'";
-}
-
-/**
- * If the given value is a string, replaces single or double quotes with character entities
- * @private
- * @param {*} value The string to encode quotes in
- * @return {*} Encoded string or original value if not a string
- */
-function escapeQuotes(value) {
- return isString(value) ? value.replace(/\"/g, '"').replace(/\'/g, ''') : value;
-}
-
-/**
- *
- * @param attrs
- * @return {*}
- */
-exports.html_attrs = function html_attrs(attrs) {
- return filter(map(attrs, function (value, key) {
- return join_pair(key, escapeQuotes(value));
- })).sort().join(" ");
-};
-
-const CLOUDINARY_JS_CONFIG_PARAMS = ['api_key', 'cloud_name', 'private_cdn', 'secure_distribution', 'cdn_subdomain'];
-
-function cloudinary_js_config() {
- let params = pickOnlyExistingValues(config(), ...CLOUDINARY_JS_CONFIG_PARAMS);
- return ``;
-}
-
-function v1_result_adapter(callback) {
- if (callback == null) {
- return undefined;
- }
- return function (result) {
- if (result.error != null) {
- return callback(result.error);
- }
- return callback(void 0, result);
- };
-}
-
-function v1_adapter(name, num_pass_args, v1) {
- return function (...args) {
- let pass_args = take(args, num_pass_args);
- let options = args[num_pass_args];
- let callback = args[num_pass_args + 1];
- if ((callback == null) && isFunction(options)) {
- callback = options;
- options = {};
- }
- callback = v1_result_adapter(callback);
- args = pass_args.concat([callback, options]);
- return v1[name].apply(this, args);
- };
-}
-
-function v1_adapters(exports, v1, mapping) {
- return Object.keys(mapping).map((name) => {
- let num_pass_args = mapping[name];
- exports[name] = v1_adapter(name, num_pass_args, v1);
- return exports[name];
- });
-}
-
-function as_safe_bool(value) {
- if (value == null) {
- return void 0;
- }
- if (value === true || value === 'true' || value === '1') {
- value = 1;
- }
- if (value === false || value === 'false' || value === '0') {
- value = 0;
- }
- return value;
-}
-
-const NUMBER_PATTERN = "([0-9]*)\\.([0-9]+)|([0-9]+)";
-
-const OFFSET_ANY_PATTERN = `(${NUMBER_PATTERN})([%pP])?`;
-const RANGE_VALUE_RE = RegExp(`^${OFFSET_ANY_PATTERN}$`);
-const OFFSET_ANY_PATTERN_RE = RegExp(`(${OFFSET_ANY_PATTERN})\\.\\.(${OFFSET_ANY_PATTERN})`);
-
-// Split a range into the start and end values
-function split_range(range) { // :nodoc:
- switch (range.constructor) {
- case String:
- if (!OFFSET_ANY_PATTERN_RE.test(range)) {
- return range;
- }
- return range.split("..");
- case Array:
- return [first(range), last(range)];
- default:
- return [null, null];
- }
-}
-
-function norm_range_value(value) { // :nodoc:
- let offset = String(value).match(RANGE_VALUE_RE);
- if (offset) {
- let modifier = offset[5] ? 'p' : '';
- value = `${offset[1] || offset[4]}${modifier}`;
- }
- return value;
-}
-
-/**
- * A video codec parameter can be either a String or a Hash.
- * @param {Object} param vc_[ : : []]
- * or { codec: 'h264', profile: 'basic', level: '3.1' }
- * @return {String} : : []] if a Hash was provided
- * or the param if a String was provided.
- * Returns null if param is not a Hash or String
- */
-function process_video_params(param) {
- switch (param.constructor) {
- case Object: {
- let video = "";
- if ('codec' in param) {
- video = param.codec;
- if ('profile' in param) {
- video += ":" + param.profile;
- if ('level' in param) {
- video += ":" + param.level;
- }
- }
- }
- return video;
- }
- case String:
- return param;
- default:
- return null;
- }
-}
-
-/**
- * Returns a Hash of parameters used to create an archive
- * @private
- * @param {object} options
- * @return {object} Archive API parameters
- */
-
-function archive_params(options = {}) {
- return {
- allow_missing: exports.as_safe_bool(options.allow_missing),
- async: exports.as_safe_bool(options.async),
- expires_at: options.expires_at,
- flatten_folders: exports.as_safe_bool(options.flatten_folders),
- flatten_transformations: exports.as_safe_bool(options.flatten_transformations),
- keep_derived: exports.as_safe_bool(options.keep_derived),
- mode: options.mode,
- notification_url: options.notification_url,
- prefixes: options.prefixes && toArray(options.prefixes),
- fully_qualified_public_ids: options.fully_qualified_public_ids && toArray(options.fully_qualified_public_ids),
- public_ids: options.public_ids && toArray(options.public_ids),
- skip_transformation_name: exports.as_safe_bool(options.skip_transformation_name),
- tags: options.tags && toArray(options.tags),
- target_format: options.target_format,
- target_public_id: options.target_public_id,
- target_tags: options.target_tags && toArray(options.target_tags),
- timestamp: options.timestamp || exports.timestamp(),
- transformations: utils.build_eager(options.transformations),
- type: options.type,
- use_original_filename: exports.as_safe_bool(options.use_original_filename)
- };
-}
-
-exports.process_layer = process_layer;
-
-exports.create_source_tag = function create_source_tag(src, source_type, codecs = null) {
- let video_type = source_type === 'ogv' ? 'ogg' : source_type;
- let mime_type = `video/${video_type}`;
- if (!isEmpty(codecs)) {
- let codecs_str = isArray(codecs) ? codecs.join(', ') : codecs;
- mime_type += `; codecs=${codecs_str}`;
- }
- return ``;
-};
-
-function build_explicit_api_params(public_id, options = {}) {
- return [exports.build_upload_params(extend({}, {public_id}, options))];
-}
-
-function generate_responsive_breakpoints_string(breakpoints) {
- if (breakpoints == null) {
- return null;
- }
- breakpoints = clone(breakpoints);
- if (!isArray(breakpoints)) {
- breakpoints = [breakpoints];
- }
- for (let j = 0; j < breakpoints.length; j++) {
- let breakpoint_settings = breakpoints[j];
- if (breakpoint_settings != null) {
- if (breakpoint_settings.transformation) {
- breakpoint_settings.transformation = utils.generate_transformation_string(clone(breakpoint_settings.transformation));
- }
- }
- }
- return JSON.stringify(breakpoints);
-}
-
-function build_streaming_profiles_param(options = {}) {
- let params = pickOnlyExistingValues(options, "display_name", "representations");
- if (isArray(params.representations)) {
- params.representations = JSON.stringify(params.representations.map(r => ({
- transformation: utils.generate_transformation_string(r.transformation)
- })));
- }
- return params;
-}
-
-function hashToParameters(hash) {
- return entries(hash).reduce((parameters, [key, value]) => {
- if (isArray(value)) {
- key = key.endsWith('[]') ? key : key + '[]';
- const items = value.map(v => [key, v]);
- parameters = parameters.concat(items);
- } else {
- parameters.push([key, value]);
- }
- return parameters;
- }, []);
-}
-
-/**
- * Convert a hash of values to a URI query string.
- * Array values are spread as individual parameters.
- * @param {object} hash Key-value parameters
- * @return {string} A URI query string.
- */
-function hashToQuery(hash) {
- return hashToParameters(hash).map(([key, value]) => `${querystring.escape(key)}=${querystring.escape(value)}`).join('&');
-}
-
-/**
- * Verify that the parameter `value` is defined and it's string value is not zero.
- *
This function should not be confused with `isEmpty()`.
- * @private
- * @param {string|number} value The value to check.
- * @return {boolean} True if the value is defined and not empty.
- */
-
-function present(value) {
- return value != null && ("" + value).length > 0;
-}
-
-/**
- * Returns a new object with key values from source based on the keys.
- * `null` or `undefined` values are not copied.
- * @private
- * @param {object} source The object to pick values from.
- * @param {...string} keys One or more keys to copy from source.
- * @return {object} A new object with the required keys and values.
- */
-
-function pickOnlyExistingValues(source, ...keys) {
- let result = {};
- if (source) {
- keys.forEach((key) => {
- if (source[key] != null) {
- result[key] = source[key];
- }
- });
- }
- return result;
-}
-
-/**
- * Returns a JSON array as String.
- * Yields the array before it is converted to JSON format
- * @private
- * @param {object|String|Array