@efxlab/motion-canvas-vite-plugin 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +3 -0
- package/lib/index.js +23 -0
- package/lib/index.js.map +1 -0
- package/lib/main.d.ts +82 -0
- package/lib/main.js +42 -0
- package/lib/main.js.map +1 -0
- package/lib/openInExplorer.d.ts +1 -0
- package/lib/openInExplorer.js +44 -0
- package/lib/openInExplorer.js.map +1 -0
- package/lib/partials/assets.d.ts +6 -0
- package/lib/partials/assets.js +50 -0
- package/lib/partials/assets.js.map +1 -0
- package/lib/partials/corsProxy.d.ts +43 -0
- package/lib/partials/corsProxy.js +218 -0
- package/lib/partials/corsProxy.js.map +1 -0
- package/lib/partials/editor.d.ts +8 -0
- package/lib/partials/editor.js +75 -0
- package/lib/partials/editor.js.map +1 -0
- package/lib/partials/exporter.d.ts +6 -0
- package/lib/partials/exporter.js +48 -0
- package/lib/partials/exporter.js.map +1 -0
- package/lib/partials/index.d.ts +9 -0
- package/lib/partials/index.js +26 -0
- package/lib/partials/index.js.map +1 -0
- package/lib/partials/meta.d.ts +2 -0
- package/lib/partials/meta.js +66 -0
- package/lib/partials/meta.js.map +1 -0
- package/lib/partials/projects.d.ts +9 -0
- package/lib/partials/projects.js +88 -0
- package/lib/partials/projects.js.map +1 -0
- package/lib/partials/scenes.d.ts +2 -0
- package/lib/partials/scenes.js +46 -0
- package/lib/partials/scenes.js.map +1 -0
- package/lib/partials/settings.d.ts +2 -0
- package/lib/partials/settings.js +65 -0
- package/lib/partials/settings.js.map +1 -0
- package/lib/partials/webgl.d.ts +10 -0
- package/lib/partials/webgl.js +88 -0
- package/lib/partials/webgl.js.map +1 -0
- package/lib/plugins.d.ts +104 -0
- package/lib/plugins.js +9 -0
- package/lib/plugins.js.map +1 -0
- package/lib/utils.d.ts +3 -0
- package/lib/utils.js +54 -0
- package/lib/utils.js.map +1 -0
- package/lib/versions.d.ts +6 -0
- package/lib/versions.js +28 -0
- package/lib/versions.js.map +1 -0
- package/package.json +39 -0
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
const main_1 = __importDefault(require("./main"));
|
|
21
|
+
exports.default = main_1.default;
|
|
22
|
+
__exportStar(require("./plugins"), exports);
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,kDAAkC;AAElC,kBAAe,cAAY,CAAC;AAC5B,4CAA0B"}
|
package/lib/main.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
import { CorsProxyPluginConfig } from './partials';
|
|
3
|
+
export interface MotionCanvasPluginConfig {
|
|
4
|
+
/**
|
|
5
|
+
* The import path of the project file or an array of paths.
|
|
6
|
+
* Also supports globs.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* Each file must contain a default export exposing an instance of the
|
|
10
|
+
* {@link Project} class.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* motionCanvas({
|
|
15
|
+
* project: [
|
|
16
|
+
* './src/firstProject.ts',
|
|
17
|
+
* './src/secondProject.ts',
|
|
18
|
+
* ]
|
|
19
|
+
* })
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @defaultValue './src/project.ts'
|
|
23
|
+
*/
|
|
24
|
+
project?: string | string[];
|
|
25
|
+
/**
|
|
26
|
+
* A directory path to which the animation will be rendered.
|
|
27
|
+
*
|
|
28
|
+
* @defaultValue './output'
|
|
29
|
+
*/
|
|
30
|
+
output?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Defines which assets should be buffered before being sent to the browser.
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* Streaming larger assets directly from the drive may cause issues with other
|
|
36
|
+
* applications. For instance, if an audio file is being used in the project,
|
|
37
|
+
* Adobe Audition will perceive it as "being used by another application"
|
|
38
|
+
* and refuse to override it.
|
|
39
|
+
*
|
|
40
|
+
* Buffered assets are first loaded to the memory and then streamed from
|
|
41
|
+
* there. This leaves the original files open for modification with hot module
|
|
42
|
+
* replacement still working.
|
|
43
|
+
*
|
|
44
|
+
* @defaultValue /^$/
|
|
45
|
+
*/
|
|
46
|
+
bufferedAssets?: RegExp | false;
|
|
47
|
+
/**
|
|
48
|
+
* The import path of the editor package.
|
|
49
|
+
*
|
|
50
|
+
* @remarks
|
|
51
|
+
* This path will be resolved using Node.js module resolution rules.
|
|
52
|
+
* It should lead to a directory containing the following files:
|
|
53
|
+
* - `editor.html` - The HTML template for the editor.
|
|
54
|
+
* - `styles.css` - The editor styles.
|
|
55
|
+
* - `main.js` - A module exporting necessary factory functions.
|
|
56
|
+
*
|
|
57
|
+
* `main.js` should export the following functions:
|
|
58
|
+
* - `editor` - Receives the project factory as its first argument and creates
|
|
59
|
+
* the user interface.
|
|
60
|
+
* - `index` - Receives a list of all projects as its first argument and
|
|
61
|
+
* creates the initial page for selecting a project.
|
|
62
|
+
*
|
|
63
|
+
* @defaultValue '\@efxlab/motion-canvas-ui'
|
|
64
|
+
*/
|
|
65
|
+
editor?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Configuration of the Proxy used for remote sources
|
|
68
|
+
*
|
|
69
|
+
* @remarks
|
|
70
|
+
* This passes configuration to Motion Canvas' proxy.
|
|
71
|
+
* Note that the proxy is disabled by default.
|
|
72
|
+
* You can either pass `true` and a config object
|
|
73
|
+
* to enable it.
|
|
74
|
+
**/
|
|
75
|
+
proxy?: boolean | CorsProxyPluginConfig;
|
|
76
|
+
/**
|
|
77
|
+
* Build the project to run in the editor.
|
|
78
|
+
*/
|
|
79
|
+
buildForEditor?: boolean;
|
|
80
|
+
}
|
|
81
|
+
declare const _default: ({ project, output, bufferedAssets, editor, proxy, buildForEditor, }?: MotionCanvasPluginConfig) => Plugin[];
|
|
82
|
+
export default _default;
|
package/lib/main.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const path_1 = __importDefault(require("path"));
|
|
7
|
+
const partials_1 = require("./partials");
|
|
8
|
+
const plugins_1 = require("./plugins");
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
exports.default = ({ project = './src/project.ts', output = './output', bufferedAssets = /^$/, editor = '@efxlab/motion-canvas-ui', proxy, buildForEditor, } = {}) => {
|
|
11
|
+
const plugins = [];
|
|
12
|
+
let config = {
|
|
13
|
+
output: path_1.default.resolve(output),
|
|
14
|
+
projects: (0, utils_1.getProjects)(project),
|
|
15
|
+
};
|
|
16
|
+
return [
|
|
17
|
+
{
|
|
18
|
+
name: 'motion-canvas',
|
|
19
|
+
async configResolved(resolvedConfig) {
|
|
20
|
+
plugins.push(...resolvedConfig.plugins
|
|
21
|
+
.filter(plugins_1.isPlugin)
|
|
22
|
+
.map(plugin => plugin[plugins_1.PLUGIN_OPTIONS]));
|
|
23
|
+
for (const plugin of plugins) {
|
|
24
|
+
const newConfig = await plugin.config?.(config);
|
|
25
|
+
if (newConfig) {
|
|
26
|
+
config = { ...config, ...newConfig };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
(0, partials_1.metaPlugin)(),
|
|
32
|
+
(0, partials_1.settingsPlugin)(),
|
|
33
|
+
(0, partials_1.scenesPlugin)(),
|
|
34
|
+
(0, partials_1.exporterPlugin)({ outputPath: config.output }),
|
|
35
|
+
(0, partials_1.editorPlugin)({ editor, projects: config.projects }),
|
|
36
|
+
(0, partials_1.projectsPlugin)({ projects: config.projects, plugins, buildForEditor }),
|
|
37
|
+
(0, partials_1.assetsPlugin)({ bufferedAssets }),
|
|
38
|
+
(0, partials_1.webglPlugin)(),
|
|
39
|
+
(0, partials_1.corsProxyPlugin)(proxy),
|
|
40
|
+
];
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=main.js.map
|
package/lib/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AAExB,yCAWoB;AACpB,uCAAgF;AAChF,mCAAoC;AAkFpC,kBAAe,CAAC,EACd,OAAO,GAAG,kBAAkB,EAC5B,MAAM,GAAG,UAAU,EACnB,cAAc,GAAG,IAAI,EACrB,MAAM,GAAG,0BAA0B,EACnC,KAAK,EACL,cAAc,MACc,EAAE,EAAY,EAAE;IAC5C,MAAM,OAAO,GAAoB,EAAE,CAAC;IACpC,IAAI,MAAM,GAAiB;QACzB,MAAM,EAAE,cAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5B,QAAQ,EAAE,IAAA,mBAAW,EAAC,OAAO,CAAC;KAC/B,CAAC;IAEF,OAAO;QACL;YACE,IAAI,EAAE,eAAe;YACrB,KAAK,CAAC,cAAc,CAAC,cAAc;gBACjC,OAAO,CAAC,IAAI,CACV,GAAG,cAAc,CAAC,OAAO;qBACtB,MAAM,CAAC,kBAAQ,CAAC;qBAChB,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,wBAAc,CAAC,CAAC,CACzC,CAAC;gBAEF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;oBAC7B,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;oBAChD,IAAI,SAAS,EAAE,CAAC;wBACd,MAAM,GAAG,EAAC,GAAG,MAAM,EAAE,GAAG,SAAS,EAAC,CAAC;oBACrC,CAAC;gBACH,CAAC;YACH,CAAC;SACF;QACD,IAAA,qBAAU,GAAE;QACZ,IAAA,yBAAc,GAAE;QAChB,IAAA,uBAAY,GAAE;QACd,IAAA,yBAAc,EAAC,EAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAC,CAAC;QAC3C,IAAA,uBAAY,EAAC,EAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAC,CAAC;QACjD,IAAA,yBAAc,EAAC,EAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAC,CAAC;QACpE,IAAA,uBAAY,EAAC,EAAC,cAAc,EAAC,CAAC;QAC9B,IAAA,sBAAW,GAAE;QACb,IAAA,0BAAe,EAAC,KAAK,CAAC;KACvB,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function openInExplorer(file: string): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.openInExplorer = openInExplorer;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const os_1 = require("os");
|
|
6
|
+
function openInExplorer(file) {
|
|
7
|
+
let command = null;
|
|
8
|
+
let args = [file];
|
|
9
|
+
const os = (0, os_1.platform)();
|
|
10
|
+
switch (os) {
|
|
11
|
+
case 'win32':
|
|
12
|
+
command = 'explorer';
|
|
13
|
+
break;
|
|
14
|
+
case 'linux':
|
|
15
|
+
if (isRunningOnWSL()) {
|
|
16
|
+
command = 'bash';
|
|
17
|
+
args = ['-c', `cd ${file} && explorer.exe .`];
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
command = 'xdg-open';
|
|
21
|
+
}
|
|
22
|
+
break;
|
|
23
|
+
case 'darwin':
|
|
24
|
+
command = 'open';
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
if (command) {
|
|
28
|
+
(0, child_process_1.spawn)(command, args, { detached: true }).unref();
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.warn(`Unsupported OS: ${os}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function isRunningOnWSL() {
|
|
35
|
+
try {
|
|
36
|
+
const uname = (0, child_process_1.execSync)('uname -a').toString().toLowerCase();
|
|
37
|
+
return uname.includes('microsoft');
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error(`exec error: ${error}`);
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=openInExplorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openInExplorer.js","sourceRoot":"","sources":["../src/openInExplorer.ts"],"names":[],"mappings":";;AAGA,wCA2BC;AA9BD,iDAA8C;AAC9C,2BAA4B;AAE5B,SAAgB,cAAc,CAAC,IAAY;IACzC,IAAI,OAAO,GAAkB,IAAI,CAAC;IAClC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAClB,MAAM,EAAE,GAAG,IAAA,aAAQ,GAAE,CAAC;IAEtB,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,OAAO;YACV,OAAO,GAAG,UAAU,CAAC;YACrB,MAAM;QACR,KAAK,OAAO;YACV,IAAI,cAAc,EAAE,EAAE,CAAC;gBACrB,OAAO,GAAG,MAAM,CAAC;gBACjB,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,oBAAoB,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,UAAU,CAAC;YACvB,CAAC;YACD,MAAM;QACR,KAAK,QAAQ;YACX,OAAO,GAAG,MAAM,CAAC;YACjB,MAAM;IACV,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,IAAA,qBAAK,EAAC,OAAO,EAAE,IAAI,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAC,KAAK,EAAE,CAAC;IACjD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAA,wBAAQ,EAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,eAAe,KAAK,EAAE,CAAC,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.assetsPlugin = assetsPlugin;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const stream_1 = require("stream");
|
|
10
|
+
const AUDIO_EXTENSION_REGEX = /\.(mp3|wav|ogg|aac|flac)(?:$|\?)/;
|
|
11
|
+
const AUDIO_HMR_DELAY = 1000;
|
|
12
|
+
function assetsPlugin({ bufferedAssets }) {
|
|
13
|
+
let config;
|
|
14
|
+
return {
|
|
15
|
+
name: 'motion-canvas:assets',
|
|
16
|
+
configResolved(resolvedConfig) {
|
|
17
|
+
config = resolvedConfig;
|
|
18
|
+
},
|
|
19
|
+
configureServer(server) {
|
|
20
|
+
server.middlewares.use((req, res, next) => {
|
|
21
|
+
if (req.url && bufferedAssets && bufferedAssets.test(req.url)) {
|
|
22
|
+
const file = fs_1.default.readFileSync(path_1.default.resolve(config.root, req.url.slice(1)));
|
|
23
|
+
stream_1.Readable.from(file).pipe(res);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
next();
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
async handleHotUpdate(ctx) {
|
|
30
|
+
const urls = [];
|
|
31
|
+
const modules = [];
|
|
32
|
+
for (const module of ctx.modules) {
|
|
33
|
+
urls.push(module.url);
|
|
34
|
+
if (!AUDIO_EXTENSION_REGEX.test(module.url)) {
|
|
35
|
+
modules.push(module);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
await new Promise(resolve => {
|
|
39
|
+
setTimeout(resolve, AUDIO_HMR_DELAY);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (urls.length > 0) {
|
|
44
|
+
ctx.server.ws.send('motion-canvas:assets', { urls });
|
|
45
|
+
}
|
|
46
|
+
return modules;
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/partials/assets.ts"],"names":[],"mappings":";;;;;AAYA,oCA6CC;AAzDD,4CAAoB;AACpB,gDAAwB;AACxB,mCAAgC;AAGhC,MAAM,qBAAqB,GAAG,kCAAkC,CAAC;AACjE,MAAM,eAAe,GAAG,IAAI,CAAC;AAM7B,SAAgB,YAAY,CAAC,EAAC,cAAc,EAAqB;IAC/D,IAAI,MAAsB,CAAC;IAC3B,OAAO;QACL,IAAI,EAAE,sBAAsB;QAE5B,cAAc,CAAC,cAAc;YAC3B,MAAM,GAAG,cAAc,CAAC;QAC1B,CAAC;QAED,eAAe,CAAC,MAAM;YACpB,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;gBACxC,IAAI,GAAG,CAAC,GAAG,IAAI,cAAc,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC9D,MAAM,IAAI,GAAG,YAAE,CAAC,YAAY,CAC1B,cAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAC5C,CAAC;oBACF,iBAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC9B,OAAO;gBACT,CAAC;gBAED,IAAI,EAAE,CAAC;YACT,CAAC,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,eAAe,CAAC,GAAG;YACvB,MAAM,IAAI,GAAG,EAAE,CAAC;YAChB,MAAM,OAAO,GAAiB,EAAE,CAAC;YAEjC,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBACjC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACtB,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC5C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACvB,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;wBAC1B,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;oBACvC,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpB,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAC,IAAI,EAAC,CAAC,CAAC;YACrD,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration used by the Proxy plugin
|
|
4
|
+
*/
|
|
5
|
+
export interface CorsProxyPluginConfig {
|
|
6
|
+
/**
|
|
7
|
+
* Set which types of resources are allowed by default.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Catchall on the right side is supported.
|
|
11
|
+
* Pass an empty Array to allow all types of resources, although this is not
|
|
12
|
+
* recommended.
|
|
13
|
+
*
|
|
14
|
+
* @defaultValue ["image/*", "video/*"]
|
|
15
|
+
*/
|
|
16
|
+
allowedMimeTypes?: string[];
|
|
17
|
+
/**
|
|
18
|
+
* Set which hosts are allowed
|
|
19
|
+
*
|
|
20
|
+
* @remarks
|
|
21
|
+
* Note that the host is everything to the left of the first `/`, and to the
|
|
22
|
+
* right of the protocol `https://`. AllowList is not used by default,
|
|
23
|
+
* although you should consider setting up just the relevant hosts.
|
|
24
|
+
*/
|
|
25
|
+
allowListHosts?: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* This module provides the proxy located at
|
|
29
|
+
* /cors-proxy/...
|
|
30
|
+
*
|
|
31
|
+
* It is needed when accessing remote resources.
|
|
32
|
+
* Trying to access remote resources works while
|
|
33
|
+
* in preview, but will fail when you try to
|
|
34
|
+
* output the image (= "read" the canvas)
|
|
35
|
+
*
|
|
36
|
+
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image
|
|
37
|
+
* for reasons
|
|
38
|
+
*
|
|
39
|
+
* Using the proxy circumvents CORS-issues because
|
|
40
|
+
* this way all remote resources are served from the
|
|
41
|
+
* same host as the main app.
|
|
42
|
+
*/
|
|
43
|
+
export declare function corsProxyPlugin(config?: CorsProxyPluginConfig | boolean): Plugin;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.corsProxyPlugin = corsProxyPlugin;
|
|
7
|
+
const follow_redirects_1 = __importDefault(require("follow-redirects"));
|
|
8
|
+
/**
|
|
9
|
+
* This module provides the proxy located at
|
|
10
|
+
* /cors-proxy/...
|
|
11
|
+
*
|
|
12
|
+
* It is needed when accessing remote resources.
|
|
13
|
+
* Trying to access remote resources works while
|
|
14
|
+
* in preview, but will fail when you try to
|
|
15
|
+
* output the image (= "read" the canvas)
|
|
16
|
+
*
|
|
17
|
+
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image
|
|
18
|
+
* for reasons
|
|
19
|
+
*
|
|
20
|
+
* Using the proxy circumvents CORS-issues because
|
|
21
|
+
* this way all remote resources are served from the
|
|
22
|
+
* same host as the main app.
|
|
23
|
+
*/
|
|
24
|
+
function corsProxyPlugin(config) {
|
|
25
|
+
setupEnvVarsForProxy(config);
|
|
26
|
+
return {
|
|
27
|
+
name: 'motion-canvas:cors-proxy',
|
|
28
|
+
configureServer(server) {
|
|
29
|
+
if (config !== false && config !== undefined) {
|
|
30
|
+
motionCanvasCorsProxy(server.middlewares, config === true ? {} : config);
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function setupEnvVarsForProxy(config) {
|
|
36
|
+
// Define Keys for Env Var
|
|
37
|
+
const prefix = 'VITE_MC_PROXY_';
|
|
38
|
+
const isEnabledKey = prefix + 'ENABLED';
|
|
39
|
+
const allowList = prefix + 'ALLOW_LIST';
|
|
40
|
+
if (config === true) {
|
|
41
|
+
config = {}; // Use Default values
|
|
42
|
+
}
|
|
43
|
+
process.env[isEnabledKey] = String(!!config); // 'true' or 'false'
|
|
44
|
+
if (config) {
|
|
45
|
+
// These values are only configured if the Proxy is enabled
|
|
46
|
+
// You cannot access them via import.meta.env if the Proxy
|
|
47
|
+
// is set to false
|
|
48
|
+
process.env[allowList] = JSON.stringify(config.allowListHosts ?? []);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function motionCanvasCorsProxy(middleware, config) {
|
|
52
|
+
// Set the default config if no config was provided
|
|
53
|
+
config.allowedMimeTypes ??= ['image/*', 'video/*'];
|
|
54
|
+
config.allowListHosts ??= [];
|
|
55
|
+
// Check the Mime Types to have a correct structure (left/right)
|
|
56
|
+
// not having them in the correct format would crash the Middleware
|
|
57
|
+
// further down below
|
|
58
|
+
if ((config.allowedMimeTypes ?? []).some(e => e.split('/').length !== 2)) {
|
|
59
|
+
throw new Error("Invalid config for Proxy:\nAll Entries must have the following format:\n 'left/right' where left may be '*'");
|
|
60
|
+
}
|
|
61
|
+
middleware.use((req, res, next) => {
|
|
62
|
+
if (!req.url || !req.url.startsWith('/cors-proxy/')) {
|
|
63
|
+
// url does not start with /cors-proxy/, so this
|
|
64
|
+
// middleware does not care about it
|
|
65
|
+
return next();
|
|
66
|
+
}
|
|
67
|
+
// For now, only allow GET Requests
|
|
68
|
+
if (req.method !== 'GET') {
|
|
69
|
+
return writeError('Only GET Requests are allowed', res, 405);
|
|
70
|
+
}
|
|
71
|
+
let sourceUrl;
|
|
72
|
+
try {
|
|
73
|
+
sourceUrl = extractDestination(req.url);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
return writeError(err, res);
|
|
77
|
+
}
|
|
78
|
+
if (!isReceivedUrlInAllowedHosts(sourceUrl.hostname, config.allowListHosts)) {
|
|
79
|
+
return writeError(`Blocked by Proxy: ${sourceUrl.hostname} is not on Hosts Allowlist`, res);
|
|
80
|
+
}
|
|
81
|
+
// Get the resource, do some checks. Throws an Error
|
|
82
|
+
// if the checks fail. The catch then writes an Error
|
|
83
|
+
return tryGetResource(res, sourceUrl, config).catch(error => {
|
|
84
|
+
writeError(error, res);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Unwrap the destination from the URL.
|
|
90
|
+
*
|
|
91
|
+
* @remarks
|
|
92
|
+
* Throws an Error if the value could not be unwrapped.
|
|
93
|
+
*
|
|
94
|
+
* @param url - the entire URL with the `/cors-proxy/` prefix and containing the
|
|
95
|
+
* url-Encoded Path.
|
|
96
|
+
*
|
|
97
|
+
* @returns The URL that needs to be called.
|
|
98
|
+
*/
|
|
99
|
+
function extractDestination(url) {
|
|
100
|
+
const withoutPrefix = url.replace('/cors-proxy/', '');
|
|
101
|
+
const asUrl = new URL(decodeURIComponent(withoutPrefix));
|
|
102
|
+
if (asUrl.protocol !== 'http:' && asUrl.protocol !== 'https:') {
|
|
103
|
+
throw new Error('Only supported protocols are http and https');
|
|
104
|
+
}
|
|
105
|
+
return asUrl;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* A simple Error Helper that will write an Error and close the response.
|
|
109
|
+
*/
|
|
110
|
+
function writeError(message, res, statusCode = 400) {
|
|
111
|
+
res.writeHead(statusCode, message);
|
|
112
|
+
res.end();
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check if the Proxy is allowed to get the requested resource based on the
|
|
116
|
+
* host.
|
|
117
|
+
*/
|
|
118
|
+
function isReceivedUrlInAllowedHosts(hostname, allowListHosts) {
|
|
119
|
+
if (!allowListHosts || allowListHosts.length === 0) {
|
|
120
|
+
// if the allowListHosts is just the predefinedAllowlist, the user has not
|
|
121
|
+
// set any additional hosts. In this case, allow any hostname
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
// Check if the hostname is any of the values set in allowListHosts
|
|
125
|
+
return allowListHosts.some(e => e.toLowerCase().trim() === hostname.toLowerCase().trim());
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Check if the Proxy is allowed to get the requested resource based on the
|
|
129
|
+
* MIME-Type.
|
|
130
|
+
*
|
|
131
|
+
* @remarks
|
|
132
|
+
* Also handles catch-All Declarations like `image/*`.
|
|
133
|
+
*/
|
|
134
|
+
function isResultOfAllowedResourceType(foundMimeType, allowedMimeTypes) {
|
|
135
|
+
if (!allowedMimeTypes || allowedMimeTypes.length === 0) {
|
|
136
|
+
return true; // no filters set
|
|
137
|
+
}
|
|
138
|
+
if (foundMimeType.split('/').length !== 2) {
|
|
139
|
+
return false; // invalid mime structure
|
|
140
|
+
}
|
|
141
|
+
const [leftSegment, rightSegment] = foundMimeType
|
|
142
|
+
.split('/')
|
|
143
|
+
.map(e => e.trim().toLowerCase());
|
|
144
|
+
// Get all Segments where the left Part is identical between foundMimeType and
|
|
145
|
+
// allowedMimeType.
|
|
146
|
+
const leftSegmentMatches = allowedMimeTypes.filter(e => e.trim().toLowerCase().split('/')[0] === leftSegment);
|
|
147
|
+
if (leftSegmentMatches.length === 0) {
|
|
148
|
+
// No matches at all, not even catchall - resource is rejected.
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
// This just gets the right part of the MIME Types from the
|
|
152
|
+
// configured allowList, e.g. "image/png" -> png
|
|
153
|
+
const rightSegmentOfLeftSegmentMatches = leftSegmentMatches.map(e => e.split('/')[1]);
|
|
154
|
+
// if an exact match or a catchall is found, the resource is allowed to be
|
|
155
|
+
// proxied.
|
|
156
|
+
return rightSegmentOfLeftSegmentMatches.some(e => e === '*' || e === rightSegment);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Requests a remote resource with the help of axios
|
|
160
|
+
* May throw a string in case of a bad mime-type or missing headers
|
|
161
|
+
*/
|
|
162
|
+
async function tryGetResource(res, sourceUrl, config) {
|
|
163
|
+
// Turn this callback into a Promise to avoid additional nesting
|
|
164
|
+
const result = await new Promise((res, rej) => {
|
|
165
|
+
try {
|
|
166
|
+
// We check what protocol was used and decide if we use http or https
|
|
167
|
+
const request = (sourceUrl.protocol.startsWith('https')
|
|
168
|
+
? follow_redirects_1.default.https
|
|
169
|
+
: follow_redirects_1.default.http).get(sourceUrl, data => {
|
|
170
|
+
res(data);
|
|
171
|
+
});
|
|
172
|
+
request.on('error', (err) => {
|
|
173
|
+
if (err.code && err.code === 'ENOTFOUND') {
|
|
174
|
+
// This is a bit hacky, but this basically returns as a
|
|
175
|
+
// 404 instead of crashing the Node Server with ENOTFOUND
|
|
176
|
+
res({ statusCode: 404 });
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
rej(err);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
rej(err);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
if (!result.statusCode || result.statusCode >= 300) {
|
|
188
|
+
throw 'Unexpected Status: ' + (result.statusCode ?? 'NO_STATUS');
|
|
189
|
+
}
|
|
190
|
+
const contentType = result.headers['content-type'];
|
|
191
|
+
const contentLength = result.headers['content-length'];
|
|
192
|
+
if (!contentType) {
|
|
193
|
+
throw 'Proxied Response does not contain a Content Type';
|
|
194
|
+
}
|
|
195
|
+
if (!contentLength) {
|
|
196
|
+
throw 'Proxied Response does not contain a Content Length';
|
|
197
|
+
}
|
|
198
|
+
if (!isResultOfAllowedResourceType(contentType.toString(), config.allowedMimeTypes ?? [])) {
|
|
199
|
+
throw 'Proxied response has blocked content-type: ' + contentType;
|
|
200
|
+
}
|
|
201
|
+
// Prepare Response
|
|
202
|
+
for (const key in result.headers) {
|
|
203
|
+
const header = result.headers[key];
|
|
204
|
+
if (header === undefined) {
|
|
205
|
+
console.warn('Proxy: Received Header is empty. Skipping…');
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
res.setHeader(key, header);
|
|
209
|
+
}
|
|
210
|
+
res.addListener('error', () => {
|
|
211
|
+
console.log('Proxy: Connection Reset');
|
|
212
|
+
});
|
|
213
|
+
res.setHeader('x-proxy-destination', sourceUrl.toString());
|
|
214
|
+
// Don't store on the server, just immediately pass on the
|
|
215
|
+
// received chunks
|
|
216
|
+
result.pipe(res);
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=corsProxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"corsProxy.js","sourceRoot":"","sources":["../../src/partials/corsProxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.editorPlugin = editorPlugin;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function editorPlugin({ editor, projects }) {
|
|
10
|
+
const editorPath = path_1.default.dirname(require.resolve(editor));
|
|
11
|
+
const editorFile = fs_1.default.readFileSync(path_1.default.resolve(editorPath, 'editor.html'));
|
|
12
|
+
const htmlParts = editorFile
|
|
13
|
+
.toString()
|
|
14
|
+
.replace('{{style}}', `/@fs/${path_1.default.resolve(editorPath, 'style.css')}`)
|
|
15
|
+
.split('{{source}}');
|
|
16
|
+
const createHtml = (src) => htmlParts[0] + src + htmlParts[1];
|
|
17
|
+
const resolvedEditorId = '\0virtual:editor';
|
|
18
|
+
const lookup = new Map();
|
|
19
|
+
for (const project of projects) {
|
|
20
|
+
lookup.set(project.url, project);
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
name: 'motion-canvas:editor',
|
|
24
|
+
async load(id) {
|
|
25
|
+
const [, query] = id.split('?');
|
|
26
|
+
if (id.startsWith(resolvedEditorId)) {
|
|
27
|
+
if (projects.length === 1) {
|
|
28
|
+
/* language=typescript */
|
|
29
|
+
return `\
|
|
30
|
+
import {editor} from '${editor}';
|
|
31
|
+
import project from '${projects[0].filePath}?project';
|
|
32
|
+
editor(project);
|
|
33
|
+
`;
|
|
34
|
+
}
|
|
35
|
+
if (query) {
|
|
36
|
+
const params = new URLSearchParams(query);
|
|
37
|
+
const name = params.get('project');
|
|
38
|
+
if (name && lookup.has(name)) {
|
|
39
|
+
/* language=typescript */
|
|
40
|
+
return `\
|
|
41
|
+
import {editor} from '${editor}';
|
|
42
|
+
import project from '${lookup.get(name).filePath}?project';
|
|
43
|
+
editor(project);
|
|
44
|
+
`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/* language=typescript */
|
|
48
|
+
return `\
|
|
49
|
+
import {index} from '${editor}';
|
|
50
|
+
index(${JSON.stringify(projects)});
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
configureServer(server) {
|
|
55
|
+
server.middlewares.use((req, res, next) => {
|
|
56
|
+
if (req.url) {
|
|
57
|
+
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
58
|
+
if (url.pathname === '/') {
|
|
59
|
+
res.setHeader('Content-Type', 'text/html');
|
|
60
|
+
res.end(createHtml('/@id/__x00__virtual:editor'));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const name = url.pathname.slice(1);
|
|
64
|
+
if (name && lookup.has(name)) {
|
|
65
|
+
res.setHeader('Content-Type', 'text/html');
|
|
66
|
+
res.end(createHtml(`/@id/__x00__virtual:editor?project=${encodeURIComponent(name)}`));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
next();
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/partials/editor.ts"],"names":[],"mappings":"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"}
|