├── SECURITY.md
├── README.md
├── axamples
├── aws-companion
│ ├── .gitignore
│ ├── index.html
│ ├── README.md
│ ├── main.js
│ ├── package.json
│ └── server.cjs
├── php-xhr
│ ├── .gitignore
│ ├── index.html
│ ├── README.md
│ ├── main.js
│ ├── package.json
│ └── server.php
├── angular-example
│ ├── src
│ │ ├── assets
│ │ │ └── .gitkeep
│ │ ├── app
│ │ │ ├── app.component.css
│ │ │ ├── app.module.ts
│ │ │ └── app.component.ts
│ │ ├── main.ts
│ │ ├── styles.css
│ │ └── index.html
│ ├── .vscode
│ │ ├── extensions.json
│ │ ├── launch.json
│ │ └── tasks.json
│ ├── tsconfig.spec.json
│ ├── tsconfig.app.json
│ ├── .editorconfig
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── .eslintrc.json
│ ├── README.md
│ ├── package.json
│ └── angular.json
├── petProj-with-companion
│ ├── output
│ │ └── .empty
│ ├── .gitignore
│ ├── README.md
│ ├── package.json
│ ├── client
│ │ └── index.html
│ └── server
│ │ └── index.js
├── python-xhr
│ ├── .gitignore
│ ├── requirements.txt
│ ├── index.html
│ ├── main.js
│ ├── package.json
│ ├── README.md
│ └── server.py
├── transloadit
│ ├── .gitignore
│ ├── README.md
│ ├── package.json
│ ├── server.js
│ ├── index.html
│ └── main.js
├── vue3
│ ├── .gitignore
│ ├── public
│ │ └── favicon.ico
│ ├── src
│ │ ├── assets
│ │ │ └── logo.png
│ │ ├── main.js
│ │ └── App.vue
│ ├── README.md
│ ├── vite.config.js
│ ├── index.html
│ └── package.json
├── svelte-example
│ ├── .gitignore
│ ├── src
│ │ ├── main.ts
│ │ └── App.svelte
│ ├── postcss.config.js
│ ├── tsconfig.json
│ ├── README.md
│ ├── public
│ │ ├── index.html
│ │ └── global.css
│ ├── package.json
│ ├── server.mjs
│ └── rollup.config.js
├── react-native-expo
│ ├── .eslintrc.json
│ ├── babel.config.js
│ ├── .expo-shared
│ │ └── assets.json
│ ├── .gitignore
│ ├── index.js
│ ├── SelectFilesButton.js
│ ├── app.json
│ ├── readme.md
│ ├── tusFileReader.js
│ ├── PauseResumeButton.js
│ ├── metro.config.js
│ ├── ProgressBar.js
│ ├── package.json
│ ├── FileList.js
│ └── App.js
├── vue
│ ├── src
│ │ ├── main.js
│ │ └── App.vue
│ ├── vite.config.js
│ ├── .gitignore
│ ├── README.md
│ ├── index.html
│ └── package.json
├── react-example
│ ├── vite.config.js
│ ├── main.jsx
│ ├── index.html
│ ├── package.json
│ ├── README.md
│ └── App.jsx
├── redux
│ ├── package.json
│ ├── README.md
│ ├── index.html
│ └── main.js
├── transloadit-markdown-bin
│ ├── README.md
│ ├── package.json
│ ├── index.html
│ └── main.js
├── aws-nodejs
│ ├── package.json
│ ├── README.md
│ ├── public
│ │ ├── drag.html
│ │ └── index.html
│ └── index.js
└── xhr-bundle
│ ├── main.js
│ └── README.md
├── .dockerignore
├── .prettierignore
├── .eslintignore
├── .remarkignore
├── .browserslistrc
├── .prettierrc.js
├── .stylelintrc.json
├── .editorconfig
├── Dockerfile.test
├── .yarnrc.yml
├── .yarn
└── patches
│ ├── p-queue-npm-7.4.1-e0cf0a6f17.patch
│ ├── uuid-npm-8.3.2-eca0baba53.patch
│ ├── stylelint-config-rational-order-npm-0.1.2-d8336e84ed.patch
│ ├── start-server-and-test-npm-1.14.0-841aa34fdf.patch
│ ├── pre-commit-npm-1.2.2-f30af83877.patch
│ └── preact-npm-10.10.0-dd04de05e8.patch
├── .vscode
├── petProj.bak
└── petProj.code-workspace
├── .gitignore
├── LICENSE
├── Dockerfile
├── Makefile
├── .env.example
├── BUNDLE-README.md
└── .eslintrc.js
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # petProj
--------------------------------------------------------------------------------
/axamples/aws-companion/.gitignore:
--------------------------------------------------------------------------------
1 | tmp
2 |
--------------------------------------------------------------------------------
/axamples/php-xhr/.gitignore:
--------------------------------------------------------------------------------
1 | uploads/
2 |
--------------------------------------------------------------------------------
/axamples/angular-example/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/axamples/petProj-with-companion/output/.empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/axamples/python-xhr/.gitignore:
--------------------------------------------------------------------------------
1 | uploads/
2 |
--------------------------------------------------------------------------------
/axamples/angular-example/src/app/app.component.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/axamples/python-xhr/requirements.txt:
--------------------------------------------------------------------------------
1 | flask
2 | werkzeug
3 | flask-cors
4 |
--------------------------------------------------------------------------------
/axamples/transloadit/.gitignore:
--------------------------------------------------------------------------------
1 | petProj.min.css
2 | bundle.js
3 | bundle.js.map
4 |
--------------------------------------------------------------------------------
/axamples/petProj-with-companion/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | output/*
3 | !output/.empty
4 |
--------------------------------------------------------------------------------
/axamples/vue3/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | dist
4 | dist-ssr
5 | *.local
6 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | **/node_modules
2 | .git
3 | website
4 | assets
5 | private
6 | e2e
7 | .env
8 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | *.js
3 | *.jsx
4 | *.cjs
5 | *.mjs
6 | !private/js2ts/*
7 | *.md
8 | *.lock
9 |
--------------------------------------------------------------------------------
/axamples/vue3/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyberblobber/petProj/HEAD/axamples/vue3/public/favicon.ico
--------------------------------------------------------------------------------
/axamples/vue3/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyberblobber/petProj/HEAD/axamples/vue3/src/assets/logo.png
--------------------------------------------------------------------------------
/axamples/svelte-example/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules/
2 | /uploads/
3 | /public/build/
4 |
5 | .DS_Store
6 | package-lock.json
7 |
--------------------------------------------------------------------------------
/axamples/vue3/src/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import App from './App.vue'
3 |
4 | createApp(App).mount('#app')
5 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "react/react-in-jsx-scope": "off",
4 | "no-use-before-define": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | lib
3 | dist
4 | coverage
5 | test/lib/**
6 | test/endtoend/*/build
7 | examples/svelte-example/public/build/
8 | bundle-legacy.js
9 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = (api) => {
2 | api.cache(true)
3 | return {
4 | presets: ['babel-preset-expo'],
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/axamples/svelte-example/src/main.ts:
--------------------------------------------------------------------------------
1 | import App from './App.svelte'
2 |
3 | const app = new App({
4 | target: document.body,
5 | })
6 |
7 | export default app
8 |
--------------------------------------------------------------------------------
/axamples/svelte-example/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | // eslint-disable-next-line global-require
4 | require('postcss-import')(),
5 | ],
6 | }
7 |
--------------------------------------------------------------------------------
/.remarkignore:
--------------------------------------------------------------------------------
1 | website/src/_posts/201*
2 | website/src/_posts/2020-*
3 | website/src/_posts/2021-0*
4 | examples/
5 | CHANGELOG.md
6 | CHANGELOG.next.md
7 | BACKLOG.md
8 | node_modules/
9 |
--------------------------------------------------------------------------------
/axamples/angular-example/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
3 | "recommendations": ["angular.ng-template"]
4 | }
5 |
--------------------------------------------------------------------------------
/axamples/vue/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | Vue.config.productionTip = false
5 |
6 | new Vue({
7 | render: h => h(App),
8 | }).$mount('#app')
9 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/.expo-shared/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "12bb71dsgc6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52sdf4": true,
3 | "40b842e832070c58233c6aa9e08fa459302ee3f9da492c7gfsd93d2fbf4a56fd": true
4 | }
5 |
--------------------------------------------------------------------------------
/axamples/react-example/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .expo/
3 | dist/
4 | npm-debug.*
5 | *.jks
6 | *.p8
7 | *.p12
8 | *.key
9 | *.mobileprovision
10 | *.orig.*
11 | web-build/
12 |
13 | # macOS
14 | .DS_Store
15 |
--------------------------------------------------------------------------------
/axamples/vue/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import { createVuePlugin } from 'vite-plugin-vue2'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [createVuePlugin()],
7 | })
8 |
--------------------------------------------------------------------------------
/axamples/react-example/main.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React from 'react'
3 | import { createRoot } from 'react-dom/client';
4 | import App from './App.jsx'
5 |
6 | createRoot(document.querySelector('#app')).render(
7 |
8 | )
9 |
--------------------------------------------------------------------------------
/axamples/svelte-example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/svelte/tsconfig.json",
3 | "compilerOptions": {},
4 | "esModuleInterop": true,
5 | "include": ["src/**/*"],
6 | "exclude": ["node_modules/*", "__sapper__/*", "public/*"]
7 | }
8 |
--------------------------------------------------------------------------------
/.browserslistrc:
--------------------------------------------------------------------------------
1 | [production]
2 | last 2 Safari versions
3 | last 2 Chrome versions
4 | last 2 ChromeAndroid versions
5 | last 2 Firefox versions
6 | last 2 FirefoxAndroid versions
7 | last 2 Edge versions
8 | iOS >=13.4
9 |
10 | [legacy]
11 | IE 11
12 |
--------------------------------------------------------------------------------
/axamples/vue3/README.md:
--------------------------------------------------------------------------------
1 | # Vue 3 example
2 |
3 | To run the example, from the root directory of this repo, run the following commands:
4 |
5 | ```sh
6 | cp .env.example .env
7 | corepack yarn install
8 | corepack yarn build
9 | corepack yarn workspace @petProj-example/vue3 dev
10 | ```
11 |
--------------------------------------------------------------------------------
/axamples/angular-example/src/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
2 |
3 | import { AppModule } from './app/app.module'
4 |
5 | platformBrowserDynamic()
6 | .bootstrapModule(AppModule)
7 | .catch((err) => console.error(err)) // eslint-disable-line no-console
8 |
--------------------------------------------------------------------------------
/axamples/angular-example/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 | @import '@petProj/core/dist/style.css';
3 | @import '@petProj/dashboard/dist/style.css';
4 | @import '@petProj/drag-drop/dist/style.css';
5 | @import '@petProj/progress-bar/dist/style.css';
6 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | proseWrap: 'always',
3 | singleQuote: true,
4 | trailingComma: 'all',
5 | semi: false,
6 | overrides: [
7 | {
8 | files: 'packages/@petProj/angular/**',
9 | options: {
10 | semi: true,
11 | },
12 | },
13 | ],
14 | }
15 |
--------------------------------------------------------------------------------
/.stylelintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "stylelint-config-standard",
4 | "stylelint-config-standard-scss",
5 | "stylelint-config-rational-order"
6 | ],
7 | "rules": {
8 | "at-rule-no-unknown": null,
9 | "scss/at-rule-no-unknown": true
10 | },
11 | "defaultSeverity": "warning"
12 | }
13 |
--------------------------------------------------------------------------------
/axamples/angular-example/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/spec",
6 | "types": ["jasmine"]
7 | },
8 | "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/axamples/angular-example/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/app",
6 | "types": []
7 | },
8 | "files": ["src/main.ts"],
9 | "include": ["src/**/*.d.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; This file is for unifying the coding style for different editors and IDEs.
2 | ; More information at http://editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | charset = utf-8
8 | indent_style = space
9 | indent_size = 2
10 | end_of_line = lf
11 | insert_final_newline = true
12 | trim_trailing_whitespace = true
13 |
--------------------------------------------------------------------------------
/axamples/php-xhr/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | PHP + petProj Example
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/axamples/aws-companion/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Companion + AWS Example
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/axamples/vue3/vite.config.js:
--------------------------------------------------------------------------------
1 | import { fileURLToPath } from 'node:url'
2 | import { defineConfig } from 'vite'
3 | import vue from '@vitejs/plugin-vue'
4 |
5 | const ROOT = new URL('../../', import.meta.url)
6 |
7 | // https://vitejs.dev/config/
8 | export default defineConfig({
9 | envDir: fileURLToPath(ROOT),
10 | plugins: [vue()],
11 | })
12 |
--------------------------------------------------------------------------------
/axamples/angular-example/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AngularExample
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/index.js:
--------------------------------------------------------------------------------
1 | import { registerRootComponent } from 'expo'
2 |
3 | import App from './App'
4 |
5 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App);
6 | // It also ensures that whether you load the app in Expo Go or in a native build,
7 | // the environment is set up appropriately
8 | registerRootComponent(App)
9 |
--------------------------------------------------------------------------------
/Dockerfile.test:
--------------------------------------------------------------------------------
1 | FROM node:18.17.1-alpine
2 |
3 | COPY package.json /app/package.json
4 |
5 | WORKDIR /app
6 |
7 | RUN apk --update add --virtual native-dep \
8 | make gcc g++ python3 libgcc libstdc++ git && \
9 | corepack yarn install && \
10 | apk del native-dep
11 | RUN apk add bash
12 |
13 | COPY . /app
14 | RUN npm install -g nodemon
15 | CMD ["npm","test"]
16 |
--------------------------------------------------------------------------------
/axamples/vue/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 | /public
5 |
6 |
7 | # local env files
8 | .env.local
9 | .env.*.local
10 |
11 | # Log files
12 | npm-debug.log*
13 | yarn-debug.log*
14 | yarn-error.log*
15 | pnpm-debug.log*
16 |
17 | # Editor directories and files
18 | .idea
19 | .vscode
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/axamples/angular-example/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.ts]
12 | quote_type = single
13 |
14 | [*.md]
15 | max_line_length = off
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/axamples/vue/README.md:
--------------------------------------------------------------------------------
1 | # Vue 2 example
2 |
3 | You’re browsing the documentation for Vue v2.x and earlier. Check out
4 | [Vue 3 example](../vue3/) for new projects.
5 |
6 | To run the example, from the root directory of this repo, run the following commands:
7 |
8 | ```sh
9 | corepack yarn install
10 | corepack yarn build
11 | corepack yarn workspace @petProj-example/vue2 dev
12 | ```
13 |
--------------------------------------------------------------------------------
/axamples/python-xhr/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Python + petProj Example
7 |
8 |
9 | This app requires JavaScript.
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | changesetBaseRefs:
2 | - main
3 | - upstream/main
4 | - origin/main
5 |
6 | initScope: petProj
7 |
8 | enableGlobalCache: false
9 | nodeLinker: node-modules
10 |
11 | plugins:
12 | - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
13 | spec: '@yarnpkg/plugin-workspace-tools'
14 | - path: .yarn/plugins/@yarnpkg/plugin-version.cjs
15 | spec: '@yarnpkg/plugin-version'
16 |
--------------------------------------------------------------------------------
/axamples/svelte-example/README.md:
--------------------------------------------------------------------------------
1 | # petProj with Svelte
2 |
3 | ## Run it
4 |
5 | To run this example, make sure you've correctly installed the **repository root**:
6 |
7 | ```sh
8 | corepack yarn install
9 | corepack yarn build
10 | ```
11 |
12 | Then, again in the **repository root**, start this example by doing:
13 |
14 | ```sh
15 | corepack yarn workspace @petProj-example/svelte-app start
16 | ```
17 |
--------------------------------------------------------------------------------
/axamples/vue/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/axamples/vue3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/axamples/react-example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | petProj React Example
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.yarn/patches/p-queue-npm-7.4.1-e0cf0a6f17.patch:
--------------------------------------------------------------------------------
1 | diff --git a/package.json b/package.json
2 | index 8367745346fffd144a817ccf04912bb799e18b66..66dd17a4cd736089a332d72a70040701b0cd9c93 100644
3 | --- a/package.json
4 | +++ b/package.json
5 | @@ -6,6 +6,7 @@
6 | "repository": "sindresorhus/p-queue",
7 | "funding": "https://github.com/sponsors/sindresorhus",
8 | "type": "module",
9 | + "main": "./dist/index.js",
10 | "exports": "./dist/index.js",
11 | "engines": {
12 | "node": ">=12"
13 |
--------------------------------------------------------------------------------
/.yarn/patches/uuid-npm-8.3.2-eca0baba53.patch:
--------------------------------------------------------------------------------
1 | diff --git a/package.json b/package.json
2 | index f0ab3711ee4f490cbf961ebe6283ce2a28b6824b..644235a3ef52c974e946403a3fcdd137d01fad0c 100644
3 | --- a/package.json
4 | +++ b/package.json
5 | @@ -25,6 +25,7 @@
6 | "require": "./dist/index.js",
7 | "import": "./wrapper.mjs"
8 | },
9 | + "jest": "./dist/index.js",
10 | "default": "./dist/esm-browser/index.js"
11 | },
12 | "./package.json": "./package.json"
13 |
--------------------------------------------------------------------------------
/axamples/svelte-example/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Svelte app
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.yarn/patches/stylelint-config-rational-order-npm-0.1.2-d8336e84ed.patch:
--------------------------------------------------------------------------------
1 | diff --git a/package.json b/package.json
2 | index a2047a8b2895a64a4cbf7b493362ee1d72c43771..7478198712b460936f6b7f2557b116c52f4d71b5 100644
3 | --- a/package.json
4 | +++ b/package.json
5 | @@ -30,8 +30,8 @@
6 | "order"
7 | ],
8 | "dependencies": {
9 | - "stylelint": "^9.10.1",
10 | - "stylelint-order": "^2.2.1"
11 | + "stylelint": "^15.0.1",
12 | + "stylelint-order": "^6.0.3"
13 | },
14 | "devDependencies": {
15 | "eslint": "^5.16.0",
16 |
--------------------------------------------------------------------------------
/.yarn/patches/start-server-and-test-npm-1.14.0-841aa34fdf.patch:
--------------------------------------------------------------------------------
1 | diff --git a/src/utils.js b/src/utils.js
2 | index 1f636c6617a71a68318dc587a1c9e6081020f9aa..b28e840ed08f26a4eadd242a6f541fbaefea0eda 100644
3 | --- a/src/utils.js
4 | +++ b/src/utils.js
5 | @@ -112,7 +112,7 @@ const getArguments = cliArgs => {
6 | }
7 |
8 | function normalizeCommand (command) {
9 | - return UTILS.isPackageScriptName(command) ? `npm run ${command}` : command
10 | + return UTILS.isPackageScriptName(command) ? `corepack yarn ${command}` : command
11 | }
12 |
13 | /**
14 |
--------------------------------------------------------------------------------
/axamples/php-xhr/README.md:
--------------------------------------------------------------------------------
1 | # petProj + PHP Example
2 |
3 | This example uses PHP server and `@petProj/xhr-upload` to upload files to the local file system.
4 |
5 | ## Run it
6 |
7 | To run this example, make sure you've correctly installed the **repository root**:
8 |
9 | ```sh
10 | corepack yarn install
11 | corepack yarn build
12 | ```
13 |
14 | That will also install the dependencies for this example.
15 |
16 | Then, again in the **repository root**, start this example by doing:
17 |
18 | ```sh
19 | corepack yarn workspace @petProj-example/php-xhr start
20 | ```
21 |
--------------------------------------------------------------------------------
/axamples/redux/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/redux",
3 | "version": "0.0.0",
4 | "type": "module",
5 | "dependencies": {
6 | "@reduxjs/toolkit": "^1.9.3",
7 | "@petProj/core": "workspace:*",
8 | "@petProj/dashboard": "workspace:*",
9 | "@petProj/store-redux": "workspace:*",
10 | "@petProj/tus": "workspace:*",
11 | "redux": "^4.2.1",
12 | "redux-logger": "^3.0.6"
13 | },
14 | "devDependencies": {
15 | "vite": "^4.0.0"
16 | },
17 | "private": true,
18 | "scripts": {
19 | "start": "vite"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/axamples/transloadit-markdown-bin/README.md:
--------------------------------------------------------------------------------
1 | # petProj Markdown Editor
2 |
3 | This example uses petProj to handle images in a markdown editor.
4 |
5 | ## Run it
6 |
7 | To run this example, make sure you've correctly installed the **repository root**:
8 |
9 | ```sh
10 | corepack yarn install
11 | corepack yarn build
12 | ```
13 |
14 | That will also install the dependencies for this example.
15 |
16 | Then, again in the **repository root**, start this example by doing:
17 |
18 | ```sh
19 | corepack yarn workspace @petProj-example/transloadit-markdown-bin start
20 | ```
21 |
--------------------------------------------------------------------------------
/axamples/angular-example/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
3 | "version": "0.2.0",
4 | "configurations": [
5 | {
6 | "name": "ng serve",
7 | "type": "chrome",
8 | "request": "launch",
9 | "preLaunchTask": "npm: start",
10 | "url": "http://localhost:4200/"
11 | },
12 | {
13 | "name": "ng test",
14 | "type": "chrome",
15 | "request": "launch",
16 | "preLaunchTask": "npm: test",
17 | "url": "http://localhost:9876/debug.html"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/axamples/transloadit/README.md:
--------------------------------------------------------------------------------
1 | # Transloadit example
2 |
3 | This example shows how to make advantage of petProj API to upload files to
4 | [Transloadit](https://transloadit.com/).
5 |
6 | ## Run it
7 |
8 | To run this example, make sure you've correctly installed the **repository root**:
9 |
10 | ```sh
11 | corepack yarn install
12 | corepack yarn build
13 | ```
14 |
15 | That will also install the dependencies for this example.
16 |
17 | Then, again in the **repository root**, start this example by doing:
18 |
19 | ```sh
20 | corepack yarn workspace @petProj-example/transloadit start
21 | ```
22 |
--------------------------------------------------------------------------------
/axamples/petProj-with-companion/README.md:
--------------------------------------------------------------------------------
1 | # @petProj/companion example
2 |
3 | This is a simple, lean example that combines the usage of @petProj/companion and petProj client.
4 |
5 | ## Test it
6 |
7 | To run this example, make sure you've correctly installed the **repository root**:
8 |
9 | ```bash
10 | corepack yarn install
11 | corepack yarn build
12 | ```
13 |
14 | That will also install the dependencies for this example.
15 |
16 | Then, again in the **repository root**, start this example by doing:
17 |
18 | ```bash
19 | corepack yarn workspace @petProj-example/petProj-with-companion start
20 | ```
21 |
--------------------------------------------------------------------------------
/axamples/aws-nodejs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/aws-nodejs",
3 | "version": "1.0.0",
4 | "description": "petProj for AWS S3 with a custom Node.js backend for signing URLs",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "node --watch index.js",
8 | "start": "node index.js"
9 | },
10 | "private": true,
11 | "license": "MIT",
12 | "dependencies": {
13 | "@aws-sdk/client-s3": "^3.338.0",
14 | "@aws-sdk/client-sts": "^3.338.0",
15 | "@aws-sdk/s3-request-presigner": "^3.338.0",
16 | "body-parser": "^1.20.0",
17 | "dotenv": "^16.0.0",
18 | "express": "^4.18.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/axamples/php-xhr/main.js:
--------------------------------------------------------------------------------
1 | import petProj from '@petProj/core'
2 | import Webcam from '@petProj/webcam'
3 | import Dashboard from '@petProj/dashboard'
4 | import XHRUpload from '@petProj/xhr-upload'
5 |
6 | import '@petProj/core/dist/style.css'
7 | import '@petProj/dashboard/dist/style.css'
8 | import '@petProj/webcam/dist/style.css'
9 |
10 | const petProj = new petProj({
11 | debug: true,
12 | autoProceed: false,
13 | })
14 |
15 | petProj.use(Webcam)
16 | petProj.use(Dashboard, {
17 | inline: true,
18 | target: 'body',
19 | plugins: ['Webcam'],
20 | })
21 | petProj.use(XHRUpload, {
22 | endpoint: 'http://localhost:3020/upload.php',
23 | })
24 |
--------------------------------------------------------------------------------
/axamples/python-xhr/main.js:
--------------------------------------------------------------------------------
1 | import petProj from '@petProj/core'
2 | import Webcam from '@petProj/webcam'
3 | import Dashboard from '@petProj/dashboard'
4 | import XHRUpload from '@petProj/xhr-upload'
5 |
6 | import '@petProj/core/dist/style.css'
7 | import '@petProj/webcam/dist/style.css'
8 | import '@petProj/dashboard/dist/style.css'
9 |
10 | const petProj = new petProj({
11 | debug: true,
12 | autoProceed: false,
13 | })
14 |
15 | petProj.use(Webcam)
16 | petProj.use(Dashboard, {
17 | inline: true,
18 | target: 'body',
19 | plugins: ['Webcam'],
20 | })
21 | petProj.use(XHRUpload, {
22 | endpoint: 'http://localhost:3020/upload',
23 | })
24 |
--------------------------------------------------------------------------------
/axamples/php-xhr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/php-xhr",
3 | "version": "0.0.0",
4 | "type": "module",
5 | "dependencies": {
6 | "@petProj/core": "workspace:*",
7 | "@petProj/dashboard": "workspace:*",
8 | "@petProj/webcam": "workspace:*",
9 | "@petProj/xhr-upload": "workspace:*"
10 | },
11 | "devDependencies": {
12 | "npm-run-all": "^4.1.3",
13 | "vite": "^4.0.0"
14 | },
15 | "private": true,
16 | "scripts": {
17 | "start": "npm-run-all --parallel start:server start:client",
18 | "start:client": "vite",
19 | "start:server": "mkdir -p uploads && php -S 0.0.0.0:3020 server.php"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/SelectFilesButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Text, TouchableHighlight, StyleSheet } from 'react-native'
3 |
4 | export default function SelectFiles ({ showFilePicker }) {
5 | return (
6 |
10 | Select files
11 |
12 | )
13 | }
14 |
15 | const styles = StyleSheet.create({
16 | button: {
17 | backgroundColor: '#cc0077',
18 | padding: 15,
19 | },
20 | text: {
21 | color: '#fff',
22 | textAlign: 'center',
23 | fontSize: 17,
24 | },
25 | })
26 |
--------------------------------------------------------------------------------
/axamples/vue3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/vue3",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "vite",
7 | "build": "vite build",
8 | "preview": "vite preview --port 5050"
9 | },
10 | "dependencies": {
11 | "@petProj/core": "workspace:*",
12 | "@petProj/dashboard": "workspace:*",
13 | "@petProj/drag-drop": "workspace:*",
14 | "@petProj/progress-bar": "workspace:*",
15 | "@petProj/tus": "workspace:*",
16 | "@petProj/vue": "workspace:*",
17 | "vue": "^3.2.33"
18 | },
19 | "devDependencies": {
20 | "@vitejs/plugin-vue": "^3.0.0",
21 | "vite": "^4.0.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/axamples/xhr-bundle/main.js:
--------------------------------------------------------------------------------
1 | import petProj from '@petProj/core'
2 | import Dashboard from '@petProj/dashboard'
3 | import XHRUpload from '@petProj/xhr-upload'
4 |
5 | import '@petProj/core/dist/style.css'
6 | import '@petProj/dashboard/dist/style.css'
7 |
8 | const petProj = new petProj({
9 | debug: true,
10 | meta: { something: 'xyz' },
11 | })
12 |
13 | petProj.use(Dashboard, {
14 | target: '#app',
15 | inline: true,
16 | hideRetryButton: true,
17 | hideCancelButton: true,
18 | })
19 |
20 | petProj.use(XHRUpload, {
21 | bundle: true,
22 | endpoint: 'http://localhost:9967/upload',
23 | allowedMetaFields: ['something'],
24 | fieldName: 'files',
25 | })
26 |
--------------------------------------------------------------------------------
/axamples/transloadit-markdown-bin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/transloadit-markdown-bin",
3 | "version": "0.0.0",
4 | "type": "module",
5 | "dependencies": {
6 | "@petProj/core": "workspace:*",
7 | "@petProj/dashboard": "workspace:*",
8 | "@petProj/drop-target": "workspace:*",
9 | "@petProj/image-editor": "workspace:*",
10 | "@petProj/remote-sources": "workspace:*",
11 | "@petProj/transloadit": "workspace:*",
12 | "@petProj/webcam": "workspace:*",
13 | "marked": "^4.0.18"
14 | },
15 | "devDependencies": {
16 | "vite": "^4.0.0"
17 | },
18 | "private": true,
19 | "scripts": {
20 | "start": "vite"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/axamples/petProj-with-companion/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/petProj-with-companion",
3 | "version": "0.0.0",
4 | "dependencies": {
5 | "@petProj/companion": "workspace:*",
6 | "body-parser": "^1.18.2",
7 | "express": "^4.16.2",
8 | "express-session": "^1.15.6",
9 | "light-server": "^2.4.0",
10 | "upload-server": "^1.1.6"
11 | },
12 | "license": "ISC",
13 | "main": "index.js",
14 | "private": true,
15 | "scripts": {
16 | "client": "light-server -p 3000 -s client",
17 | "server": "node ./server/index.js",
18 | "start": "yarn run server & yarn run client",
19 | "test": "echo \"Error: no test specified\" && exit 1"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/axamples/vue/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/vue2",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "vite",
7 | "build": "vite build",
8 | "preview": "vite preview --port 5050"
9 | },
10 | "dependencies": {
11 | "@petProj/core": "workspace:*",
12 | "@petProj/dashboard": "workspace:*",
13 | "@petProj/drag-drop": "workspace:*",
14 | "@petProj/progress-bar": "workspace:*",
15 | "@petProj/transloadit": "workspace:*",
16 | "@petProj/vue": "workspace:*",
17 | "vue": "^2.6.14"
18 | },
19 | "devDependencies": {
20 | "vite": "^4.0.0",
21 | "vite-plugin-vue2": "^2.0.1",
22 | "vue-template-compiler": "^2.6.14"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/axamples/python-xhr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/python-xhr",
3 | "version": "0.0.0",
4 | "type": "module",
5 | "dependencies": {
6 | "@petProj/core": "workspace:*",
7 | "@petProj/dashboard": "workspace:*",
8 | "@petProj/webcam": "workspace:*",
9 | "@petProj/xhr-upload": "workspace:*"
10 | },
11 | "devDependencies": {
12 | "npm-run-all": "^4.1.3",
13 | "vite": "^4.0.0"
14 | },
15 | "private": true,
16 | "scripts": {
17 | "installPythonDeps": "python3 -m pip install -r requirements.txt",
18 | "start": "npm-run-all --parallel start:server start:client",
19 | "start:client": "vite",
20 | "start:server": "mkdir -p uploads && python3 server.py"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/.vscode/petProj.bak:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "path": "."
5 | }
6 | ],
7 | "settings": {
8 | "workbench.colorCustomizations": {
9 | "titleBar.activeForeground": "#ffffff",
10 | "titleBar.activeBackground": "#ff009d",
11 | },
12 | "search.exclude": {
13 | "website/public/": true,
14 | "node_modules/": true,
15 | "website/node_modules/": true,
16 | "dist/": true,
17 | "lib/": true,
18 | "package-lock.json": true,
19 | "website/package-lock.json": true,
20 | "yarn-error.log": true,
21 | "website/.deploy_git": true,
22 | "npm-debug.log": true,
23 | "website/npm-debug.log": true,
24 | "website/debug.log": true,
25 | "nohup.out": true,
26 | "yarn.lock": true
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | Thumbs.db
3 | npm-debug.log
4 | npm-debug.log*
5 | nohup.out
6 | node_modules
7 | .angular
8 | .cache
9 | .parcel-cache
10 | .eslintcache
11 | .vscode/settings.json
12 | .yarn/cache
13 | .yarn/install-state.gz
14 | yarn-error.log
15 | .idea
16 | .env
17 | tsconfig.tsbuildinfo
18 | tsconfig.build.tsbuildinfo
19 |
20 | dist/
21 | lib/
22 | coverage/
23 | examples/dev/bundle.js
24 | examples/aws-php/vendor/*
25 | test/endtoend/create-react-app/build/
26 | test/endtoend/create-react-app/coverage/
27 | petProj-*.tgz
28 | generatedLocale.d.ts
29 |
30 | **/output/*
31 | !output/.keep
32 | examples/dev/file.txt
33 | issues.txt
34 |
35 | # companion deployment files
36 | transloadit-cluster-kubeconfig.yaml
37 | companion-env.yml
38 |
--------------------------------------------------------------------------------
/.vscode/petProj.code-workspace:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "path": ".."
5 | }
6 | ],
7 | "settings": {
8 | "workbench.colorCustomizations": {
9 | "titleBar.activeForeground": "#ffffff",
10 | "titleBar.activeBackground": "#ff009d",
11 | },
12 | "search.exclude": {
13 | "website/public/": true,
14 | "node_modules/": true,
15 | "website/node_modules/": true,
16 | "dist/": true,
17 | "lib/": true,
18 | "package-lock.json": true,
19 | "website/package-lock.json": true,
20 | "yarn-error.log": true,
21 | "website/.deploy_git": true,
22 | "npm-debug.log": true,
23 | "website/npm-debug.log": true,
24 | "website/debug.log": true,
25 | "nohup.out": true,
26 | "yarn.lock": true
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/axamples/aws-companion/README.md:
--------------------------------------------------------------------------------
1 | # petProj + AWS S3 Example
2 |
3 | This example uses @petProj/companion with a custom AWS S3 configuration.
4 | Files are uploaded to a randomly named directory inside the `whatever/`
5 | directory in a bucket.
6 |
7 | ## Run it
8 |
9 | First, set up the `COMPANION_AWS_KEY`, `COMPANION_AWS_SECRET`,
10 | `COMPANION_AWS_REGION`, and `COMPANION_AWS_BUCKET` environment variables for
11 | `@petProj/companion` in a `.env` file. You may find useful to first copy the
12 | `.env.example` file:
13 |
14 | ```sh
15 | [ -f .env ] || cp .env.example .env
16 | ```
17 |
18 | To run this example, from the **repository root**, run:
19 |
20 | ```sh
21 | corepack yarn install
22 | corepack yarn workspace @petProj-example/aws-companion start
23 | ```
24 |
--------------------------------------------------------------------------------
/axamples/angular-example/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # Compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 | /bazel-out
8 |
9 | # Node
10 | /node_modules
11 | npm-debug.log
12 | yarn-error.log
13 |
14 | # IDEs and editors
15 | .idea/
16 | .project
17 | .classpath
18 | .c9/
19 | *.launch
20 | .settings/
21 | *.sublime-workspace
22 |
23 | # Visual Studio Code
24 | .vscode/*
25 | !.vscode/settings.json
26 | !.vscode/tasks.json
27 | !.vscode/launch.json
28 | !.vscode/extensions.json
29 | .history/*
30 |
31 | # Miscellaneous
32 | /.angular/cache
33 | .sass-cache/
34 | /connect.lock
35 | /coverage
36 | /libpeerconnection.log
37 | testem.log
38 | /typings
39 |
40 | # System files
41 | .DS_Store
42 | Thumbs.db
43 |
--------------------------------------------------------------------------------
/axamples/aws-companion/main.js:
--------------------------------------------------------------------------------
1 | import AwsS3 from '@petProj/aws-s3'
2 | import petProj from '@petProj/core'
3 | import Dashboard from '@petProj/dashboard'
4 | import GoogleDrive from '@petProj/google-drive'
5 | import Webcam from '@petProj/webcam'
6 |
7 | import '@petProj/core/dist/style.css'
8 | import '@petProj/dashboard/dist/style.css'
9 | import '@petProj/webcam/dist/style.css'
10 |
11 | const petProj = new petProj({
12 | debug: true,
13 | autoProceed: false,
14 | })
15 |
16 | petProj.use(GoogleDrive, {
17 | companionUrl: 'http://localhost:3020',
18 | })
19 | petProj.use(Webcam)
20 | petProj.use(Dashboard, {
21 | inline: true,
22 | target: 'body',
23 | plugins: ['GoogleDrive', 'Webcam'],
24 | })
25 | petProj.use(AwsS3, {
26 | companionUrl: 'http://localhost:3020',
27 | })
28 |
--------------------------------------------------------------------------------
/axamples/python-xhr/README.md:
--------------------------------------------------------------------------------
1 | # petProj + Python Example
2 |
3 | This example uses a Python Flask server and `@petProj/xhr-upload` to upload files to the local file system.
4 |
5 | ## Run it
6 |
7 | To run this example, make sure you've correctly installed the **repository root**:
8 |
9 | ```sh
10 | corepack yarn install
11 | corepack yarn build
12 | ```
13 |
14 | That will also install the npm dependencies for this example.
15 |
16 | Additionally, this example uses python dependencies. Move into this directory, and install them using pip:
17 |
18 | ```sh
19 | corepack yarn workspace @petProj-example/python-xhr installPythonDeps
20 | ```
21 |
22 | Then, again in the **repository root**, start this example by doing:
23 |
24 | ```sh
25 | corepack yarn workspace @petProj-example/python-xhr start
26 | ```
27 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "react-native-expo",
4 | "slug": "react-native-expo",
5 | "version": "1.0.0",
6 | "orientation": "portrait",
7 | "icon": "./assets/icon.png",
8 | "splash": {
9 | "image": "./assets/splash.png",
10 | "resizeMode": "contain",
11 | "backgroundColor": "#ffffff"
12 | },
13 | "updates": {
14 | "fallbackToCacheTimeout": 0
15 | },
16 | "assetBundlePatterns": ["**/*"],
17 | "ios": {
18 | "supportsTablet": true
19 | },
20 | "android": {
21 | "adaptiveIcon": {
22 | "foregroundImage": "./assets/adaptive-icon.png",
23 | "backgroundColor": "#FFFFFF"
24 | }
25 | },
26 | "web": {
27 | "favicon": "./assets/favicon.png"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/readme.md:
--------------------------------------------------------------------------------
1 | # petProj in React Native Expo (Beta)
2 |
3 | ⚠️ In Beta
4 |
5 | `@petProj/react-native` is a basic petProj component for React Native with Expo. It is in Beta, and is not full-featured. You can select local images or videos, take a picture with a camera or add any file from a remote url with petProj Companion.
6 |
7 | ## Run it
8 |
9 | To run this example, make sure you've correctly installed the **repository root**:
10 |
11 | ```bash
12 | yarn install
13 | yarn run build
14 | ```
15 |
16 | That will also install the dependencies for this example.
17 |
18 | Then, start this example by doing:
19 |
20 | ```bash
21 | cd examples/react-native-expo
22 | yarn start
23 | ```
24 |
25 | Then you'll see a menu within your terminal where you can chose where to open the app (Android, iOS, device etc.)
26 |
--------------------------------------------------------------------------------
/axamples/react-example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/react",
3 | "version": "0.0.0",
4 | "type": "module",
5 | "dependencies": {
6 | "@petProj/core": "workspace:*",
7 | "@petProj/dashboard": "workspace:*",
8 | "@petProj/drag-drop": "workspace:*",
9 | "@petProj/file-input": "workspace:*",
10 | "@petProj/google-drive": "workspace:*",
11 | "@petProj/progress-bar": "workspace:*",
12 | "@petProj/react": "workspace:*",
13 | "@petProj/tus": "workspace:*",
14 | "react": "^18.0.0",
15 | "react-dom": "^18.0.0"
16 | },
17 | "private": true,
18 | "scripts": {
19 | "dev": "vite",
20 | "build": "vite build",
21 | "preview": "vite preview --port 5050"
22 | },
23 | "devDependencies": {
24 | "@vitejs/plugin-react": "^2.0.0",
25 | "vite": "^4.0.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/tusFileReader.js:
--------------------------------------------------------------------------------
1 | import * as FileSystem from 'expo-file-system'
2 | import base64 from 'base64-js'
3 |
4 | export default function getTusFileReader (file, chunkSize, cb) {
5 | FileSystem.getInfoAsync(file.uri, { size: true }).then((info) => {
6 | cb(null, new TusFileReader(file, info.size))
7 | }).catch(cb)
8 | }
9 |
10 | class TusFileReader {
11 | constructor (file, size) {
12 | this.file = file
13 | this.size = size
14 | }
15 |
16 | slice (start, end, cb) {
17 | const options = {
18 | encoding: FileSystem.EncodingType.Base64,
19 | length: Math.min(end, this.size) - start,
20 | position: start,
21 | }
22 | FileSystem.readAsStringAsync(this.file.uri, options).then((data) => {
23 | cb(null, base64.toByteArray(data))
24 | }).catch(cb)
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/axamples/redux/README.md:
--------------------------------------------------------------------------------
1 | # Redux
2 |
3 | This example uses petProj with a Redux store.
4 | The same Redux store is also used for other parts of the application, namely the counter example.
5 | Each action is logged to the console using [redux-logger](https://github.com/theaqua/redux-logger).
6 |
7 | This example supports the [Redux Devtools extension](https://github.com/zalmoxisus/redux-devtools-extension), including time travel.
8 |
9 | ## Run it
10 |
11 | To run this example, make sure you've correctly installed the **repository root**:
12 |
13 | ```sh
14 | corepack yarn install
15 | corepack yarn build
16 | ```
17 |
18 | That will also install the dependencies for this example.
19 |
20 | Then, again in the **repository root**, start this example by doing:
21 |
22 | ```sh
23 | corepack yarn workspace @petProj-example/redux start
24 | ```
25 |
--------------------------------------------------------------------------------
/axamples/angular-example/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core'
2 | import { BrowserModule } from '@angular/platform-browser'
3 |
4 | import {
5 | petProjAngularDashboardModule,
6 | petProjAngularStatusBarModule,
7 | petProjAngularDragDropModule,
8 | petProjAngularProgressBarModule,
9 | petProjAngularDashboardModalModule,
10 | } from '@petProj' +
11 | /angular'
12 | import { AppComponent } from './app.component'
13 |
14 | @NgModule({
15 | declarations: [AppComponent],
16 | imports: [
17 | BrowserModule,
18 | petProjAngularDashboardModule,
19 | petProjAngularStatusBarModule,
20 | petProjAngularDashboardModalModule,
21 | petProjAngularDragDropModule,
22 | petProjAngularProgressBarModule,
23 | ],
24 | providers: [],
25 | bootstrap: [AppComponent],
26 | })
27 | export class AppModule {}
28 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/PauseResumeButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { StyleSheet, Text, TouchableHighlight } from 'react-native'
3 |
4 | export default function PauseResumeButton ({ uploadStarted, uploadComplete, isPaused, onPress }) {
5 | if (!uploadStarted || uploadComplete) {
6 | return null
7 | }
8 |
9 | return (
10 |
14 |
17 | {isPaused ? 'Resume' : 'Pause'}
18 |
19 |
20 | )
21 | }
22 |
23 | const styles = StyleSheet.create({
24 | button: {
25 | backgroundColor: '#cc0077',
26 | padding: 10,
27 | },
28 | text: {
29 | color: '#fff',
30 | textAlign: 'center',
31 | fontSize: 17,
32 | },
33 | })
34 |
--------------------------------------------------------------------------------
/axamples/redux/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | petProj example: Redux
7 |
8 |
9 |
10 | A counter
11 |
12 |
13 | Clicked: 0 times
14 | +
15 | -
16 | Increment if odd
17 | Increment async
18 |
19 |
20 | An petProj
21 |
22 |
23 |
24 | This app requires JavaScript.
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/axamples/transloadit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/transloadit",
3 | "version": "0.0.0",
4 | "type": "module",
5 | "devDependencies": {
6 | "npm-run-all": "^4.1.5",
7 | "vite": "^4.0.0"
8 | },
9 | "dependencies": {
10 | "@petProj/core": "workspace:*",
11 | "@petProj/dashboard": "workspace:*",
12 | "@petProj/drop-target": "workspace:*",
13 | "@petProj/form": "workspace:*",
14 | "@petProj/image-editor": "workspace:*",
15 | "@petProj/progress-bar": "workspace:*",
16 | "@petProj/remote-sources": "workspace:*",
17 | "@petProj/transloadit": "workspace:*",
18 | "@petProj/webcam": "workspace:*",
19 | "express": "^4.16.4",
20 | "he": "^1.2.0"
21 | },
22 | "private": true,
23 | "scripts": {
24 | "start:server": "node server.js",
25 | "start:client": "vite",
26 | "start": "npm-run-all --parallel start:server start:client"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/metro.config.js:
--------------------------------------------------------------------------------
1 | // Learn more https://docs.expo.dev/guides/monorepos
2 | const { getDefaultConfig } = require('expo/metro-config')
3 | const path = require('node:path')
4 |
5 | // Find the project and workspace directories
6 | const projectRoot = __dirname
7 | // This can be replaced with `find-yarn-workspace-root`
8 | const workspaceRoot = path.resolve(projectRoot, '../../')
9 |
10 | const config = getDefaultConfig(projectRoot)
11 |
12 | // 1. Watch all files within the monorepo
13 | config.watchFolders = [workspaceRoot]
14 | // 2. Let Metro know where to resolve packages and in what order
15 | config.resolver.nodeModulesPaths = [
16 | path.resolve(projectRoot, 'node_modules'),
17 | path.resolve(workspaceRoot, 'node_modules'),
18 | ]
19 | // 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths`
20 | config.resolver.disableHierarchicalLookup = true
21 |
22 | module.exports = config
23 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/ProgressBar.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { View, Text, StyleSheet } from 'react-native'
3 |
4 | const colorGreen = '#0b8600'
5 | const colorBlue = '#006bb7'
6 |
7 | export default function ProgressBar ({ progress }) {
8 | return (
9 |
10 |
13 |
18 |
19 | {progress ? `${progress}%` : null}
20 |
21 | )
22 | }
23 |
24 | const styles = StyleSheet.create({
25 | root: {
26 | marginTop: 15,
27 | marginBottom: 15,
28 | },
29 | wrapper:{
30 | height: 5,
31 | overflow: 'hidden',
32 | backgroundColor: '#dee1e3',
33 | },
34 | bar: {
35 | height: 5,
36 | },
37 | })
38 |
--------------------------------------------------------------------------------
/axamples/aws-companion/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/aws-companion",
3 | "version": "0.0.0",
4 | "type": "module",
5 | "dependencies": {
6 | "@petProj/aws-s3": "workspace:*",
7 | "@petProj/core": "workspace:*",
8 | "@petProj/dashboard": "workspace:*",
9 | "@petProj/google-drive": "workspace:*",
10 | "@petProj/webcam": "workspace:*"
11 | },
12 | "devDependencies": {
13 | "@petProj/companion": "workspace:*",
14 | "body-parser": "^1.20.0",
15 | "cookie-parser": "^1.4.6",
16 | "cors": "^2.8.5",
17 | "dotenv": "^16.0.1",
18 | "express": "^4.18.1",
19 | "express-session": "^1.17.3",
20 | "npm-run-all": "^4.1.5",
21 | "vite": "^4.0.0"
22 | },
23 | "private": true,
24 | "engines": {
25 | "node": ">=16.15.0"
26 | },
27 | "scripts": {
28 | "dev": "vite",
29 | "start": "npm-run-all --parallel start:client start:server",
30 | "start:client": "vite",
31 | "start:server": "node server.cjs"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/axamples/react-example/README.md:
--------------------------------------------------------------------------------
1 | # React example
2 |
3 | This is minimal example created to demonstrate how to integrate petProj in your
4 | React app.
5 |
6 | To spawn the demo, use the following commands:
7 |
8 | ```sh
9 | corepack yarn install
10 | corepack yarn build
11 | corepack yarn workspace @petProj-example/react dev
12 | ```
13 |
14 | If you'd like to use a different package manager than Yarn (e.g. npm) to work
15 | with this example, you can extract it from the workspace like this:
16 |
17 | ```sh
18 | corepack yarn workspace @petProj-example/react pack
19 |
20 | # The above command should have create a .tgz file, we're going to extract it to
21 | # a new directory outside of the petProj workspace.
22 | mkdir ../react-example
23 | tar -xzf examples/react-example/package.tgz -C ../react-example --strip-components 1
24 | rm -f examples/react-example/package.tgz
25 |
26 | # Now you can leave the petProj workspace and use the example as a standalone JS project:
27 | cd ../react-example
28 | npm i
29 | npm run dev
30 | ```
31 |
--------------------------------------------------------------------------------
/axamples/angular-example/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": "./",
6 | "outDir": "./dist/out-tsc",
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": true,
9 | "noImplicitOverride": true,
10 | "noPropertyAccessFromIndexSignature": true,
11 | "noImplicitReturns": true,
12 | "noFallthroughCasesInSwitch": true,
13 | "sourceMap": true,
14 | "declaration": false,
15 | "downlevelIteration": true,
16 | "experimentalDecorators": true,
17 | "moduleResolution": "node",
18 | "importHelpers": true,
19 | "target": "ES2022",
20 | "module": "ES2022",
21 | "useDefineForClassFields": false,
22 | "lib": ["ES2022", "dom"]
23 | },
24 | "angularCompilerOptions": {
25 | "enableI18nLegacyMessageIdFormat": false,
26 | "strictInjectionParameters": true,
27 | "strictInputAccessModifiers": true,
28 | "strictTemplates": true
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/axamples/xhr-bundle/README.md:
--------------------------------------------------------------------------------
1 | # XHR Bundle Upload
2 |
3 | This example uses petProj with XHRUpload plugin in `bundle` mode. Bundle mode uploads all files to the endpoint in a single request, instead of firing off a new request for each file. This makes uploading a bit slower, but it may be easier to handle on the server side, depending on your setup.
4 |
5 | [`server.cjs`](./server.cjs) contains an example express.js server that receives a multipart form-data upload and responds with some information about the files that were received (name, size) as JSON. It uses [multer](https://npmjs.com/package/multer) to parse the upload stream.
6 |
7 | ## Run it
8 |
9 | To run this example, make sure you've correctly installed the **repository root**:
10 |
11 | ```sh
12 | corepack yarn install
13 | corepack yarn build
14 | ```
15 |
16 | That will also install the dependencies for this example.
17 |
18 | Then, again in the **repository root**, start this example by doing:
19 |
20 | ```sh
21 | corepack yarn workspace @petProj-example/xhr-bundle start
22 | ```
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 Transloadit (https://transloadit.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/axamples/angular-example/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
3 | "version": "2.0.0",
4 | "tasks": [
5 | {
6 | "type": "npm",
7 | "script": "start",
8 | "isBackground": true,
9 | "problemMatcher": {
10 | "owner": "typescript",
11 | "pattern": "$tsc",
12 | "background": {
13 | "activeOnStart": true,
14 | "beginsPattern": {
15 | "regexp": "(.*?)"
16 | },
17 | "endsPattern": {
18 | "regexp": "bundle generation complete"
19 | }
20 | }
21 | }
22 | },
23 | {
24 | "type": "npm",
25 | "script": "test",
26 | "isBackground": true,
27 | "problemMatcher": {
28 | "owner": "typescript",
29 | "pattern": "$tsc",
30 | "background": {
31 | "activeOnStart": true,
32 | "beginsPattern": {
33 | "regexp": "(.*?)"
34 | },
35 | "endsPattern": {
36 | "regexp": "bundle generation complete"
37 | }
38 | }
39 | }
40 | }
41 | ]
42 | }
43 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/react-native-expo",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "start": "expo start",
7 | "android": "expo start --android",
8 | "ios": "expo start --ios",
9 | "web": "expo start --web",
10 | "eject": "expo eject"
11 | },
12 | "dependencies": {
13 | "@react-native-async-storage/async-storage": "~1.15.0",
14 | "@petProj/core": "workspace:*",
15 | "@petProj/dashboard": "workspace:*",
16 | "@petProj/instagram": "workspace:*",
17 | "@petProj/react": "workspace:*",
18 | "@petProj/react-native": "workspace:*",
19 | "@petProj/tus": "workspace:*",
20 | "@petProj/url": "workspace:*",
21 | "@petProj/xhr-upload": "workspace:*",
22 | "base64-js": "^1.3.0",
23 | "expo": "~43.0.2",
24 | "expo-file-system": "~13.0.3",
25 | "expo-status-bar": "~1.1.0",
26 | "preact-render-to-string": "^5.1.0",
27 | "react": "17.0.1",
28 | "react-dom": "17.0.1",
29 | "react-native": "0.64.3",
30 | "react-native-web": "0.17.1"
31 | },
32 | "devDependencies": {
33 | "@babel/core": "^7.12.9"
34 | },
35 | "private": true
36 | }
37 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:18.17.1-alpine as build
2 |
3 | # Create link to node on amd64 so that corepack can find it
4 | RUN if [ "$(uname -m)" == "aarch64" ]; then mkdir -p /usr/local/sbin/ && ln -s /usr/local/bin/node /usr/local/sbin/node; fi
5 |
6 | WORKDIR /app
7 |
8 | COPY . /app/
9 |
10 | RUN apk --update add --virtual native-dep \
11 | make gcc g++ python3 libgcc libstdc++ git && \
12 | (cd /app && corepack yarn workspaces focus @petProj/companion) && \
13 | apk del native-dep
14 |
15 | RUN cd /app && corepack yarn workspace @petProj/companion build
16 |
17 | # Now remove all non-prod dependencies for a leaner image
18 | RUN cd /app && corepack yarn workspaces focus @petProj/companion --production
19 |
20 | FROM node:18.17.1-alpine
21 |
22 | WORKDIR /app
23 |
24 | # copy required files from build stage.
25 | COPY --from=build /app/packages/@petProj/companion/bin /app/bin
26 | COPY --from=build /app/packages/@petProj/companion/lib /app/lib
27 | COPY --from=build /app/packages/@petProj/companion/package.json /app/package.json
28 | COPY --from=build /app/packages/@petProj/companion/node_modules /app/node_modules
29 |
30 | ENV PATH "${PATH}:/app/node_modules/.bin"
31 |
32 | CMD ["node","/app/bin/companion"]
33 | # This can be overruled later
34 | EXPOSE 3020
35 |
--------------------------------------------------------------------------------
/axamples/svelte-example/public/global.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | position: relative;
4 | width: 100%;
5 | height: 100%;
6 | }
7 |
8 | body {
9 | color: #333;
10 | margin: 0;
11 | padding: 8px;
12 | box-sizing: border-box;
13 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
14 | Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
15 | }
16 |
17 | a {
18 | color: rgb(0, 100, 200);
19 | text-decoration: none;
20 | }
21 |
22 | a:hover {
23 | text-decoration: underline;
24 | }
25 |
26 | a:visited {
27 | color: rgb(0, 80, 160);
28 | }
29 |
30 | label {
31 | display: block;
32 | }
33 |
34 | input,
35 | button,
36 | select,
37 | textarea {
38 | font-family: inherit;
39 | font-size: inherit;
40 | -webkit-padding: 0.4em 0;
41 | padding: 0.4em;
42 | margin: 0 0 0.5em 0;
43 | box-sizing: border-box;
44 | border: 1px solid #ccc;
45 | border-radius: 2px;
46 | }
47 |
48 | input:disabled {
49 | color: #ccc;
50 | }
51 |
52 | button {
53 | color: #333;
54 | background-color: #f4f4f4;
55 | outline: none;
56 | }
57 |
58 | button:disabled {
59 | color: #999;
60 | }
61 |
62 | button:not(:disabled):active {
63 | background-color: #ddd;
64 | }
65 |
66 | button:focus {
67 | border-color: #666;
68 | }
69 |
--------------------------------------------------------------------------------
/axamples/angular-example/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignorePatterns": ["projects/**/*"],
3 | "overrides": [
4 | {
5 | "files": ["*.ts"],
6 | "extends": [
7 | "eslint:recommended",
8 | "plugin:@typescript-eslint/recommended",
9 | "plugin:@angular-eslint/recommended",
10 | "plugin:@angular-eslint/template/process-inline-templates"
11 | ],
12 | "rules": {
13 | "@angular-eslint/directive-selector": [
14 | "error",
15 | {
16 | "type": "attribute",
17 | "prefix": "app",
18 | "style": "camelCase"
19 | }
20 | ],
21 | "@typescript-eslint/semi": ["error", "never"],
22 | "import/no-unresolved": "off",
23 | "import/prefer-default-export": "off",
24 | "@angular-eslint/component-selector": [
25 | "error",
26 | {
27 | "type": "element",
28 | "prefix": "app",
29 | "style": "kebab-case"
30 | }
31 | ],
32 | "semi": ["error", "never"]
33 | }
34 | },
35 | {
36 | "files": ["star.html"],
37 | "extends": [
38 | "plugin:@angular-eslint/template/recommended",
39 | "plugin:@angular-eslint/template/accessibility"
40 | ],
41 | "rules": {}
42 | }
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/axamples/angular-example/README.md:
--------------------------------------------------------------------------------
1 | # AngularExample
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 16.2.0.
4 |
5 | ## Development server
6 |
7 | ```
8 | corepack yarn install
9 | corepack yarn build
10 | corepack yarn workspace @petProj/angular prepublishOnly
11 | corepack yarn workspace @petProj-example/angular start
12 | ```
13 |
14 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
15 |
16 | ## Code scaffolding
17 |
18 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
19 |
20 | ## Build
21 |
22 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
23 |
24 | ## Running unit tests
25 |
26 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
27 |
28 | ## Running end-to-end tests
29 |
30 | Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
31 |
32 | ## Further help
33 |
34 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
35 |
--------------------------------------------------------------------------------
/axamples/petProj-with-companion/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 | Open Modal
14 | This web page requires JavaScript to work properly.
15 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/axamples/svelte-example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/svelte-app",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "build": "rollup -c",
6 | "serve": "sirv public",
7 | "start:client": "rollup -c -w",
8 | "start:server": "node ./server.mjs",
9 | "start": "npm-run-all --parallel start:client start:server",
10 | "validate": "svelte-check"
11 | },
12 | "devDependencies": {
13 | "@rollup/plugin-commonjs": "^22.0.0",
14 | "@rollup/plugin-json": "^4.1.0",
15 | "@rollup/plugin-node-resolve": "^13.0.0",
16 | "@rollup/plugin-typescript": "^8.0.0",
17 | "@tsconfig/svelte": "^1.0.0",
18 | "npm-run-all": "^4.1.5",
19 | "postcss": "^8.4.31",
20 | "postcss-import": "^13.0.0",
21 | "postcss-load-config": "^3.0.0",
22 | "rollup": "^2.60.2",
23 | "rollup-plugin-css-only": "^3.0.0",
24 | "rollup-plugin-livereload": "^2.0.0",
25 | "rollup-plugin-svelte": "^7.0.0",
26 | "rollup-plugin-terser": "^7.0.0",
27 | "svelte": ">=3.24.0",
28 | "svelte-check": "^1.6.0",
29 | "svelte-preprocess": "^5.0.0",
30 | "tslib": "^2.0.0",
31 | "typescript": "~5.1"
32 | },
33 | "dependencies": {
34 | "@petProj/core": "workspace:*",
35 | "@petProj/svelte": "workspace:*",
36 | "@petProj/webcam": "workspace:*",
37 | "@petProj/xhr-upload": "workspace:*",
38 | "formidable": "^2.0.1",
39 | "sirv-cli": "^1.0.0"
40 | },
41 | "private": true
42 | }
43 |
--------------------------------------------------------------------------------
/.yarn/patches/pre-commit-npm-1.2.2-f30af83877.patch:
--------------------------------------------------------------------------------
1 | diff --git a/index.js b/index.js
2 | index a20646d922945004cb737918ef6b6d063bb3c2a4..a44863e9555abdaa569f309b1197fddc8dd244a5 100644
3 | --- a/index.js
4 | +++ b/index.js
5 | @@ -147,7 +147,7 @@ Hook.prototype.log = function log(lines, exit) {
6 | * @api private
7 | */
8 | Hook.prototype.initialize = function initialize() {
9 | - ['git', 'npm'].forEach(function each(binary) {
10 | + ['git', 'corepack'].forEach(function each(binary) {
11 | try { this[binary] = which.sync(binary); }
12 | catch (e) {}
13 | }, this);
14 | @@ -159,9 +159,9 @@ Hook.prototype.initialize = function initialize() {
15 | if (!this.npm) {
16 | try {
17 | process.env.PATH += path.delimiter + path.dirname(process.env._);
18 | - this.npm = which.sync('npm');
19 | + this.npm = which.sync('corepack');
20 | } catch (e) {
21 | - return this.log(this.format(Hook.log.binary, 'npm'), 0);
22 | + return this.log(this.format(Hook.log.binary, 'corepack'), 0);
23 | }
24 | }
25 |
26 | @@ -225,7 +225,7 @@ Hook.prototype.run = function runner() {
27 | // this doesn't have the required `isAtty` information that libraries use to
28 | // output colors resulting in script output that doesn't have any color.
29 | //
30 | - spawn(hooked.npm, ['run', script, '--silent'], {
31 | + spawn(hooked.npm, ['yarn', script], {
32 | env: process.env,
33 | cwd: hooked.root,
34 | stdio: [0, 1, 2]
35 |
--------------------------------------------------------------------------------
/axamples/python-xhr/server.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import os
3 | from flask import Flask, request, jsonify
4 | from werkzeug.utils import secure_filename
5 | from flask_cors import CORS
6 |
7 | UPLOAD_FOLDER = 'uploads'
8 | ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
9 |
10 | app = Flask(__name__)
11 | app.config['UPLOAD_FOLDER'] = os.path.join(os.path.dirname(__file__), UPLOAD_FOLDER)
12 | CORS(app)
13 |
14 | def allowed_file(filename):
15 | return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
16 |
17 | @app.route('/upload', methods=['POST'])
18 | def upload_file():
19 | if request.method == 'POST':
20 | uploaded_files = request.files.getlist('file')
21 | if not uploaded_files:
22 | return jsonify(error="No files in the request"), 400
23 |
24 | uploaded_filenames = []
25 | for file in uploaded_files:
26 | if file and allowed_file(file.filename):
27 | filename = secure_filename(file.filename)
28 | file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
29 | uploaded_filenames.append(filename)
30 |
31 | if uploaded_filenames:
32 | return jsonify(message="Files uploaded successfully", uploaded_files=uploaded_filenames), 201
33 | else:
34 | return jsonify(error="No valid files uploaded"), 400
35 |
36 | if __name__ == '__main__':
37 | app.run(port=3020)
38 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Licensed under MIT.
2 | # Copyright (2016) by Kevin van Zonneveld https://twitter.com/kvz
3 | #
4 | # https://www.npmjs.com/package/fakefile
5 | #
6 | # Please do not edit this file directly, but propose changed upstream instead:
7 | # https://github.com/kvz/fakefile/blob/master/Makefile
8 | #
9 | # This Makefile offers convience shortcuts into any Node.js project that utilizes npm scripts.
10 | # It functions as a wrapper around the actual listed in `package.json`
11 | # So instead of typing:
12 | #
13 | # $ npm script build:assets
14 | #
15 | # you could also type:
16 | #
17 | # $ make build-assets
18 | #
19 | # Notice that colons (:) are replaced by dashes for Makefile compatibility.
20 | #
21 | # The benefits of this wrapper are:
22 | #
23 | # - You get to keep the the scripts package.json, which is more portable
24 | # (Makefiles & Windows are harder to mix)
25 | # - Offer a polite way into the project for developers coming from different
26 | # languages (npm scripts is obviously very Node centric)
27 | # - Profit from better autocomplete (make ) than npm currently offers.
28 | # OSX users will have to install bash-completion
29 | # (http://davidalger.com/development/bash-completion-on-os-x-with-brew/)
30 |
31 | define npm_script_targets
32 | TARGETS := $(shell node -e 'for (var k in require("./package.json").scripts) {console.log(k.replace(/:/g, "-"));}')
33 | $$(TARGETS):
34 | npm run $(subst -,:,$(MAKECMDGOALS))
35 |
36 | .PHONY: $$(TARGETS)
37 | endef
38 |
39 | $(eval $(call npm_script_targets))
40 |
41 | # These npm run scripts are available, without needing to be mentioned in `package.json`
42 | install:
43 | npm install
44 |
--------------------------------------------------------------------------------
/axamples/svelte-example/server.mjs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /* eslint-disable no-console */
4 |
5 | import http from 'node:http'
6 | import { fileURLToPath } from 'node:url'
7 | import { mkdir } from 'node:fs/promises'
8 |
9 | import formidable from 'formidable'
10 |
11 | const UPLOAD_DIR = new URL('./uploads/', import.meta.url)
12 |
13 | await mkdir(UPLOAD_DIR, { recursive: true })
14 |
15 | http.createServer((req, res) => {
16 | const headers = {
17 | 'Content-Type': 'application/json',
18 | 'Access-Control-Allow-Origin': '*',
19 | 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
20 | 'Access-Control-Max-Age': 2592000, // 30 days
21 | /** add other headers as per requirement */
22 | }
23 |
24 | if (req.method === 'OPTIONS') {
25 | res.writeHead(204, headers)
26 | res.end()
27 | return
28 | }
29 | if (req.url === '/upload' && req.method.toLowerCase() === 'post') {
30 | // parse a file upload
31 | const form = formidable({
32 | keepExtensions: true,
33 | uploadDir: fileURLToPath(UPLOAD_DIR),
34 | })
35 |
36 | form.parse(req, (err, fields, files) => {
37 | if (err) {
38 | console.log('some error', err)
39 | res.writeHead(200, headers)
40 | res.write(JSON.stringify(err))
41 | return res.end()
42 | }
43 | const { files: { filepath, originalFilename, mimetype, size } } = files
44 | console.log('saved file', { filepath, originalFilename, mimetype, size })
45 | res.writeHead(200, headers)
46 | res.write(JSON.stringify({ fields, files }))
47 | return res.end()
48 | })
49 | }
50 | }).listen(9967, () => {
51 | console.log('server started')
52 | })
53 |
--------------------------------------------------------------------------------
/axamples/aws-companion/server.cjs:
--------------------------------------------------------------------------------
1 | const fs = require('node:fs')
2 | const path = require('node:path')
3 | const crypto = require('node:crypto')
4 | const companion = require('@petProj/companion')
5 |
6 | require('dotenv').config({ path: path.join(__dirname, '..', '..', '.env') })
7 | const app = require('express')()
8 |
9 | const DATA_DIR = path.join(__dirname, 'tmp')
10 |
11 | app.use(require('cors')({
12 | origin: 'http://localhost:3000',
13 | methods: ['GET', 'POST', 'OPTIONS'],
14 | credentials: true,
15 | }))
16 | app.use(require('cookie-parser')())
17 | app.use(require('body-parser').json())
18 | app.use(require('express-session')({
19 | secret: 'hello planet',
20 | saveUninitialized: false,
21 | resave: false,
22 | }))
23 |
24 | const options = {
25 | providerOptions: {
26 | drive: {
27 | key: process.env.COMPANION_GOOGLE_KEY,
28 | secret: process.env.COMPANION_GOOGLE_SECRET,
29 | },
30 | },
31 | s3: {
32 | getKey: (req, filename) => `${crypto.randomUUID()}-${filename}`,
33 | key: process.env.COMPANION_AWS_KEY,
34 | secret: process.env.COMPANION_AWS_SECRET,
35 | bucket: process.env.COMPANION_AWS_BUCKET,
36 | region: process.env.COMPANION_AWS_REGION,
37 | endpoint: process.env.COMPANION_AWS_ENDPOINT,
38 | },
39 | server: { host: 'localhost:3020' },
40 | filePath: DATA_DIR,
41 | secret: 'blah blah',
42 | debug: true,
43 | }
44 |
45 | // Create the data directory here for the sake of the example.
46 | try {
47 | fs.accessSync(DATA_DIR)
48 | } catch (err) {
49 | fs.mkdirSync(DATA_DIR)
50 | }
51 | process.on('exit', () => {
52 | fs.rmSync(DATA_DIR, { recursive: true, force: true })
53 | })
54 |
55 | const { app: companionApp } = companion.app(options)
56 |
57 | app.use(companionApp)
58 |
59 | const server = app.listen(3020, () => {
60 | console.log('listening on port 3020')
61 | })
62 |
63 | companion.socket(server)
64 |
--------------------------------------------------------------------------------
/axamples/svelte-example/src/App.svelte:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 | Welcome to the @petProj/svelte demo!
25 | Inline Dashboard
26 |
27 |
31 | Show Dashboard
32 |
33 | {#if showInlineDashboard}
34 |
38 | {/if}
39 | Modal Dashboard
40 |
41 | open = true}>Show Dashboard
42 | open = false,
47 | plugins: ['Webcam']
48 | }}
49 | />
50 |
51 |
52 | Drag Drop Area
53 |
56 |
57 | Progress Bar
58 |
64 |
65 |
74 |
--------------------------------------------------------------------------------
/axamples/angular-example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@petProj-example/angular",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "ng": "ng",
6 | "start": "ng serve",
7 | "build": "ng build",
8 | "watch": "ng build --watch --configuration development",
9 | "test": "ng test",
10 | "lint": "ng lint"
11 | },
12 | "private": true,
13 | "dependencies": {
14 | "@angular/animations": "^16.2.0",
15 | "@angular/common": "^16.2.0",
16 | "@angular/compiler": "^16.2.0",
17 | "@angular/core": "^16.2.0",
18 | "@angular/forms": "^16.2.0",
19 | "@angular/platform-browser": "^16.2.0",
20 | "@angular/platform-browser-dynamic": "^16.2.0",
21 | "@angular/router": "^16.2.0",
22 | "@petProj/angular": "workspace:*",
23 | "@petProj/core": "workspace:*",
24 | "@petProj/drag-drop": "workspace:*",
25 | "@petProj/google-drive": "workspace:*",
26 | "@petProj/progress-bar": "workspace:*",
27 | "@petProj/tus": "workspace:*",
28 | "@petProj/webcam": "workspace:*",
29 | "rxjs": "~7.8.0",
30 | "tslib": "^2.3.0",
31 | "zone.js": "~0.13.0"
32 | },
33 | "devDependencies": {
34 | "@angular-devkit/build-angular": "^16.2.0",
35 | "@angular-eslint/builder": "16.1.1",
36 | "@angular-eslint/eslint-plugin": "16.1.1",
37 | "@angular-eslint/eslint-plugin-template": "16.1.1",
38 | "@angular-eslint/schematics": "16.1.1",
39 | "@angular-eslint/template-parser": "16.1.1",
40 | "@angular/cli": "~16.2.0",
41 | "@angular/compiler-cli": "^16.2.0",
42 | "@types/jasmine": "~4.3.0",
43 | "@typescript-eslint/eslint-plugin": "5.62.0",
44 | "@typescript-eslint/parser": "5.62.0",
45 | "eslint": "^8.0.0",
46 | "jasmine-core": "~4.6.0",
47 | "karma": "~6.4.0",
48 | "karma-chrome-launcher": "~3.2.0",
49 | "karma-coverage": "~2.2.0",
50 | "karma-jasmine": "~5.1.0",
51 | "karma-jasmine-html-reporter": "~2.1.0",
52 | "typescript": "~5.1"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/axamples/petProj-with-companion/server/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const bodyParser = require('body-parser')
3 | const session = require('express-session')
4 | const companion = require('@petProj/companion')
5 |
6 | const app = express()
7 |
8 | app.use(bodyParser.json())
9 | app.use(session({
10 | secret: 'some-secret',
11 | resave: true,
12 | saveUninitialized: true,
13 | }))
14 |
15 | app.use((req, res, next) => {
16 | res.setHeader('Access-Control-Allow-Origin', req.headers.origin || '*')
17 | next()
18 | })
19 |
20 | // Routes
21 | app.get('/', (req, res) => {
22 | res.setHeader('Content-Type', 'text/plain')
23 | res.send('Welcome to Companion')
24 | })
25 |
26 | // initialize petProj
27 | const companionOptions = {
28 | providerOptions: {
29 | drive: {
30 | key: 'your google key',
31 | secret: 'your google secret',
32 | },
33 | instagram: {
34 | key: 'your instagram key',
35 | secret: 'your instagram secret',
36 | },
37 | dropbox: {
38 | key: 'your dropbox key',
39 | secret: 'your dropbox secret',
40 | },
41 | box: {
42 | key: 'your box key',
43 | secret: 'your box secret',
44 | },
45 | // you can also add options for additional providers here
46 | },
47 | server: {
48 | host: 'localhost:3020',
49 | protocol: 'http',
50 | },
51 | filePath: './output',
52 | secret: 'some-secret',
53 | debug: true,
54 | }
55 |
56 | const { app: companionApp } = companion.app(companionOptions)
57 | app.use(companionApp)
58 |
59 | // handle 404
60 | app.use((req, res) => {
61 | return res.status(404).json({ message: 'Not Found' })
62 | })
63 |
64 | // handle server errors
65 | app.use((err, req, res) => {
66 | console.error('\x1b[31m', err.stack, '\x1b[0m')
67 | res.status(err.status || 500).json({ message: err.message, error: err })
68 | })
69 |
70 | companion.socket(app.listen(3020))
71 |
72 | console.log('Welcome to Companion!')
73 | console.log(`Listening on http://0.0.0.0:${3020}`)
74 |
--------------------------------------------------------------------------------
/.yarn/patches/preact-npm-10.10.0-dd04de05e8.patch:
--------------------------------------------------------------------------------
1 | diff --git a/debug/package.json b/debug/package.json
2 | index 054944f5478a0a5cf7b6b8791950c595f956157b..06a4fe2719605eb42c5ee795101c21cfd10b59ce 100644
3 | --- a/debug/package.json
4 | +++ b/debug/package.json
5 | @@ -9,6 +9,7 @@
6 | "umd:main": "dist/debug.umd.js",
7 | "source": "src/index.js",
8 | "license": "MIT",
9 | + "type": "module",
10 | "mangle": {
11 | "regex": "^(?!_renderer)^_"
12 | },
13 | diff --git a/devtools/package.json b/devtools/package.json
14 | index 09b04a77690bdfba01083939ff9eaf987dd50bcb..92c159fbb3cf312c6674202085fb237d6fb921ad 100644
15 | --- a/devtools/package.json
16 | +++ b/devtools/package.json
17 | @@ -10,6 +10,7 @@
18 | "source": "src/index.js",
19 | "license": "MIT",
20 | "types": "src/index.d.ts",
21 | + "type": "module",
22 | "peerDependencies": {
23 | "preact": "^10.0.0"
24 | },
25 | diff --git a/hooks/package.json b/hooks/package.json
26 | index 74807025bf3de273ebada2cd355428a2c972503d..98501726ffbfe55ffa09928e56a9dcafb9a348ff 100644
27 | --- a/hooks/package.json
28 | +++ b/hooks/package.json
29 | @@ -10,6 +10,7 @@
30 | "source": "src/index.js",
31 | "license": "MIT",
32 | "types": "src/index.d.ts",
33 | + "type": "module",
34 | "scripts": {
35 | "build": "microbundle build --raw",
36 | "dev": "microbundle watch --raw --format cjs",
37 | diff --git a/jsx-runtime/package.json b/jsx-runtime/package.json
38 | index 7a4027831223f16519a74e3028c34f2f8f5f011a..6b58d17dbacce81894467ef43c0a8e2435e388c4 100644
39 | --- a/jsx-runtime/package.json
40 | +++ b/jsx-runtime/package.json
41 | @@ -10,6 +10,7 @@
42 | "source": "src/index.js",
43 | "types": "src/index.d.ts",
44 | "license": "MIT",
45 | + "type": "module",
46 | "peerDependencies": {
47 | "preact": "^10.0.0"
48 | },
49 | diff --git a/package.json b/package.json
50 | index 60279c24a08b808ffbf7dc64a038272bddb6785d..088f35fb2c92f2e9b7248557857af2839988d1aa 100644
51 | --- a/package.json
52 | +++ b/package.json
53 | @@ -9,6 +9,7 @@
54 | "umd:main": "dist/preact.umd.js",
55 | "unpkg": "dist/preact.min.js",
56 | "source": "src/index.js",
57 | + "type": "module",
58 | "exports": {
59 | ".": {
60 | "types": "./src/index.d.ts",
61 |
--------------------------------------------------------------------------------
/axamples/angular-example/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core'
2 | import { petProj} from '@petProj' +
3 | /core'
4 | import Webcam from '@petProj' +
5 | /webcam'
6 | import Tus from '@petProj' +
7 | /tus'
8 | import GoogleDrive from '@petProj' +
9 | /google-drive'
10 |
11 | @Component({
12 | selector: 'app-root',
13 | template: /* html */ `
14 | petProj Angular Example!
15 | Inline dashboard
16 |
17 |
22 | Show Dashboard
23 |
24 |
25 |
30 |
31 | Modal Dashboard
32 |
33 |
38 |
39 | {{ showModal ? 'Close dashboard' : 'Open dashboard' }}
40 |
41 |
42 |
43 | Drag Drop Area
44 |
45 |
46 | Progress Bar
47 |
51 | `,
52 | styleUrls: [],
53 | })
54 | export class AppComponent implements OnInit {
55 | title = 'angular-example'
56 |
57 | showInline = false
58 |
59 | showModal = false
60 |
61 | dashboardProps = {
62 | plugins: ['Webcam'],
63 | }
64 |
65 | dashboardModalProps = {
66 | target: document.body,
67 | onRequestCloseModal: (): void => {
68 | this.showModal = false
69 | },
70 | }
71 |
72 | petProj: petProj = new petProj({ debug: true, autoProceed: true })
73 |
74 | ngOnInit(): void {
75 | this.petProj
76 | .use(Webcam)
77 | .use(Tus, { endpoint: 'https://tusd.tusdemo.net/files/' })
78 | .use(GoogleDrive, { companionUrl: 'https://companion.petProj' +
79 | .io' })
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/axamples/svelte-example/rollup.config.js:
--------------------------------------------------------------------------------
1 | import svelte from 'rollup-plugin-svelte'
2 | import commonjs from '@rollup/plugin-commonjs'
3 | import resolve from '@rollup/plugin-node-resolve'
4 | import livereload from 'rollup-plugin-livereload'
5 | import { terser } from 'rollup-plugin-terser'
6 | import sveltePreprocess from 'svelte-preprocess'
7 | import typescript from '@rollup/plugin-typescript'
8 | import css from 'rollup-plugin-css-only'
9 |
10 | const production = !process.env.ROLLUP_WATCH
11 |
12 | function serve () {
13 | let server
14 |
15 | function toExit () {
16 | if (server) server.kill(0)
17 | }
18 |
19 | return {
20 | writeBundle () {
21 | if (server) return
22 | // eslint-disable-next-line global-require
23 | server = require('node:child_process').spawn('npm', ['run', 'serve', '--', '--dev'], {
24 | stdio: ['ignore', 'inherit', 'inherit'],
25 | shell: true,
26 | })
27 |
28 | process.on('SIGTERM', toExit)
29 | process.on('exit', toExit)
30 | },
31 | }
32 | }
33 |
34 | export default {
35 | input: 'src/main.ts',
36 | output: {
37 | sourcemap: true,
38 | format: 'iife',
39 | name: 'app',
40 | file: 'public/build/bundle.js',
41 | },
42 | plugins: [
43 | svelte({
44 | preprocess: sveltePreprocess({
45 | postcss: true,
46 | }),
47 | compilerOptions: {
48 | // enable run-time checks when not in production
49 | dev: !production,
50 | },
51 | }),
52 | // we'll extract any component CSS out into
53 | // a separate file - better for performance
54 | css({ output: 'bundle.css' }),
55 |
56 | // If you have external dependencies installed from
57 | // npm, you'll most likely need these plugins. In
58 | // some cases you'll need additional configuration -
59 | // consult the documentation for details:
60 | // https://github.com/rollup/plugins/tree/master/packages/commonjs
61 | resolve({
62 | browser: true,
63 | dedupe: ['svelte', '@petProj/core'],
64 | }),
65 | commonjs(),
66 | typescript({
67 | sourceMap: !production,
68 | inlineSources: !production,
69 | }),
70 |
71 | // In dev mode, call `npm run start` once
72 | // the bundle has been generated
73 | !production && serve(),
74 |
75 | // Watch the `public` directory and refresh the
76 | // browser on changes when not in production
77 | !production && livereload('public'),
78 |
79 | // If we're building for production (npm run build
80 | // instead of npm run dev), minify
81 | production && terser(),
82 | ],
83 | watch: {
84 | clearScreen: false,
85 | },
86 | }
87 |
--------------------------------------------------------------------------------
/axamples/php-xhr/server.php:
--------------------------------------------------------------------------------
1 | $max_size) {
32 | header('Access-Control-Allow-Origin: *');
33 | header('Content-type: application/json');
34 | $data = ['message' => 'File size exceeds the maximum allowed size of ' . $max_size . '.'];
35 | http_response_code(400);
36 | echo json_encode($data);
37 | exit;
38 | }
39 |
40 | // Sanitize file name to prevent directory traversal attacks
41 | $file_name = preg_replace('/[^a-zA-Z0-9._-]/', '', $file_name);
42 | $target_file = $target_dir . DIRECTORY_SEPARATOR . $file_name;
43 |
44 | try {
45 | if (move_uploaded_file($_FILES['file']['tmp_name'], $target_file)) {
46 | header('Access-Control-Allow-Origin: *');
47 | header('Content-type: application/json');
48 | $data = ['url' => $target_file, 'message' => 'The file ' . $file_name . ' has been uploaded.'];
49 | http_response_code(201);
50 | echo json_encode($data);
51 | } else {
52 | throw new Exception('Unable to move the uploaded file to its final location:' . $target_file);
53 | }
54 |
55 | } catch (\Throwable $th) {
56 | header('Access-Control-Allow-Origin: *');
57 | header('Content-type: application/json');
58 | $data = ['message' => 'Sorry, there was an error uploading your file.', 'error' => $th->getMessage()];
59 | http_response_code(400);
60 | echo json_encode($data);
61 | }
62 | } else {
63 | header('Access-Control-Allow-Origin: *');
64 | header('Content-type: application/json');
65 | $data = ['message' => 'Please upload a file.'];
66 | http_response_code(400);
67 | echo json_encode($data);
68 | }
69 |
--------------------------------------------------------------------------------
/axamples/vue3/src/App.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
Welcome to petProj Vue Demo!
9 |
Inline Dashboard
10 |
11 | {
16 | showInlineDashboard = event.target.checked
17 | }
18 | "
19 | />
20 | Show Dashboard
21 |
22 |
29 |
Modal Dashboard
30 |
31 | Show Dashboard
32 |
39 |
40 |
41 |
Drag Drop Area
42 |
53 |
54 |
Progress Bar
55 |
61 |
62 |
63 |
64 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
111 |
--------------------------------------------------------------------------------
/axamples/redux/main.js:
--------------------------------------------------------------------------------
1 | import { compose, combineReducers, applyMiddleware } from 'redux'
2 | import { configureStore } from '@reduxjs/toolkit'
3 | import logger from 'redux-logger'
4 | import petProj from '@petProj/core'
5 | import ReduxStore from '@petProj/store-redux'
6 | import * as petProjReduxStore from '@petProj/store-redux'
7 | import Dashboard from '@petProj/dashboard'
8 | import Tus from '@petProj/tus'
9 |
10 | import '@petProj/core/dist/style.css'
11 | import '@petProj/dashboard/dist/style.css'
12 |
13 | function counter (state = 0, action) {
14 | switch (action.type) {
15 | case 'INCREMENT':
16 | return state + 1
17 | case 'DECREMENT':
18 | return state - 1
19 | default:
20 | return state
21 | }
22 | }
23 |
24 | const reducer = combineReducers({
25 | counter,
26 | // You don't have to use the `petProj` key. But if you don't,
27 | // you need to provide a custom `selector` to the `petProjReduxStore` call below.
28 | petProj: petProjReduxStore.reducer,
29 | })
30 |
31 | let enhancer = applyMiddleware(
32 | petProjReduxStore.middleware(),
33 | logger,
34 | )
35 | if (typeof __REDUX_DEVTOOLS_EXTENSION__ !== 'undefined') {
36 | // eslint-disable-next-line no-undef
37 | enhancer = compose(enhancer, __REDUX_DEVTOOLS_EXTENSION__())
38 | }
39 |
40 | const store = configureStore({
41 | reducer,
42 | enhancers: [enhancer],
43 | middleware: (getDefaultMiddleware) => getDefaultMiddleware({
44 | serializableCheck: {
45 | ignoredActions: [petProjReduxStore.STATE_UPDATE],
46 | ignoreState: true,
47 | },
48 | }),
49 | })
50 |
51 | // Counter example from https://github.com/reactjs/redux/blob/master/examples/counter-vanilla/index.html
52 | const valueEl = document.querySelector('#value')
53 |
54 | function getCounter () { return store.getState().counter }
55 | function render () {
56 | valueEl.innerHTML = getCounter().toString()
57 | }
58 | render()
59 | store.subscribe(render)
60 |
61 | document.querySelector('#increment').onclick = () => {
62 | store.dispatch({ type: 'INCREMENT' })
63 | }
64 | document.querySelector('#decrement').onclick = () => {
65 | store.dispatch({ type: 'DECREMENT' })
66 | }
67 | document.querySelector('#incrementIfOdd').onclick = () => {
68 | if (getCounter() % 2 !== 0) {
69 | store.dispatch({ type: 'INCREMENT' })
70 | }
71 | }
72 | document.querySelector('#incrementAsync').onclick = () => {
73 | setTimeout(() => store.dispatch({ type: 'INCREMENT' }), 1000)
74 | }
75 |
76 | // petProj using the same store
77 | const petProj = new petProj({
78 | id: 'redux',
79 | store: new ReduxStore({ store }),
80 | // If we had placed our `reducer` elsewhere in Redux, eg. under an `petProj` key in the state for a profile page,
81 | // we'd do something like:
82 | //
83 | // store: new ReduxStore({
84 | // store: store,
85 | // id: 'avatar',
86 | // selector: state => state.pages.profile.petProj
87 | // }),
88 | debug: true,
89 | })
90 | petProj.use(Dashboard, {
91 | target: '#app',
92 | inline: true,
93 | width: 400,
94 | })
95 | petProj.use(Tus, { endpoint: 'https://tusd.tusdemo.net/files/' })
96 |
--------------------------------------------------------------------------------
/axamples/vue/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Welcome to petProj Vue Demo!
4 |
Inline Dashboard
5 |
6 | {
11 | showInlineDashboard = event.target.checked
12 | }
13 | "
14 | />
15 | Show Dashboard
16 |
17 |
24 |
Modal Dashboard
25 |
26 | Show Dashboard
27 |
34 |
35 |
36 |
Drag Drop Area
37 |
48 |
49 |
Progress Bar
50 |
56 |
57 |
58 |
59 |
97 |
98 |
99 |
100 |
101 |
102 |
112 |
--------------------------------------------------------------------------------
/axamples/angular-example/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "angular-example": {
7 | "projectType": "application",
8 | "schematics": {},
9 | "root": "",
10 | "sourceRoot": "src",
11 | "prefix": "app",
12 | "architect": {
13 | "build": {
14 | "builder": "@angular-devkit/build-angular:browser",
15 | "options": {
16 | "outputPath": "dist/angular-example",
17 | "index": "src/index.html",
18 | "main": "src/main.ts",
19 | "polyfills": ["zone.js"],
20 | "tsConfig": "tsconfig.app.json",
21 | "assets": ["src/favicon.ico", "src/assets"],
22 | "styles": ["src/styles.css"],
23 | "scripts": []
24 | },
25 | "configurations": {
26 | "production": {
27 | "budgets": [
28 | {
29 | "type": "initial",
30 | "maximumWarning": "500kb",
31 | "maximumError": "1mb"
32 | },
33 | {
34 | "type": "anyComponentStyle",
35 | "maximumWarning": "2kb",
36 | "maximumError": "4kb"
37 | }
38 | ],
39 | "outputHashing": "all"
40 | },
41 | "development": {
42 | "buildOptimizer": false,
43 | "optimization": false,
44 | "vendorChunk": true,
45 | "extractLicenses": false,
46 | "sourceMap": true,
47 | "namedChunks": true
48 | }
49 | },
50 | "defaultConfiguration": "production"
51 | },
52 | "serve": {
53 | "builder": "@angular-devkit/build-angular:dev-server",
54 | "configurations": {
55 | "production": {
56 | "browserTarget": "angular-example:build:production"
57 | },
58 | "development": {
59 | "browserTarget": "angular-example:build:development"
60 | }
61 | },
62 | "defaultConfiguration": "development"
63 | },
64 | "extract-i18n": {
65 | "builder": "@angular-devkit/build-angular:extract-i18n",
66 | "options": {
67 | "browserTarget": "angular-example:build"
68 | }
69 | },
70 | "test": {
71 | "builder": "@angular-devkit/build-angular:karma",
72 | "options": {
73 | "polyfills": ["zone.js", "zone.js/testing"],
74 | "tsConfig": "tsconfig.spec.json",
75 | "assets": ["src/favicon.ico", "src/assets"],
76 | "styles": ["src/styles.css"],
77 | "scripts": []
78 | }
79 | },
80 | "lint": {
81 | "builder": "@angular-eslint/builder:lint",
82 | "options": {
83 | "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
84 | }
85 | }
86 | }
87 | }
88 | },
89 | "cli": {
90 | "schematicCollections": ["@angular-eslint/schematics"]
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | # Clone this file to `.env` and edit the clone.
2 |
3 | NODE_ENV=development
4 |
5 | # Companion
6 | # =======================
7 | COMPANION_DATADIR=./output
8 | COMPANION_DOMAIN=localhost:3020
9 | COMPANION_PROTOCOL=http
10 | COMPANION_PORT=3020
11 | COMPANION_CLIENT_ORIGINS=
12 | COMPANION_SECRET=development
13 | COMPANION_PREAUTH_SECRET=development2
14 |
15 | # NOTE: Only enable this in development. Enabling it in production is a security risk
16 | COMPANION_ALLOW_LOCAL_URLS=true
17 |
18 | # to enable S3
19 | COMPANION_AWS_KEY="YOUR AWS KEY"
20 | COMPANION_AWS_SECRET="YOUR AWS SECRET"
21 | # specifying a secret file will override a directly set secret
22 | # COMPANION_AWS_SECRET_FILE="PATH/TO/AWS/SECRET/FILE"
23 | COMPANION_AWS_BUCKET="YOUR AWS S3 BUCKET"
24 | COMPANION_AWS_REGION="AWS REGION"
25 | COMPANION_AWS_PREFIX="OPTIONAL PREFIX"
26 | # to enable S3 Transfer Acceleration (default: false)
27 | # COMPANION_AWS_USE_ACCELERATE_ENDPOINT="false"
28 | # to set X-Amz-Expires query param in presigned urls (in seconds, default: 800)
29 | # COMPANION_AWS_EXPIRES="800"
30 | # to set a canned ACL for uploaded objects: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl
31 | # COMPANION_AWS_ACL="public-read"
32 |
33 | COMPANION_BOX_KEY=***
34 | COMPANION_BOX_SECRET=***
35 |
36 | COMPANION_DROPBOX_KEY=***
37 | COMPANION_DROPBOX_SECRET=***
38 |
39 | COMPANION_GOOGLE_KEY=***
40 | COMPANION_GOOGLE_SECRET=***
41 |
42 | COMPANION_INSTAGRAM_KEY=***
43 | COMPANION_INSTAGRAM_SECRET=***
44 |
45 | COMPANION_FACEBOOK_KEY=***
46 | COMPANION_FACEBOOK_SECRET=***
47 |
48 | COMPANION_ZOOM_KEY=***
49 | COMPANION_ZOOM_SECRET=***
50 |
51 | COMPANION_UNSPLASH_KEY=***
52 | COMPANION_UNSPLASH_SECRET=***
53 |
54 | COMPANION_ONEDRIVE_KEY=***
55 | COMPANION_ONEDRIVE_SECRET=****
56 |
57 | # To test dynamic Oauth against local companion (which is pointless but allows us to test it without Transloadit's servers), enable these:
58 | #COMPANION_GOOGLE_KEYS_ENDPOINT=http://localhost:3020/drive/test-dynamic-oauth-credentials?secret=development
59 | #COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS=true
60 | #COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS_SECRET=development
61 |
62 |
63 | # Development environment
64 | # =======================
65 |
66 | VITE_UPLOADER=tus
67 | # VITE_UPLOADER=s3
68 | # VITE_UPLOADER=s3-multipart
69 | # xhr will use protocol 'multipart' in companion, if used with a remote service, e.g. google drive.
70 | # If local upload will use browser XHR
71 | # VITE_UPLOADER=xhr
72 | # VITE_UPLOADER=transloadit
73 | # VITE_UPLOADER=transloadit-s3
74 | # VITE_UPLOADER=transloadit-xhr
75 |
76 | VITE_COMPANION_URL=http://localhost:3020
77 | # See also Transloadit.COMPANION_PATTERN
78 | VITE_COMPANION_ALLOWED_HOSTS="\.transloadit\.com$"
79 | VITE_TUS_ENDPOINT=https://tusd.tusdemo.net/files/
80 | VITE_XHR_ENDPOINT=https://xhr-server.herokuapp.com/upload
81 |
82 | # If you want to test dynamic Oauth
83 | # VITE_COMPANION_GOOGLE_DRIVE_KEYS_PARAMS_CREDENTIALS_NAME=companion-google-drive
84 |
85 | VITE_TRANSLOADIT_KEY=***
86 | VITE_TRANSLOADIT_TEMPLATE=***
87 | VITE_TRANSLOADIT_SERVICE_URL=https://api2.transloadit.com
88 | # Fill in if you want requests sent to Transloadit to be signed:
89 | # VITE_TRANSLOADIT_SECRET=***
90 |
--------------------------------------------------------------------------------
/BUNDLE-README.md:
--------------------------------------------------------------------------------
1 | # petProj
2 |
3 | Note that the recommended way to use petProj is to install it with yarn/npm and use a
4 | bundler like Webpack so that you can create a smaller custom build with only the
5 | things that you need. More info on .
6 |
7 | ## How to use this bundle
8 |
9 | You can extract the contents of this zip to directory, such as `./js/petProj`.
10 |
11 | create an HTML file, for example `./start.html`, with the following contents:
12 |
13 | ```html
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Upload
22 |
23 |
Uploaded files:
24 |
25 |
26 |
27 |
28 |
56 | ```
57 |
58 | Now open `start.html` in your browser, and the petProj Dashboard will appear.
59 |
60 | ## Next steps
61 |
62 | In the example you built, petProj uploads to a demo server shortly after uploading.
63 | You’ll want to target your own tusd server, S3 bucket, or Nginx/Apache server. For the latter, use the Xhr plugin: which uploads using regular multipart form posts, that you’ll existing Ruby or PHP backend will be able to make sense of, as if a ` ` had been used.
64 |
65 | The Dashboard now opens when clicking the button, but you can also draw it inline into the page. This, and many more configuration options can be found here: .
66 |
67 | petProj has many more Plugins besides Xhr and the Dashboard. For example, you can enable Webcam, Instagram, or video encoding support. For a full list of Plugins check here: .
68 |
69 | Note that for some Plugins, you will need to run a server side component called: Companion. Those plugins are marked with a (c) symbol. Alternatively, you can sign up for a free Transloadit account. Transloadit runs Companion for you, tusd servers to handle resumable file uploads, and can post-process files to scan for viruses, recognize faces, etc. Check: .
70 |
71 |
72 |
--------------------------------------------------------------------------------
/axamples/aws-nodejs/README.md:
--------------------------------------------------------------------------------
1 | # petProj + AWS S3 with Node.JS
2 |
3 | A simple and fully working example of petProj and AWS S3 storage with Node.js (and
4 | Express.js). It uses presigned URL at the backend level.
5 |
6 | ## AWS Configuration
7 |
8 | It's assumed that you are familiar with AWS, at least, with the storage service
9 | (S3) and users & policies (IAM).
10 |
11 | These instructions are **not fit for production** but tightening the security is
12 | out of the scope here.
13 |
14 | ### S3 Setup
15 |
16 | - Create new S3 bucket in AWS (e.g. `aws-nodejs`).
17 | - Add a bucket policy.
18 |
19 | ```json
20 | {
21 | "Version": "2012-10-17",
22 | "Statement": [
23 | {
24 | "Sid": "PublicAccess",
25 | "Effect": "Allow",
26 | "Principal": "*",
27 | "Action": "s3:GetObject",
28 | "Resource": "arn:aws:s3:::aws-nodejs/*"
29 | }
30 | ]
31 | }
32 | ```
33 |
34 | - Make the S3 bucket public.
35 | - Add CORS configuration.
36 |
37 | ```json
38 | [
39 | {
40 | "AllowedHeaders": ["*"],
41 | "AllowedMethods": ["GET", "PUT", "HEAD", "POST", "DELETE"],
42 | "AllowedOrigins": ["*"],
43 | "ExposeHeaders": []
44 | }
45 | ]
46 | ```
47 |
48 | ### AWS Credentials
49 |
50 | You may use existing AWS credentials or create a new user in the IAM page.
51 |
52 | - Make sure you setup the AWS credentials properly and write down the Access Key
53 | ID and Secret Access Key.
54 | - You may configure AWS S3 credentials using
55 | [environment variables](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html)
56 | or a
57 | [credentials file in `~/.aws/credentials`](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html).
58 | - You will need at least `PutObject` and `PutObjectAcl` permissions.
59 |
60 | ```json
61 | {
62 | "Version": "2012-10-17",
63 | "Statement": [
64 | {
65 | "Sid": "VisualEditor0",
66 | "Effect": "Allow",
67 | "Action": ["s3:PutObject", "s3:PutObjectAcl"],
68 | "Resource": "arn:aws:s3:::aws-nodejs/*"
69 | }
70 | ]
71 | }
72 | ```
73 |
74 | ## Prerequisites
75 |
76 | Download this code or clone repository into a folder and install dependencies:
77 |
78 | ```sh
79 | CYPRESS_INSTALL_BINARY=0 corepack yarn install
80 | ```
81 |
82 | Add a `.env` file to the root directory and define the S3 bucket name and port
83 | variables like the example below:
84 |
85 | ```
86 | COMPANION_AWS_BUCKET=aws-nodejs
87 | COMPANION_AWS_REGION=…
88 | COMPANION_AWS_KEY=…
89 | COMPANION_AWS_SECRET=…
90 | PORT=8080
91 | ```
92 |
93 | N.B.: This example uses `COMPANION_AWS_` environnement variables to facilitate
94 | integrations with other examples in this repository, but this example does _not_
95 | uses Companion at all.
96 |
97 | ## Enjoy it
98 |
99 | Start the application:
100 |
101 | ```sh
102 | corepack yarn workspace @petProj-example/aws-nodejs start
103 | ```
104 |
105 | Dashboard demo should now be available at http://localhost:8080.
106 |
107 | You have also a Drag & Drop demo on http://localhost:8080/drag.
108 |
109 | _Feel free to check how the demo works and feel free to open an issue._
110 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/FileList.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { StyleSheet, View, FlatList, Text, Image } from 'react-native'
3 |
4 | import getFileTypeIcon from '@petProj/dashboard/lib/utils/getFileTypeIcon.js'
5 | import renderStringFromJSX from 'preact-render-to-string'
6 |
7 | const fileIcon = require('./assets/file-icon.png')
8 |
9 | const truncateString = (str) => {
10 | const maxChars = 20
11 | if (str.length > maxChars) {
12 | return `${str.substring(0, 25)}...`
13 | }
14 |
15 | return str
16 | }
17 |
18 | function FileIcon () {
19 | return (
20 |
21 |
25 |
26 | )
27 | }
28 |
29 | function petProjDashboardFileIcon ({ type }) {
30 | const icon = renderStringFromJSX(getFileTypeIcon(type).icon)
31 | if (!icon) {
32 | return
33 | }
34 | const { color } = getFileTypeIcon(type)
35 | return (
36 |
42 | logo
43 |
44 | )
45 | }
46 |
47 | export default function FileList ({ petProj }) {
48 | const petProjFiles = petProj.store.state.files
49 | const petProjFilesArray = Object.keys(petProjFiles).map((id) => petProjFiles[id])
50 |
51 | return (
52 |
53 | item.id}
56 | numColumns={2}
57 | renderItem={({ item }) => {
58 | return (
59 |
60 | {item.type === 'image' ? (
61 |
65 | ) : (
66 |
67 | )}
68 | {truncateString(item.name, 20)}
69 | {item.type}
70 |
71 | )
72 | }}
73 | />
74 |
75 | )
76 | }
77 |
78 | const styles = StyleSheet.create({
79 | container: {
80 | marginTop: 20,
81 | marginBottom: 20,
82 | flex: 1,
83 | justifyContent: 'center',
84 | alignItems:'center',
85 | marginRight: -25,
86 | },
87 | item: {
88 | width: 100,
89 | marginTop: 5,
90 | marginBottom: 15,
91 | marginRight: 25,
92 | },
93 | itemImage: {
94 | width: 100,
95 | height: 100,
96 | borderRadius: 5,
97 | marginBottom: 5,
98 | },
99 | itemIconContainer: {
100 | width: 100,
101 | height: 100,
102 | borderRadius: 5,
103 | marginBottom: 5,
104 | backgroundColor: '#cfd3d6',
105 | alignItems: 'center',
106 | justifyContent: 'center',
107 | },
108 | itemIcon: {
109 | width: 42,
110 | height: 56,
111 | },
112 | itemIconSVG: {
113 | width: 50,
114 | height: 50,
115 | },
116 | itemName: {
117 | fontSize: 13,
118 | color: '#2c3e50',
119 | fontWeight: '600',
120 | },
121 | itemType: {
122 | fontWeight: '600',
123 | fontSize: 12,
124 | color: '#95a5a6',
125 | },
126 | })
127 |
--------------------------------------------------------------------------------
/axamples/aws-nodejs/public/drag.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | petProj
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Uploaded files:
17 |
18 |
19 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/axamples/react-example/App.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React from'react'
3 | import petProj from'@petProj/core'
4 | import Tus from'@petProj/tus'
5 | import GoogleDrive from '@petProj/google-drive'
6 | import Webcam from '@petProj/webcam'
7 | import RemoteSources from '@petProj/remote-sources'
8 | import { Dashboard, DashboardModal, DragDrop, ProgressBar, FileInput } from'@petProj/react'
9 |
10 | import '@petProj/core/dist/style.css'
11 | import '@petProj/dashboard/dist/style.css'
12 | import '@petProj/drag-drop/dist/style.css'
13 | import '@petProj/file-input/dist/style.css'
14 | import '@petProj/progress-bar/dist/style.css'
15 |
16 | export default class App extends React.Component {
17 | constructor (props) {
18 | super(props)
19 |
20 | this.state = {
21 | showInlineDashboard: false,
22 | open: false
23 | }
24 |
25 | this.petProj = new petProj({ id: 'petProj1', autoProceed: true, debug: true })
26 | .use(Tus, { endpoint: 'https://tusd.tusdemo.net/files/' })
27 | .use(Webcam)
28 | .use(RemoteSources, { companionUrl: 'https://companion.petProj.io', sources: ['GoogleDrive', 'Box', 'Dropbox', 'Facebook', 'Instagram', 'OneDrive', 'Unsplash', 'Zoom', 'Url'],
29 | })
30 |
31 | this.petProj2 = new petProj({ id: 'petProj2', autoProceed: false, debug: true })
32 | .use(Tus, { endpoint: 'https://tusd.tusdemo.net/files/' })
33 |
34 | this.handleModalClick = this.handleModalClick.bind(this)
35 | }
36 |
37 | componentWillUnmount () {
38 | this.petProj.close({ reason: 'unmount' })
39 | this.petProj2.close({ reason: 'unmount' })
40 | }
41 |
42 | handleModalClick () {
43 | this.setState({
44 | open: !this.state.open
45 | })
46 | }
47 |
48 | render () {
49 | const { showInlineDashboard } = this.state
50 | return (
51 |
52 |
React Examples
53 |
54 |
Inline Dashboard
55 |
56 | {
60 | this.setState({
61 | showInlineDashboard: event.target.checked
62 | })
63 | }}
64 | />
65 | Show Dashboard
66 |
67 | {showInlineDashboard && (
68 |
75 | )}
76 |
77 |
Modal Dashboard
78 |
79 |
80 | {this.state.open ? 'Close dashboard' : 'Open dashboard'}
81 |
82 | this.setState({ open: false })}
87 | />
88 |
89 |
90 |
Drag Drop Area
91 |
100 |
101 |
Progress Bar
102 |
106 |
107 |
File Input
108 |
111 |
112 | )
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/axamples/transloadit/server.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /* eslint-disable compat/compat */
4 | import http from 'node:http'
5 | import qs from 'node:querystring'
6 | import he from 'he'
7 |
8 | const e = he.encode
9 |
10 | function Header () {
11 | return `
12 |
13 |
14 |
15 |
25 |
26 |
27 |
28 | `
29 | }
30 |
31 | function Footer () {
32 | return `
33 |
34 |
35 |
36 | `
37 | }
38 |
39 | function FormFields (fields) {
40 | function Field ([name, value]) {
41 | if (name === 'transloadit') return ''
42 | let isValueJSON = false
43 | if (value.startsWith('{') || value.startsWith('[')) {
44 | try {
45 | // eslint-disable-next-line no-param-reassign
46 | value = JSON.stringify(
47 | JSON.parse(value),
48 | null,
49 | 2,
50 | )
51 | isValueJSON = true
52 | } catch {
53 | // Nothing
54 | }
55 | }
56 |
57 | const prettyValue = isValueJSON ? `
58 |
59 |
60 | ${e(value)}
61 |
62 |
63 | ` : e(value)
64 |
65 | return `
66 | ${e(name)}
67 |
68 | ${prettyValue}
69 |
70 | `
71 | }
72 |
73 | return `
74 | Form Fields
75 |
76 | ${Object.entries(fields).map(Field).join('\n')}
77 |
78 | `
79 | }
80 |
81 | function UploadsList (uploads) {
82 | function Upload (upload) {
83 | return `${e(upload.name)} `
84 | }
85 |
86 | return `
87 |
88 | ${uploads.map(Upload).join('\n')}
89 |
90 | `
91 | }
92 |
93 | function ResultsList (results) {
94 | function Result (result) {
95 | return `${e(result.name)} View `
96 | }
97 |
98 | function ResultsSection (stepName) {
99 | return `
100 | ${e(stepName)}
101 |
102 | ${results[stepName].map(Result).join('\n')}
103 |
104 | `
105 | }
106 |
107 | return Object.keys(results)
108 | .map(ResultsSection)
109 | .join('\n')
110 | }
111 |
112 | function AssemblyResult (assembly) {
113 | return `
114 | ${e(assembly.assembly_id)} (${e(assembly.ok)})
115 | ${UploadsList(assembly.uploads)}
116 | ${ResultsList(assembly.results)}
117 | `
118 | }
119 |
120 | function onrequest (req, res) {
121 | if (req.url !== '/test') {
122 | res.writeHead(404, { 'content-type': 'text/html' })
123 | res.end('404')
124 | return
125 | }
126 |
127 | function onbody (body) {
128 | const fields = qs.parse(body)
129 | const result = JSON.parse(fields.petProjResult)
130 | const assemblies = result[0].transloadit
131 |
132 | res.setHeader('content-type', 'text/html')
133 | res.write(Header())
134 | res.write(FormFields(fields))
135 | assemblies.forEach((assembly) => {
136 | res.write(AssemblyResult(assembly))
137 | })
138 | res.end(Footer())
139 | }
140 |
141 | {
142 | let body = ''
143 | req.on('data', (chunk) => { body += chunk })
144 | req.on('end', () => {
145 | onbody(body)
146 | })
147 | }
148 | }
149 |
150 | /**
151 | * A very haxxor server that outputs some of the data it receives in a POST form parameter.
152 | */
153 |
154 | const server = http.createServer(onrequest)
155 | server.listen(9967)
156 |
--------------------------------------------------------------------------------
/axamples/transloadit-markdown-bin/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
115 |
116 |
117 |
120 |
121 |
122 | Markdown Bin is a demo app that works a bit like Github Gists or
123 | pastebin. You can add markdown snippets, and add file attachments to
124 | each snippet by clicking "Upload an attachment" or by dragging files
125 | onto the text area. Transloadit generates an inline preview image for
126 | images, videos, and audio files.
127 | » View the Assembly Template here.
132 |
133 |
134 |
135 | ⚠️ For this demo, snippets are stored locally in your browser.
136 | Attachments are stored in Transloadit's temporary storage and expire
137 | after about 24 hours. In a real app, you can easily export files to a
138 | permanent storage solution like Amazon S3 or Google Cloud.
139 | » Learn more
144 |
145 |
146 |
159 |
160 | Previous snippets
161 |
162 |
163 |
164 |
165 |
169 |
170 | This app requires JavaScript.
171 |
172 |
173 |
174 |
--------------------------------------------------------------------------------
/axamples/react-native-expo/App.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState, useCallback } from 'react'
2 | import { Text, View, Image, StyleSheet } from 'react-native'
3 | import AsyncStorage from '@react-native-async-storage/async-storage'
4 | import petProj from '@petProj/core'
5 | import Tus from '@petProj/tus'
6 | import FilePicker from '@petProj/react-native'
7 | import usepetProj from '@petProj/react/lib/usepetProj'
8 | import FileList from './FileList'
9 | import PauseResumeButton from './PauseResumeButton'
10 | import ProgressBar from './ProgressBar'
11 | import SelectFiles from './SelectFilesButton'
12 | import getTusFileReader from './tusFileReader'
13 |
14 | export default function App () {
15 | const [state, _setState] = useState({
16 | progress: 0,
17 | total: 0,
18 | file: null,
19 | uploadURL: null,
20 | isFilePickerVisible: false,
21 | isPaused: false,
22 | uploadStarted: false,
23 | uploadComplete: false,
24 | info: null,
25 | totalProgress: 0,
26 | })
27 |
28 | const setState = useCallback((newState) => _setState((oldState) => ({ ...oldState, ...newState })), [])
29 |
30 | const petProj = usepetProj(() => {
31 | return new petProj({ autoProceed: true, debug: true })
32 | .use(Tus, {
33 | endpoint: 'https://tusd.tusdemo.net/files/',
34 | urlStorage: AsyncStorage,
35 | fileReader: getTusFileReader,
36 | chunkSize: 10 * 1024 * 1024, // keep the chunk size small to avoid memory exhaustion
37 | })
38 | })
39 |
40 | useEffect(() => {
41 | petProj.on('upload-progress', (file, progress) => {
42 | setState({
43 | progress: progress.bytesUploaded,
44 | total: progress.bytesTotal,
45 | totalProgress: petProj.state.totalProgress,
46 | uploadStarted: true,
47 | })
48 | })
49 | petProj.on('upload-success', () => {
50 | // console.log(file.name, response)
51 | })
52 | petProj.on('complete', (result) => {
53 | setState({
54 | status: result.successful[0] ? 'Upload complete ✅' : 'Upload errored ❌',
55 | uploadURL: result.successful[0] ? result.successful[0].uploadURL : null,
56 | uploadComplete: true,
57 | uploadStarted: false,
58 | })
59 | console.log('Upload complete:', result)
60 | })
61 | petProj.on('info-visible', () => {
62 | const { info } = petProj.getState()
63 | setState({
64 | info,
65 | })
66 | console.log('petProj-info:', info)
67 | })
68 | petProj.on('info-hidden', () => {
69 | setState({
70 | info: null,
71 | })
72 | })
73 | }, [setState, petProj])
74 |
75 | const showFilePicker = () => {
76 | setState({
77 | isFilePickerVisible: true,
78 | uploadStarted: false,
79 | uploadComplete: false,
80 | })
81 | }
82 |
83 | const hideFilePicker = () => {
84 | setState({
85 | isFilePickerVisible: false,
86 | })
87 | }
88 |
89 | const togglePauseResume = () => {
90 | if (state.isPaused) {
91 | petProj.resumeAll()
92 | setState({
93 | isPaused: false,
94 | })
95 | } else {
96 | petProj.pauseAll()
97 | setState({
98 | isPaused: true,
99 | })
100 | }
101 | }
102 |
103 | return (
104 |
107 |
110 | petProj in React Native
111 |
112 |
113 |
118 |
119 |
120 |
121 | {state.info ? (
122 |
129 | {state.info.message}
130 |
131 | ) : null}
132 |
133 |
134 |
135 |
141 |
142 | {petProj && (
143 |
149 | )}
150 |
151 | {petProj && }
152 |
153 | {state.status && Status: {state.status} }
154 | {state.progress} of {state.total}
155 |
156 | )
157 | }
158 |
159 | const styles = StyleSheet.create({
160 | root: {
161 | paddingTop: 100,
162 | paddingBottom: 20,
163 | paddingLeft: 50,
164 | paddingRight: 50,
165 | flex: 1,
166 | },
167 | title: {
168 | fontSize: 25,
169 | marginBottom: 20,
170 | textAlign: 'center',
171 | },
172 | logo: { width: 80, height: 78, marginBottom: 50 },
173 | })
174 |
--------------------------------------------------------------------------------
/axamples/transloadit/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Transloadit Example
7 |
8 |
9 |
36 |
37 |
38 | petProj Transloadit
39 |
44 | playground
45 |
46 |
47 | This page contains small examples for different ways you can use petProj
48 | with Transloadit. Please see the
49 | Github repository
53 | for the source code.
54 |
55 |
56 | Form
57 |
58 |
59 | The form API allows you to easily send files through Transloadit’s
60 | encoding backend. When the user submits the form, any files are uploaded
61 | to Transloadit. The form data is then sent to your own backend, with
62 | additional data about the Transloadit Assemblies that were started.
63 |
64 |
65 | leave a message
66 |
67 | name:
69 |
70 |
71 |
72 |
73 | message:
75 |
76 |
77 |
78 |
79 |
80 | attachments:
81 |
82 |
83 | Select Files
84 |
85 |
86 |
87 |
88 | Upload
89 |
90 |
91 |
92 |
93 |
94 | Form with inline Dashboard
95 |
96 | You can also use the Dashboard UI inside a plain old HTML form.
97 |
102 | leave a message
103 |
104 | name:
106 |
107 |
108 |
109 |
110 | message:
112 |
113 |
114 |
115 |
116 |
117 | attachments:
118 |
119 |
120 |
121 |
122 | Upload
123 |
124 |
125 |
126 |
127 |
128 | Inline Dashboard
129 |
130 | The robodog.dashboard API allows you to embed a Dashboard
131 | at any location. Users can continuously upload files through this UI, so
132 | please make sure this fits your use case!
133 |
134 |
135 |
136 |
137 | Dashboard Modal
138 |
139 |
140 | This API is a one-shot upload UI using a modal overlay. Call the
141 | function and receive a listen to an event with upload results ✌️
142 |
143 | Open
144 |
145 | petProj.upload()
146 | An <input type=file> backed by petProj.upload():
147 |
148 |
149 |
150 |
151 |
152 |
153 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/axamples/transloadit-markdown-bin/main.js:
--------------------------------------------------------------------------------
1 | import { marked } from 'marked'
2 | import petProj from '@petProj/core'
3 | import DropTarget from '@petProj/drop-target'
4 | import Dashboard from '@petProj/dashboard'
5 | import Transloadit from '@petProj/transloadit'
6 | import RemoteSources from '@petProj/remote-sources'
7 | import Webcam from '@petProj/webcam'
8 | import ImageEditor from '@petProj/image-editor'
9 |
10 | import '@petProj/core/dist/style.css'
11 | import '@petProj/dashboard/dist/style.css'
12 | import '@petProj/image-editor/dist/style.css'
13 |
14 | const TRANSLOADIT_EXAMPLE_KEY = '35c1aed03f5011e982b6afe82599b6a0'
15 | const TRANSLOADIT_EXAMPLE_TEMPLATE = '0b2ee2bc25dc43619700c2ce0a75164a'
16 |
17 | function matchFilesAndThumbs (results) {
18 | const filesById = {}
19 | const thumbsById = {}
20 |
21 | for (const [stepName, result] of Object.entries(results)) {
22 | // eslint-disable-next-line no-shadow
23 | result.forEach(result => {
24 | if (stepName === 'thumbnails') {
25 | thumbsById[result.original_id] = result
26 | } else {
27 | filesById[result.original_id] = result
28 | }
29 | })
30 | }
31 |
32 | return Object.keys(filesById).map((key) => ({
33 | file: filesById[key],
34 | thumb: thumbsById[key],
35 | }))
36 | }
37 |
38 | /**
39 | * A textarea for markdown text, with support for file attachments.
40 | */
41 | class MarkdownTextarea {
42 | constructor (element) {
43 | this.element = element
44 | this.controls = document.createElement('div')
45 | this.controls.classList.add('mdtxt-controls')
46 | this.uploadLine = document.createElement('button')
47 | this.uploadLine.setAttribute('type', 'button')
48 | this.uploadLine.classList.add('form-upload')
49 |
50 | this.uploadLine.appendChild(
51 | document.createTextNode('Tap here to upload an attachment'),
52 | )
53 | }
54 |
55 | install () {
56 | const { element } = this
57 | const wrapper = document.createElement('div')
58 | wrapper.classList.add('mdtxt')
59 | element.parentNode.replaceChild(wrapper, element)
60 | wrapper.appendChild(this.controls)
61 | wrapper.appendChild(element)
62 | wrapper.appendChild(this.uploadLine)
63 |
64 | this.setuppetProj()
65 | }
66 |
67 | setuppetProj = () => {
68 | this.petProj = new petProj({ autoProceed: true })
69 | .use(Transloadit, {
70 | waitForEncoding: true,
71 | params: {
72 | auth: { key: TRANSLOADIT_EXAMPLE_KEY },
73 | template_id: TRANSLOADIT_EXAMPLE_TEMPLATE,
74 | },
75 | })
76 | .use(DropTarget, { target: this.element })
77 | .use(Dashboard, { closeAfterFinish: true, trigger: '.form-upload' })
78 | .use(ImageEditor, { target: Dashboard })
79 | .use(Webcam, { target: Dashboard })
80 | .use(RemoteSources, { companionUrl: Transloadit.COMPANION })
81 |
82 | this.petProj.on('complete', (result) => {
83 | const { successful, failed, transloadit } = result
84 | if (successful.length !== 0) {
85 | this.insertAttachments(
86 | matchFilesAndThumbs(transloadit[0].results),
87 | )
88 | } else {
89 | failed.forEach(error => {
90 | console.error(error)
91 | this.reportUploadError(error)
92 | })
93 | }
94 | this.petProj.cancelAll()
95 | })
96 | }
97 |
98 | reportUploadError (err) {
99 | this.uploadLine.classList.add('error')
100 | const message = document.createElement('span')
101 | message.appendChild(document.createTextNode(err.message))
102 | this.uploadLine.insertChild(message, this.uploadLine.firstChild)
103 | }
104 |
105 | unreportUploadError () {
106 | this.uploadLine.classList.remove('error')
107 | const message = this.uploadLine.querySelector('message')
108 | if (message) {
109 | this.uploadLine.removeChild(message)
110 | }
111 | }
112 |
113 | insertAttachments (attachments) {
114 | attachments.forEach((attachment) => {
115 | const { file, thumb } = attachment
116 | const link = `\n[LABEL](${file.ssl_url})\n`
117 | const labelText = `View File ${file.basename}`
118 | if (thumb) {
119 | this.element.value += link.replace('LABEL', ``)
120 | } else {
121 | this.element.value += link.replace('LABEL', labelText)
122 | }
123 | })
124 | }
125 |
126 | uploadFiles = (files) => {
127 | const filesForpetProj = files.map(file => {
128 | return {
129 | data: file,
130 | type: file.type,
131 | name: file.name,
132 | meta: file.meta || {},
133 | }
134 | })
135 | this.petProj.addFiles(filesForpetProj)
136 | }
137 | }
138 |
139 | const textarea = new MarkdownTextarea(document.querySelector('#new textarea'))
140 | textarea.install()
141 |
142 | function renderSnippet (title, text) {
143 | const template = document.querySelector('#snippet')
144 | const newSnippet = document.importNode(template.content, true)
145 | const titleEl = newSnippet.querySelector('.snippet-title')
146 | const contentEl = newSnippet.querySelector('.snippet-content')
147 |
148 | titleEl.appendChild(document.createTextNode(title))
149 | contentEl.innerHTML = marked(text)
150 |
151 | const list = document.querySelector('#snippets')
152 | list.insertBefore(newSnippet, list.firstChild)
153 | }
154 |
155 | function saveSnippet (title, text) {
156 | const id = parseInt(localStorage.numSnippets || 0, 10)
157 | localStorage[`snippet_${id}`] = JSON.stringify({ title, text })
158 | localStorage.numSnippets = id + 1
159 | }
160 |
161 | function loadSnippets () {
162 | for (let id = 0; localStorage[`snippet_${id}`] != null; id += 1) {
163 | const { title, text } = JSON.parse(localStorage[`snippet_${id}`])
164 | renderSnippet(title, text)
165 | }
166 | }
167 |
168 | document.querySelector('#new').addEventListener('submit', (event) => {
169 | event.preventDefault()
170 |
171 | const title = event.target.elements['title'].value
172 | || 'Unnamed Snippet'
173 | const text = textarea.element.value
174 |
175 | saveSnippet(title, text)
176 | renderSnippet(title, text)
177 |
178 | // eslint-disable-next-line no-param-reassign
179 | event.target.querySelector('input').value = ''
180 | // eslint-disable-next-line no-param-reassign
181 | event.target.querySelector('textarea').value = ''
182 | })
183 |
184 | window.addEventListener('DOMContentLoaded', loadSnippets, { once: true })
185 |
--------------------------------------------------------------------------------
/axamples/transloadit/main.js:
--------------------------------------------------------------------------------
1 | import Transloadit, { COMPANION_URL } from '@petProj/transloadit'
2 | import petProj from '@petProj/core'
3 | import Form from '@petProj/form'
4 | import Dashboard from '@petProj/dashboard'
5 | import RemoteSources from '@petProj/remote-sources'
6 | import ImageEditor from '@petProj/image-editor'
7 | import Webcam from '@petProj/webcam'
8 | import ProgressBar from '@petProj/progress-bar'
9 |
10 | import '@petProj/core/dist/style.css'
11 | import '@petProj/dashboard/dist/style.css'
12 | import '@petProj/image-editor/dist/style.css'
13 | import '@petProj/progress-bar/dist/style.css'
14 |
15 | const TRANSLOADIT_KEY = '35c1aed03f5011e982b6afe82599b6a0'
16 | // A trivial template that resizes images, just for example purposes.
17 | //
18 | // "steps": {
19 | // ":original": { "robot": "/upload/handle" },
20 | // "resize": {
21 | // "use": ":original",
22 | // "robot": "/image/resize",
23 | // "width": 100,
24 | // "height": 100,
25 | // "imagemagick_stack": "v1.0.0"
26 | // }
27 | // }
28 | const TEMPLATE_ID = 'bbc273f69e0c4694a5a9d1b587abc1bc'
29 |
30 | /**
31 | * Form
32 | */
33 |
34 | const formpetProj = new petProj({
35 | debug: true,
36 | autoProceed: true,
37 | restrictions: {
38 | allowedFileTypes: ['.png'],
39 | },
40 | })
41 | .use(Dashboard, {
42 | trigger: '#petProj-select-files',
43 | closeAfterFinish: true,
44 | note: 'Only PNG files please!',
45 | })
46 | .use(RemoteSources, { companionUrl: COMPANION_URL })
47 | .use(Form, {
48 | target: '#test-form',
49 | fields: ['message'],
50 | // submitOnSuccess: true,
51 | addResultToForm: true,
52 | })
53 | .use(Transloadit, {
54 | waitForEncoding: true,
55 | params: {
56 | auth: { key: TRANSLOADIT_KEY },
57 | template_id: TEMPLATE_ID,
58 | },
59 | })
60 |
61 | formpetProj.on('error', (err) => {
62 | document.querySelector('#test-form .error')
63 | .textContent = err.message
64 | })
65 |
66 | formpetProj.on('upload-error', (file, err) => {
67 | document.querySelector('#test-form .error')
68 | .textContent = err.message
69 | })
70 |
71 | formpetProj.on('complete', ({ transloadit }) => {
72 | const btn = document.getElementById('petProj-select-files')
73 | btn.hidden = true
74 | const selectedFiles = document.getElementById('petProj-form-selected-files')
75 | selectedFiles.textContent = `selected files: ${Object.keys(transloadit[0].results).length}`
76 | })
77 |
78 | window.formpetProj = formpetProj
79 |
80 | /**
81 | * Form with Dashboard
82 | */
83 |
84 | const formpetProjWithDashboard = new petProj({
85 | debug: true,
86 | autoProceed: false,
87 | restrictions: {
88 | allowedFileTypes: ['.png'],
89 | },
90 | })
91 | .use(Dashboard, {
92 | inline: true,
93 | target: '#dashboard-form .dashboard',
94 | note: 'Only PNG files please!',
95 | hideUploadButton: true,
96 | })
97 | .use(RemoteSources, { companionUrl: COMPANION_URL })
98 | .use(Form, {
99 | target: '#dashboard-form',
100 | fields: ['message'],
101 | triggerUploadOnSubmit: true,
102 | submitOnSuccess: true,
103 | addResultToForm: true,
104 | })
105 | .use(Transloadit, {
106 | waitForEncoding: true,
107 | params: {
108 | auth: { key: TRANSLOADIT_KEY },
109 | template_id: TEMPLATE_ID,
110 | },
111 | })
112 |
113 | window.formpetProjWithDashboard = formpetProjWithDashboard
114 |
115 | /**
116 | * Dashboard
117 | */
118 |
119 | const dashboard = new petProj({
120 | debug: true,
121 | autoProceed: false,
122 | restrictions: {
123 | allowedFileTypes: ['.png'],
124 | },
125 | })
126 | .use(Dashboard, {
127 | inline: true,
128 | target: '#dashboard',
129 | note: 'Only PNG files please!',
130 | })
131 | .use(RemoteSources, { companionUrl: COMPANION_URL })
132 | .use(Webcam, { target: Dashboard })
133 | .use(ImageEditor, { target: Dashboard })
134 | .use(Transloadit, {
135 | waitForEncoding: true,
136 | params: {
137 | auth: { key: TRANSLOADIT_KEY },
138 | template_id: TEMPLATE_ID,
139 | },
140 | })
141 |
142 | window.dashboard = dashboard
143 |
144 | // /**
145 | // * Dashboard Modal
146 | // */
147 |
148 | const dashboardModal = new petProj({
149 | debug: true,
150 | autoProceed: false,
151 | })
152 | .use(Dashboard, { closeAfterFinish: true })
153 | .use(RemoteSources, { companionUrl: COMPANION_URL })
154 | .use(Webcam, { target: Dashboard })
155 | .use(ImageEditor, { target: Dashboard })
156 | .use(Transloadit, {
157 | waitForEncoding: true,
158 | params: {
159 | auth: { key: TRANSLOADIT_KEY },
160 | template_id: TEMPLATE_ID,
161 | },
162 | })
163 |
164 | dashboardModal.on('complete', ({ transloadit, successful, failed }) => {
165 | if (failed?.length !== 0) {
166 | // eslint-disable-next-line no-console
167 | console.error('it failed', failed)
168 | } else {
169 | // eslint-disable-next-line no-console
170 | console.log('success', { transloadit, successful })
171 | }
172 | })
173 |
174 | function openModal () {
175 | dashboardModal.getPlugin('Dashboard').openModal()
176 | }
177 |
178 | window.openModal = openModal
179 |
180 | // /**
181 | // * petProj.upload (files come from input[type=file])
182 | // */
183 |
184 | const petProjWithoutUI = new petProj({
185 | debug: true,
186 | restrictions: {
187 | allowedFileTypes: ['.png'],
188 | },
189 | })
190 | .use(Transloadit, {
191 | waitForEncoding: true,
192 | params: {
193 | auth: { key: TRANSLOADIT_KEY },
194 | template_id: TEMPLATE_ID,
195 | },
196 | })
197 | .use(ProgressBar, { target: '#upload-progress' })
198 |
199 | window.doUpload = (event) => {
200 | const resultEl = document.querySelector('#upload-result')
201 | const errorEl = document.querySelector('#upload-error')
202 |
203 | petProjWithoutUI.addFiles(event.target.files)
204 | petProjWithoutUI.upload()
205 |
206 | petProjWithoutUI.on('complete', ({ transloadit }) => {
207 | resultEl.classList.remove('hidden')
208 | errorEl.classList.add('hidden')
209 | resultEl.textContent = JSON.stringify(transloadit[0].results, null, 2)
210 |
211 | const resizedUrl = transloadit[0].results['resize'][0]['ssl_url']
212 | const img = document.createElement('img')
213 | img.src = resizedUrl
214 | document.getElementById('upload-result-image').appendChild(img)
215 | })
216 |
217 | petProjWithoutUI.on('error', (err) => {
218 | resultEl.classList.add('hidden')
219 | errorEl.classList.remove('hidden')
220 | errorEl.textContent = err.message
221 | })
222 | }
223 |
--------------------------------------------------------------------------------
/axamples/aws-nodejs/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const path = require('node:path')
4 | const crypto = require('node:crypto')
5 | require('dotenv').config({ path: path.join(__dirname, '..', '..', '.env') })
6 |
7 | const express = require('express')
8 |
9 | const app = express()
10 |
11 | const port = process.env.PORT ?? 8080
12 | const bodyParser = require('body-parser')
13 |
14 | const {
15 | S3Client,
16 | AbortMultipartUploadCommand,
17 | CompleteMultipartUploadCommand,
18 | CreateMultipartUploadCommand,
19 | ListPartsCommand,
20 | PutObjectCommand,
21 | UploadPartCommand,
22 | } = require('@aws-sdk/client-s3')
23 | const { getSignedUrl } = require('@aws-sdk/s3-request-presigner')
24 | const {
25 | STSClient,
26 | GetFederationTokenCommand,
27 | } = require('@aws-sdk/client-sts')
28 |
29 | const policy = {
30 | Version: '2012-10-17',
31 | Statement: [
32 | {
33 | Effect: 'Allow',
34 | Action: [
35 | 's3:PutObject',
36 | ],
37 | Resource: [
38 | `arn:aws:s3:::${process.env.COMPANION_AWS_BUCKET}/*`,
39 | `arn:aws:s3:::${process.env.COMPANION_AWS_BUCKET}`,
40 | ],
41 | },
42 | ],
43 | }
44 |
45 | /**
46 | * @type {S3Client}
47 | */
48 | let s3Client
49 |
50 | /**
51 | * @type {STSClient}
52 | */
53 | let stsClient
54 |
55 | const expiresIn = 900 // Define how long until a S3 signature expires.
56 |
57 | function getS3Client () {
58 | s3Client ??= new S3Client({
59 | region: process.env.COMPANION_AWS_REGION,
60 | credentials : {
61 | accessKeyId: process.env.COMPANION_AWS_KEY,
62 | secretAccessKey: process.env.COMPANION_AWS_SECRET,
63 | },
64 | })
65 | return s3Client
66 | }
67 |
68 | function getSTSClient () {
69 | stsClient ??= new STSClient({
70 | region: process.env.COMPANION_AWS_REGION,
71 | credentials : {
72 | accessKeyId: process.env.COMPANION_AWS_KEY,
73 | secretAccessKey: process.env.COMPANION_AWS_SECRET,
74 | },
75 | })
76 | return stsClient
77 | }
78 |
79 | app.use(bodyParser.urlencoded({ extended: true }), bodyParser.json())
80 |
81 | app.get('/', (req, res) => {
82 | const htmlPath = path.join(__dirname, 'public', 'index.html')
83 | res.sendFile(htmlPath)
84 | })
85 |
86 | app.get('/drag', (req, res) => {
87 | const htmlPath = path.join(__dirname, 'public', 'drag.html')
88 | res.sendFile(htmlPath)
89 | })
90 |
91 | app.get('/sts', (req, res, next) => {
92 | getSTSClient().send(new GetFederationTokenCommand({
93 | Name: '123user',
94 | // The duration, in seconds, of the role session. The value specified
95 | // can range from 900 seconds (15 minutes) up to the maximum session
96 | // duration set for the role.
97 | DurationSeconds: expiresIn,
98 | Policy: JSON.stringify(policy),
99 | })).then(response => {
100 | // Test creating multipart upload from the server — it works
101 | // createMultipartUploadYo(response)
102 | res.setHeader('Access-Control-Allow-Origin', '*')
103 | res.setHeader('Cache-Control', `public,max-age=${expiresIn}`)
104 | res.json({
105 | credentials: response.Credentials,
106 | bucket: process.env.COMPANION_AWS_BUCKET,
107 | region: process.env.COMPANION_AWS_REGION,
108 | })
109 | }, next)
110 | })
111 | app.post('/sign-s3', (req, res, next) => {
112 | const Key = `${crypto.randomUUID()}-${req.body.filename}`
113 | const { contentType } = req.body
114 |
115 | getSignedUrl(getS3Client(), new PutObjectCommand({
116 | Bucket: process.env.COMPANION_AWS_BUCKET,
117 | Key,
118 | ContentType: contentType,
119 | }), { expiresIn }).then((url) => {
120 | res.setHeader('Access-Control-Allow-Origin', '*')
121 | res.json({
122 | url,
123 | method: 'PUT',
124 | })
125 | res.end()
126 | }, next)
127 | })
128 |
129 | // === ===
130 | // You can remove those endpoints if you only want to support the non-multipart uploads.
131 |
132 | app.post('/s3/multipart', (req, res, next) => {
133 | const client = getS3Client()
134 | const { type, metadata, filename } = req.body
135 | if (typeof filename !== 'string') {
136 | return res.status(400).json({ error: 's3: content filename must be a string' })
137 | }
138 | if (typeof type !== 'string') {
139 | return res.status(400).json({ error: 's3: content type must be a string' })
140 | }
141 | const Key = `${crypto.randomUUID()}-${filename}`
142 |
143 | const params = {
144 | Bucket: process.env.COMPANION_AWS_BUCKET,
145 | Key,
146 | ContentType: type,
147 | Metadata: metadata,
148 | }
149 |
150 | const command = new CreateMultipartUploadCommand(params)
151 |
152 | return client.send(command, (err, data) => {
153 | if (err) {
154 | next(err)
155 | return
156 | }
157 | res.setHeader('Access-Control-Allow-Origin', '*')
158 | res.json({
159 | key: data.Key,
160 | uploadId: data.UploadId,
161 | })
162 | })
163 | })
164 |
165 | function validatePartNumber (partNumber) {
166 | // eslint-disable-next-line no-param-reassign
167 | partNumber = Number(partNumber)
168 | return Number.isInteger(partNumber) && partNumber >= 1 && partNumber <= 10_000
169 | }
170 | app.get('/s3/multipart/:uploadId/:partNumber', (req, res, next) => {
171 | const { uploadId, partNumber } = req.params
172 | const { key } = req.query
173 |
174 | if (!validatePartNumber(partNumber)) {
175 | return res.status(400).json({ error: 's3: the part number must be an integer between 1 and 10000.' })
176 | }
177 | if (typeof key !== 'string') {
178 | return res.status(400).json({ error: 's3: the object key must be passed as a query parameter. For example: "?key=abc.jpg"' })
179 | }
180 |
181 | return getSignedUrl(getS3Client(), new UploadPartCommand({
182 | Bucket: process.env.COMPANION_AWS_BUCKET,
183 | Key: key,
184 | UploadId: uploadId,
185 | PartNumber: partNumber,
186 | Body: '',
187 | }), { expiresIn }).then((url) => {
188 | res.setHeader('Access-Control-Allow-Origin', '*')
189 | res.json({ url, expires: expiresIn })
190 | }, next)
191 | })
192 |
193 | app.get('/s3/multipart/:uploadId', (req, res, next) => {
194 | const client = getS3Client()
195 | const { uploadId } = req.params
196 | const { key } = req.query
197 |
198 | if (typeof key !== 'string') {
199 | res.status(400).json({ error: 's3: the object key must be passed as a query parameter. For example: "?key=abc.jpg"' })
200 | return
201 | }
202 |
203 | const parts = []
204 |
205 | function listPartsPage (startAt) {
206 | client.send(new ListPartsCommand({
207 | Bucket: process.env.COMPANION_AWS_BUCKET,
208 | Key: key,
209 | UploadId: uploadId,
210 | PartNumberMarker: startAt,
211 | }), (err, data) => {
212 | if (err) {
213 | next(err)
214 | return
215 | }
216 |
217 | parts.push(...data.Parts)
218 |
219 | if (data.IsTruncated) {
220 | // Get the next page.
221 | listPartsPage(data.NextPartNumberMarker)
222 | } else {
223 | res.json(parts)
224 | }
225 | })
226 | }
227 | listPartsPage(0)
228 | })
229 |
230 | function isValidPart (part) {
231 | return part && typeof part === 'object' && Number(part.PartNumber) && typeof part.ETag === 'string'
232 | }
233 | app.post('/s3/multipart/:uploadId/complete', (req, res, next) => {
234 | const client = getS3Client()
235 | const { uploadId } = req.params
236 | const { key } = req.query
237 | const { parts } = req.body
238 |
239 | if (typeof key !== 'string') {
240 | return res.status(400).json({ error: 's3: the object key must be passed as a query parameter. For example: "?key=abc.jpg"' })
241 | }
242 | if (!Array.isArray(parts) || !parts.every(isValidPart)) {
243 | return res.status(400).json({ error: 's3: `parts` must be an array of {ETag, PartNumber} objects.' })
244 | }
245 |
246 | return client.send(new CompleteMultipartUploadCommand({
247 | Bucket: process.env.COMPANION_AWS_BUCKET,
248 | Key: key,
249 | UploadId: uploadId,
250 | MultipartUpload: {
251 | Parts: parts,
252 | },
253 | }), (err, data) => {
254 | if (err) {
255 | next(err)
256 | return
257 | }
258 | res.setHeader('Access-Control-Allow-Origin', '*')
259 | res.json({
260 | location: data.Location,
261 | })
262 | })
263 | })
264 |
265 | app.delete('/s3/multipart/:uploadId', (req, res, next) => {
266 | const client = getS3Client()
267 | const { uploadId } = req.params
268 | const { key } = req.query
269 |
270 | if (typeof key !== 'string') {
271 | return res.status(400).json({ error: 's3: the object key must be passed as a query parameter. For example: "?key=abc.jpg"' })
272 | }
273 |
274 | return client.send(new AbortMultipartUploadCommand({
275 | Bucket: process.env.COMPANION_AWS_BUCKET,
276 | Key: key,
277 | UploadId: uploadId,
278 | }), (err) => {
279 | if (err) {
280 | next(err)
281 | return
282 | }
283 | res.json({})
284 | })
285 | })
286 |
287 | // === ===
288 |
289 | app.listen(port, () => {
290 | console.log(`Example app listening on port ${port}`)
291 | })
292 |
--------------------------------------------------------------------------------
/axamples/aws-nodejs/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | petProj – AWS upload example
6 |
10 |
11 |
12 | AWS upload example
13 |
14 |
266 |
267 |
268 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable quote-props */
2 |
3 | 'use strict'
4 |
5 | const svgPresentationAttributes = [
6 | 'alignment-baseline', 'baseline-shift', 'class', 'clip', 'clip-path', 'clip-rule', 'color', 'color-interpolatio', 'color-interpolatio-filters', 'color-profile', 'color-rendering', 'cursor', 'direction', 'display', 'dominant-baseline', 'enable-background', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'image-rendering', 'kerning', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'overflow', 'pointer-events', 'shape-rendering', 'stop-color', 'stop-opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'transform', 'transform-origin', 'unicode-bidi', 'vector-effect', 'visibility', 'word-spacing', 'writing-mod',
7 | ]
8 |
9 | module.exports = {
10 | root: true,
11 | extends: ['transloadit', 'prettier'],
12 | env: {
13 | es6: true,
14 | jest: true,
15 | node: true,
16 | // extra:
17 | browser: true,
18 | },
19 | globals: {
20 | globalThis: true,
21 | hexo: true,
22 | window: true,
23 | },
24 | plugins: [
25 | '@babel/eslint-plugin',
26 | 'jest',
27 | 'markdown',
28 | 'node',
29 | 'prefer-import',
30 | 'promise',
31 | 'react',
32 | // extra:
33 | 'compat',
34 | 'jsdoc',
35 | 'no-only-tests',
36 | 'unicorn',
37 | ],
38 | parser: '@babel/eslint-parser',
39 | parserOptions: {
40 | sourceType: 'script',
41 | ecmaVersion: 2022,
42 | ecmaFeatures: {
43 | jsx: true,
44 | },
45 | },
46 | rules: {
47 | // transloadit rules we are actually ok with in the petProj repo
48 | 'import/extensions': 'off',
49 | 'object-shorthand': ['error', 'always'],
50 | 'strict': 'off',
51 | 'key-spacing': 'off',
52 | 'max-classes-per-file': ['error', 2],
53 | 'react/no-unknown-property': ['error', {
54 | ignore: svgPresentationAttributes,
55 | }],
56 |
57 | // Special rules for CI:
58 | ...(process.env.CI && {
59 | // Some imports are available only after a full build, which we don't do on CI.
60 | 'import/no-unresolved': 'off',
61 | }),
62 |
63 | // rules we want to enforce
64 | 'array-callback-return': 'error',
65 | 'func-names': 'error',
66 | 'import/no-dynamic-require': 'error',
67 | 'import/no-extraneous-dependencies': 'error',
68 | 'max-len': 'error',
69 | 'no-empty': 'error',
70 | 'no-bitwise': 'error',
71 | 'no-continue': 'error',
72 | 'no-lonely-if': 'error',
73 | 'no-nested-ternary': 'error',
74 | 'no-restricted-properties': 'error',
75 | 'no-return-assign': 'error',
76 | 'no-underscore-dangle': 'error',
77 | 'no-unused-expressions': 'error',
78 | 'no-unused-vars': 'error',
79 | 'no-useless-concat': 'error',
80 | 'no-var': 'error',
81 | 'node/handle-callback-err': 'error',
82 | 'prefer-destructuring': 'error',
83 | 'prefer-spread': 'error',
84 | 'unicorn/prefer-node-protocol': 'error',
85 |
86 | 'react/button-has-type': 'error',
87 | 'react/forbid-prop-types': 'error',
88 | 'react/no-access-state-in-setstate': 'error',
89 | 'react/no-array-index-key': 'error',
90 | 'react/no-deprecated': 'error',
91 | 'react/no-this-in-sfc': 'error',
92 | 'react/no-will-update-set-state': 'error',
93 | 'react/prefer-stateless-function': 'error',
94 | 'react/sort-comp': 'error',
95 | 'react/style-prop-object': 'error',
96 |
97 | // accessibility
98 | 'jsx-a11y/alt-text': 'error',
99 | 'jsx-a11y/anchor-has-content': 'error',
100 | 'jsx-a11y/click-events-have-key-events': 'error',
101 | 'jsx-a11y/control-has-associated-label': 'error',
102 | 'jsx-a11y/label-has-associated-control': 'error',
103 | 'jsx-a11y/media-has-caption': 'error',
104 | 'jsx-a11y/mouse-events-have-key-events': 'error',
105 | 'jsx-a11y/no-interactive-element-to-noninteractive-role': 'error',
106 | 'jsx-a11y/no-noninteractive-element-interactions': 'error',
107 | 'jsx-a11y/no-static-element-interactions': 'error',
108 |
109 | // compat
110 | 'compat/compat': ['error'],
111 |
112 | // jsdoc
113 | 'jsdoc/check-alignment': 'error',
114 | 'jsdoc/check-examples': 'off', // cannot yet be supported for ESLint 8, see https://github.com/eslint/eslint/issues/14745
115 | 'jsdoc/check-param-names': 'error',
116 | 'jsdoc/check-syntax': 'error',
117 | 'jsdoc/check-tag-names': ['error', { jsxTags: true }],
118 | 'jsdoc/check-types': 'error',
119 | 'jsdoc/newline-after-description': 'error',
120 | 'jsdoc/valid-types': 'error',
121 | 'jsdoc/check-indentation': ['off'],
122 | },
123 |
124 | settings: {
125 | 'import/core-modules': ['tsd'],
126 | react: {
127 | pragma: 'h',
128 | },
129 | jsdoc: {
130 | mode: 'typescript',
131 | },
132 | polyfills: [
133 | 'Promise',
134 | 'fetch',
135 | 'Object.assign',
136 | 'document.querySelector',
137 | ],
138 | },
139 |
140 | overrides: [
141 | {
142 | files: [
143 | '*.jsx',
144 | '*.tsx',
145 | 'packages/@petProj/react-native/**/*.js',
146 | ],
147 | parser: 'espree',
148 | parserOptions: {
149 | sourceType: 'module',
150 | ecmaFeatures: {
151 | jsx: true,
152 | },
153 | },
154 | rules: {
155 | 'no-restricted-globals': [
156 | 'error',
157 | {
158 | name: '__filename',
159 | message: 'Use import.meta.url instead',
160 | },
161 | {
162 | name: '__dirname',
163 | message: 'Not available in ESM',
164 | },
165 | {
166 | name: 'exports',
167 | message: 'Not available in ESM',
168 | },
169 | {
170 | name: 'module',
171 | message: 'Not available in ESM',
172 | },
173 | {
174 | name: 'require',
175 | message: 'Use import instead',
176 | },
177 | ],
178 | 'import/extensions': ['error', 'ignorePackages'],
179 | },
180 | },
181 | {
182 | files: [
183 | '*.mjs',
184 | 'e2e/clients/**/*.js',
185 | 'examples/aws-companion/*.js',
186 | 'examples/aws-php/*.js',
187 | 'examples/bundled/*.js',
188 | 'examples/custom-provider/client/*.js',
189 | 'examples/digitalocean-spaces/*.js',
190 | 'examples/multiple-instances/*.js',
191 | 'examples/node-xhr/*.js',
192 | 'examples/php-xhr/*.js',
193 | 'examples/python-xhr/*.js',
194 | 'examples/react-example/*.js',
195 | 'examples/redux/*.js',
196 | 'examples/transloadit/*.js',
197 | 'examples/transloadit-markdown-bin/*.js',
198 | 'examples/xhr-bundle/*.js',
199 | 'private/dev/*.js',
200 | 'private/release/*.js',
201 | 'private/remark-lint-petProj/*.js',
202 |
203 | // Packages that have switched to ESM sources:
204 | 'packages/@petProj/audio/src/**/*.js',
205 | 'packages/@petProj/aws-s3-multipart/src/**/*.js',
206 | 'packages/@petProj/aws-s3/src/**/*.js',
207 | 'packages/@petProj/box/src/**/*.js',
208 | 'packages/@petProj/companion-client/src/**/*.js',
209 | 'packages/@petProj/compressor/src/**/*.js',
210 | 'packages/@petProj/core/src/**/*.js',
211 | 'packages/@petProj/dashboard/src/**/*.js',
212 | 'packages/@petProj/drag-drop/src/**/*.js',
213 | 'packages/@petProj/drop-target/src/**/*.js',
214 | 'packages/@petProj/dropbox/src/**/*.js',
215 | 'packages/@petProj/facebook/src/**/*.js',
216 | 'packages/@petProj/file-input/src/**/*.js',
217 | 'packages/@petProj/form/src/**/*.js',
218 | 'packages/@petProj/golden-retriever/src/**/*.js',
219 | 'packages/@petProj/google-drive/src/**/*.js',
220 | 'packages/@petProj/image-editor/src/**/*.js',
221 | 'packages/@petProj/informer/src/**/*.js',
222 | 'packages/@petProj/instagram/src/**/*.js',
223 | 'packages/@petProj/locales/src/**/*.js',
224 | 'packages/@petProj/locales/template.js',
225 | 'packages/@petProj/onedrive/src/**/*.js',
226 | 'packages/@petProj/progress-bar/src/**/*.js',
227 | 'packages/@petProj/provider-views/src/**/*.js',
228 | 'packages/@petProj/react/src/**/*.js',
229 | 'packages/@petProj/redux-dev-tools/src/**/*.js',
230 | 'packages/@petProj/remote-sources/src/**/*.js',
231 | 'packages/@petProj/screen-capture/src/**/*.js',
232 | 'packages/@petProj/status-bar/src/**/*.js',
233 | 'packages/@petProj/store-default/src/**/*.js',
234 | 'packages/@petProj/store-redux/src/**/*.js',
235 | 'packages/@petProj/svelte/rollup.config.js',
236 | 'packages/@petProj/svelte/src/**/*.js',
237 | 'packages/@petProj/thumbnail-generator/src/**/*.js',
238 | 'packages/@petProj/transloadit/src/**/*.js',
239 | 'packages/@petProj/tus/src/**/*.js',
240 | 'packages/@petProj/unsplash/src/**/*.js',
241 | 'packages/@petProj/url/src/**/*.js',
242 | 'packages/@petProj/utils/src/**/*.js',
243 | 'packages/@petProj/vue/src/**/*.js',
244 | 'packages/@petProj/webcam/src/**/*.js',
245 | 'packages/@petProj/xhr-upload/src/**/*.js',
246 | 'packages/@petProj/zoom/src/**/*.js',
247 | ],
248 | parser: 'espree',
249 | parserOptions: {
250 | sourceType: 'module',
251 | ecmaFeatures: {
252 | jsx: false,
253 | },
254 | },
255 | rules: {
256 | 'import/named': 'off', // Disabled because that rule tries and fails to parse JSX dependencies.
257 | 'import/no-named-as-default': 'off', // Disabled because that rule tries and fails to parse JSX dependencies.
258 | 'import/no-named-as-default-member': 'off', // Disabled because that rule tries and fails to parse JSX dependencies.
259 | 'no-restricted-globals': [
260 | 'error',
261 | {
262 | name: '__filename',
263 | message: 'Use import.meta.url instead',
264 | },
265 | {
266 | name: '__dirname',
267 | message: 'Not available in ESM',
268 | },
269 | {
270 | name: 'exports',
271 | message: 'Not available in ESM',
272 | },
273 | {
274 | name: 'module',
275 | message: 'Not available in ESM',
276 | },
277 | {
278 | name: 'require',
279 | message: 'Use import instead',
280 | },
281 | ],
282 | 'import/extensions': ['error', 'ignorePackages'],
283 | },
284 | },
285 | {
286 | files: ['packages/petProj/*.mjs'],
287 | rules: {
288 | 'import/first': 'off',
289 | 'import/newline-after-import': 'off',
290 | 'import/no-extraneous-dependencies': ['error', {
291 | devDependencies: true,
292 | }],
293 | },
294 | },
295 | {
296 | files: [
297 | 'packages/@petProj/*/types/*.d.ts',
298 | ],
299 | rules : {
300 | 'import/no-unresolved': 'off',
301 | 'max-classes-per-file': 'off',
302 | 'no-use-before-define': 'off',
303 | },
304 | },
305 | {
306 | files: [
307 | 'packages/@petProj/dashboard/src/components/**/*.jsx',
308 | ],
309 | rules: {
310 | 'react/destructuring-assignment': 'off',
311 | },
312 | },
313 | {
314 | files: [
315 | // Those need looser rules, and cannot be made part of the stricter rules above.
316 | // TODO: update those to more modern code when switch to ESM is complete
317 | 'examples/react-native-expo/*.js',
318 | 'examples/svelte-example/**/*.js',
319 | 'examples/vue/**/*.js',
320 | 'examples/vue3/**/*.js',
321 | ],
322 | rules: {
323 | 'no-unused-vars': [
324 | 'error',
325 | {
326 | 'varsIgnorePattern': 'React',
327 | },
328 | ],
329 | },
330 | parserOptions: {
331 | sourceType: 'module',
332 | },
333 | },
334 | {
335 | files: ['./packages/@petProj/companion/**/*.js'],
336 | rules: {
337 | 'no-underscore-dangle': 'off',
338 | },
339 | },
340 | {
341 | files: [
342 | '*.test.js',
343 | 'test/endtoend/*.js',
344 | 'bin/**.js',
345 | ],
346 | rules: {
347 | 'compat/compat': ['off'],
348 | },
349 | },
350 | {
351 | files: [
352 | 'bin/**.js',
353 | 'bin/**.mjs',
354 | 'examples/**/*.cjs',
355 | 'examples/**/*.js',
356 | 'packages/@petProj/companion/test/**/*.js',
357 | 'test/**/*.js',
358 | 'test/**/*.ts',
359 | '*.test.js',
360 | '*.test.ts',
361 | '*.test-d.ts',
362 | '*.test-d.tsx',
363 | 'postcss.config.js',
364 | '.eslintrc.js',
365 | 'private/**/*.js',
366 | 'private/**/*.mjs',
367 | ],
368 | rules: {
369 | 'no-console': 'off',
370 | 'import/no-extraneous-dependencies': ['error', {
371 | devDependencies: true,
372 | }],
373 | },
374 | },
375 |
376 | {
377 | files: [
378 | 'packages/@petProj/locales/src/*.js',
379 | 'packages/@petProj/locales/template.js',
380 | ],
381 | rules: {
382 | camelcase: ['off'],
383 | 'quote-props': ['error', 'as-needed', { 'numbers': true }],
384 | },
385 | },
386 |
387 | {
388 | files: ['test/endtoend/*/*.mjs', 'test/endtoend/*/*.ts'],
389 | rules: {
390 | // we mostly import @petProj stuff in these files.
391 | 'import/no-extraneous-dependencies': ['off'],
392 | },
393 | },
394 | {
395 | files: ['test/endtoend/*/*.js'],
396 | env: {
397 | mocha: true,
398 | },
399 | },
400 |
401 | {
402 | files: ['packages/@petProj/react/src/**/*.js'],
403 | rules: {
404 | 'import/no-extraneous-dependencies': ['error', {
405 | peerDependencies: true,
406 | }],
407 | },
408 | },
409 |
410 | {
411 | files: ['**/*.md', '*.md'],
412 | processor: 'markdown/markdown',
413 | },
414 | {
415 | files: ['**/*.md/*.js', '**/*.md/*.javascript'],
416 | parserOptions: {
417 | sourceType: 'module',
418 | },
419 | rules: {
420 | 'react/destructuring-assignment': 'off',
421 | 'no-restricted-globals': [
422 | 'error',
423 | {
424 | name: '__filename',
425 | message: 'Use import.meta.url instead',
426 | },
427 | {
428 | name: '__dirname',
429 | message: 'Not available in ESM',
430 | },
431 | {
432 | name: 'exports',
433 | message: 'Not available in ESM',
434 | },
435 | {
436 | name: 'module',
437 | message: 'Not available in ESM',
438 | },
439 | {
440 | name: 'require',
441 | message: 'Use import instead',
442 | },
443 | ],
444 | },
445 | },
446 | {
447 | files: ['**/*.ts', '**/*.md/*.ts', '**/*.md/*.typescript'],
448 | excludedFiles: ['examples/angular-example/**/*.ts', 'packages/@petProj/angular/**/*.ts'],
449 | parser: '@typescript-eslint/parser',
450 | settings: {
451 | 'import/resolver': {
452 | node: {
453 | extensions: ['.js', '.jsx', '.ts', '.tsx'],
454 | },
455 | },
456 | },
457 | plugins: ['@typescript-eslint'],
458 | extends: [
459 | 'eslint:recommended',
460 | 'plugin:@typescript-eslint/eslint-recommended',
461 | 'plugin:@typescript-eslint/recommended',
462 | ],
463 | rules: {
464 | 'import/prefer-default-export': 'off',
465 | '@typescript-eslint/no-explicit-any': 'off',
466 | '@typescript-eslint/no-extra-semi': 'off',
467 | '@typescript-eslint/no-namespace': 'off',
468 | },
469 | },
470 | {
471 | files: ['packages/@petProj/*/src/**/*.ts', 'packages/@petProj/*/src/**/*.tsx'],
472 | excludedFiles: ['packages/@petProj/**/*.test.ts'],
473 | rules: {
474 | '@typescript-eslint/explicit-function-return-type': 'error',
475 | },
476 | },
477 | {
478 | files: ['**/*.md/*.*'],
479 | rules: {
480 | 'import/no-extraneous-dependencies': 'off',
481 | 'import/no-unresolved': 'off',
482 | 'no-console': 'off',
483 | 'no-undef': 'off',
484 | 'no-unused-vars': 'off',
485 | },
486 | },
487 | {
488 | files: ['**/react/*.md/*.js', '**/react.md/*.js', '**/react-*.md/*.js', '**/react/**/*.test-d.tsx'],
489 | settings: {
490 | react: { pragma: 'React' },
491 | },
492 | },
493 | {
494 | files: ['**/react/**/*.test-d.tsx'],
495 | rules: {
496 | 'import/extensions': 'off',
497 | 'import/no-useless-path-segments': 'off',
498 | 'no-alert': 'off',
499 | 'no-inner-declarations': 'off',
500 | 'no-lone-blocks': 'off',
501 | 'no-unused-expressions': 'off',
502 | 'no-unused-vars': 'off',
503 | },
504 | },
505 | {
506 | files: ['e2e/**/*.ts'],
507 | extends: ['plugin:cypress/recommended'],
508 | },
509 | {
510 | files: ['e2e/**/*.ts', 'e2e/**/*.js', 'e2e/**/*.jsx', 'e2e/**/*.mjs'],
511 | rules: {
512 | 'import/no-extraneous-dependencies': 'off',
513 | 'no-console': 'off',
514 | 'no-only-tests/no-only-tests': 'error',
515 | 'no-unused-expressions': 'off',
516 | },
517 | },
518 | ],
519 | }
520 |
--------------------------------------------------------------------------------