unframer 0.6.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/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "unframer",
3
+ "version": "0.6.0",
4
+ "description": "",
5
+ "type": "module",
6
+ "repository": "https://github.com/remorses/unframer",
7
+ "bin": "bin.mjs",
8
+ "files": [
9
+ "dist",
10
+ "framer-fixed",
11
+ "bin.mjs",
12
+ "src",
13
+ "README.md",
14
+ "esm"
15
+ ],
16
+ "exports": {
17
+ "./dist/framer": {
18
+ "default": "./dist/framer.js"
19
+ },
20
+ "./dist/react": {
21
+ "default": "./dist/react.js"
22
+ }
23
+ },
24
+ "keywords": [],
25
+ "author": "Tommaso De Rossi, morse <beats.by.morse@gmail.com>",
26
+ "license": "",
27
+ "peerDependencies": {
28
+ "react": "*",
29
+ "react-dom": "*"
30
+ },
31
+ "dependencies": {
32
+ "@juggle/resize-observer": "^3.3.1",
33
+ "chokidar": "^3.5.3",
34
+ "csstype": "^3.1.2",
35
+ "dprint-node": "^1.0.8",
36
+ "esbuild": "^0.20.2",
37
+ "esbuild-plugin-polyfill-node": "^0.3.0",
38
+ "eventemitter3": "^3.1.0",
39
+ "find-up": "^6.3.0",
40
+ "fontfaceobserver": "^2.1.0",
41
+ "framer-motion": "11.0.13",
42
+ "fs-extra": "^11.1.1",
43
+ "hey-listen": "^1.0.8",
44
+ "hoist-non-react-statics": "^3.3.2",
45
+ "hsluv": "^0.0.3",
46
+ "native-fetch": "^4.0.2",
47
+ "picocolors": "^1.0.0",
48
+ "popmotion": "^11.0.5",
49
+ "style-value-types": "^5.1.2",
50
+ "tmp": "^0.2.1",
51
+ "undici": "^5.22.1"
52
+ },
53
+ "devDependencies": {
54
+ "@types/fs-extra": "^11.0.1",
55
+ "@types/node": "^20.5.7",
56
+ "react": "^18.2.0",
57
+ "react-dom": "^18.2.0"
58
+ },
59
+ "scripts": {
60
+ "build": "tsc && cp ../README.md ./README.md",
61
+ "watch": "tsc -w"
62
+ }
63
+ }
@@ -0,0 +1,52 @@
1
+ import tmp from 'tmp'
2
+ import path from 'path'
3
+ import { test, expect } from 'vitest'
4
+ import { bundle } from './exporter.js'
5
+
6
+ test(
7
+ 'bundle simple component',
8
+ async () => {
9
+ const tempFolder = tmp.dirSync({ unsafeCleanup: true }).name
10
+ console.log('tempFolder', tempFolder)
11
+ const url =
12
+ 'https://framer.com/m/Logo-Ticker-1CEq.js@YtVlixDzOkypVBs3Dpav'
13
+ await bundle({
14
+ components: {
15
+ ticker: url,
16
+ },
17
+ cwd: tempFolder,
18
+ })
19
+ },
20
+ 1000 * 10,
21
+ )
22
+ test(
23
+ 'issue #1',
24
+ async () => {
25
+ const tempFolder = tmp.dirSync({ unsafeCleanup: true }).name
26
+ console.log('tempFolder', tempFolder)
27
+ const url = 'https://framer.com/m/Item-Qetw.js@vUDyI0yvPLONiBDf8Kzw'
28
+ await bundle({
29
+ components: {
30
+ item: url,
31
+ },
32
+ cwd: tempFolder,
33
+ })
34
+ },
35
+ 1000 * 10,
36
+ )
37
+ test(
38
+ 'bundle ticker variant',
39
+ async () => {
40
+ const tempFolder = tmp.dirSync({ unsafeCleanup: true }).name
41
+ console.log('tempFolder', tempFolder)
42
+ const url =
43
+ 'https://framer.com/m/Brand-Logo-Ticker-Uc8E.js@WLfLN2D3C6m9DWtZu0ci'
44
+ await bundle({
45
+ components: {
46
+ logos: url,
47
+ },
48
+ cwd: tempFolder,
49
+ })
50
+ },
51
+ 1000 * 10,
52
+ )
package/src/cli.tsx ADDED
@@ -0,0 +1,114 @@
1
+ import { bundle, logger } from './exporter.js'
2
+ import chokidar from 'chokidar'
3
+ import fs from 'fs-extra'
4
+ import { findUp } from 'find-up'
5
+ import tmp from 'tmp'
6
+ import path from 'path'
7
+ const configName = 'unframer.json'
8
+
9
+ const __dirname = path.dirname(new URL(import.meta.url).pathname)
10
+
11
+ export async function cli() {
12
+ const cwd = process.cwd()
13
+ const watch = process.argv.includes('--watch')
14
+ logger.log(`Looking for ${configName} in ${cwd}`)
15
+ const configPath = await findUp([configName], { cwd })
16
+ if (!configPath) {
17
+ logger.log(`No ${configName} found`)
18
+ return
19
+ }
20
+ const configContent = fs.readFileSync(configPath, 'utf8')
21
+ if (!configContent) {
22
+ logger.log(`No ${configName} contents found`)
23
+ return
24
+ }
25
+ let config = JSON.parse(configContent)
26
+
27
+ await processConfig(config)
28
+ if (watch) {
29
+ const watcher = chokidar.watch(configPath, {
30
+ persistent: true,
31
+ })
32
+ let controller = new AbortController()
33
+
34
+ watcher.on('change', async (path) => {
35
+ console.log()
36
+ controller.abort()
37
+ controller = new AbortController()
38
+
39
+ const newConfig = safeJsonParse(fs.readFileSync(configPath, 'utf8'))
40
+ if (!newConfig) {
41
+ logger.log(`Invalid ${configName} file`)
42
+ return
43
+ }
44
+ const newNames = getNewNames(config, newConfig)
45
+ if (newNames.length) {
46
+ logger.log(`New components found: ${newNames.join(', ')}`)
47
+ await processConfig(
48
+ {
49
+ ...newConfig,
50
+ components: pluck(newConfig.components, newNames),
51
+ },
52
+ controller.signal,
53
+ )
54
+ }
55
+ config = newConfig
56
+ })
57
+ }
58
+ }
59
+ function safeJsonParse(json: string) {
60
+ try {
61
+ return JSON.parse(json)
62
+ } catch (e) {
63
+ return null
64
+ }
65
+ }
66
+
67
+ function pluck<T, K extends keyof T>(o: T, names: K[]): { [k: string]: T[K] } {
68
+ return Object.fromEntries(names.map((n) => [n, o[n]]))
69
+ }
70
+
71
+ function getNewNames(oldConfig: Config, newConfig: Config) {
72
+ // get the new names, also check if the previous url (object value) has changed
73
+ const oldKeys = Object.keys(oldConfig.components)
74
+ const newKeys = Object.keys(newConfig.components)
75
+ const newNames = newKeys.filter((key) => {
76
+ if (!oldKeys.includes(key)) {
77
+ return true
78
+ }
79
+ if (oldConfig.components[key] !== newConfig.components[key]) {
80
+ return true
81
+ }
82
+ return false
83
+ })
84
+ return newNames
85
+ }
86
+
87
+ type Config = {
88
+ components: {
89
+ [name: string]: string
90
+ }
91
+ outDir?: string
92
+ }
93
+ async function processConfig(config: Config, signal?: AbortSignal) {
94
+ try {
95
+ const { components, outDir } = config || {}
96
+ const installDir = path.resolve(process.cwd(), outDir || 'framer')
97
+ if (!components) {
98
+ logger.log(`No components found in ${configName}`)
99
+ return
100
+ }
101
+
102
+ await bundle({
103
+ components,
104
+ cwd: installDir,
105
+ signal,
106
+ })
107
+ } catch (e: any) {
108
+ if (signal) {
109
+ logger.log('Error processing config', e.message)
110
+ return
111
+ }
112
+ throw e
113
+ }
114
+ }