uploadcare binding problems

This commit is contained in:
Chaebean Yang 2025-06-08 01:35:44 +09:00
parent 32c0b6135e
commit 4418783441
3 changed files with 420 additions and 173 deletions

352
package-lock.json generated
View File

@ -9,11 +9,13 @@
"version": "0.0.1", "version": "0.0.1",
"dependencies": { "dependencies": {
"@googlemaps/js-api-loader": "^1.16.8", "@googlemaps/js-api-loader": "^1.16.8",
"@uploadcare/file-uploader": "^1.16.2",
"d3": "^7.9.0", "d3": "^7.9.0",
"firebase": "^11.9.0", "firebase": "^11.9.0",
"openai": "^5.1.1", "openai": "^5.1.1",
"topojson-client": "^3.1.0", "topojson-client": "^3.1.0",
"topojson-server": "^3.0.1" "topojson-server": "^3.0.1",
"uploadcare": "^0.4.8"
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/adapter-auto": "^6.0.0",
@ -1610,6 +1612,12 @@
"vite": "^6.0.0" "vite": "^6.0.0"
} }
}, },
"node_modules/@symbiotejs/symbiote": {
"version": "1.11.7",
"resolved": "https://registry.npmjs.org/@symbiotejs/symbiote/-/symbiote-1.11.7.tgz",
"integrity": "sha512-fUOJwzuldeApJ533YeTdrfnpp4nsA+ss1eiNBodX7RHf4LnhPB2Z9HP4fF3m2YhKYnxK0whjXaKA+wrxTRP5qA==",
"license": "MIT"
},
"node_modules/@types/cookie": { "node_modules/@types/cookie": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
@ -1963,6 +1971,37 @@
"@types/geojson": "*" "@types/geojson": "*"
} }
}, },
"node_modules/@uploadcare/file-uploader": {
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/@uploadcare/file-uploader/-/file-uploader-1.16.2.tgz",
"integrity": "sha512-Uydx5Wdmhj8sCWNAeBnzC0+EtwxlKzI60yb+XSS6lvbp2lC3NShnzPNbkvoS6M6wW/EQZWKKiJnUM/3P9+MDWw==",
"license": "MIT",
"dependencies": {
"@symbiotejs/symbiote": "^1.11.7",
"@uploadcare/image-shrink": "^6.14.1",
"@uploadcare/upload-client": "^6.14.1",
"keyux": "^0.7.1"
}
},
"node_modules/@uploadcare/image-shrink": {
"version": "6.14.3",
"resolved": "https://registry.npmjs.org/@uploadcare/image-shrink/-/image-shrink-6.14.3.tgz",
"integrity": "sha512-GCZOewwaGdU/FXgK8m1Ct6FHF7CH3LUGcBvsUxPrablkV2Dyl99XdMtyomaZgpsyfRDlVUbvkntDXEB3IZo92A==",
"license": "MIT"
},
"node_modules/@uploadcare/upload-client": {
"version": "6.14.3",
"resolved": "https://registry.npmjs.org/@uploadcare/upload-client/-/upload-client-6.14.3.tgz",
"integrity": "sha512-uZDXb2IuFchpNQdHDxDowKgGPd+9UOy0PIykWEPedMbbBYxh7/UUQ+G53E4KhKe7cV7BV4zoFxUrNx+Ij0lyPw==",
"license": "MIT",
"dependencies": {
"form-data": "^4.0.0",
"ws": "^8.2.3"
},
"engines": {
"node": ">=16"
}
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.14.1", "version": "8.14.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
@ -2037,6 +2076,18 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==",
"license": "MIT"
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/axobject-query": { "node_modules/axobject-query": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@ -2091,6 +2142,19 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/chokidar": { "node_modules/chokidar": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
@ -2149,6 +2213,18 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": { "node_modules/commander": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
@ -2613,6 +2689,15 @@
"robust-predicates": "^3.0.2" "robust-predicates": "^3.0.2"
} }
}, },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/devalue": { "node_modules/devalue": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz",
@ -2620,12 +2705,71 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.25.4", "version": "0.25.4",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz",
@ -2769,6 +2913,22 @@
"@firebase/util": "1.12.0" "@firebase/util": "1.12.0"
} }
}, },
"node_modules/form-data": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
"integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fsevents": { "node_modules/fsevents": {
"version": "2.3.3", "version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@ -2784,6 +2944,15 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0" "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
} }
}, },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-caller-file": { "node_modules/get-caller-file": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@ -2793,6 +2962,43 @@
"node": "6.* || 8.* || >= 10.*" "node": "6.* || 8.* || >= 10.*"
} }
}, },
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/glob-parent": { "node_modules/glob-parent": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@ -2806,6 +3012,18 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-flag": { "node_modules/has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@ -2816,6 +3034,45 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/http-parser-js": { "node_modules/http-parser-js": {
"version": "0.5.10", "version": "0.5.10",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz",
@ -2921,6 +3178,21 @@
"@types/estree": "^1.0.6" "@types/estree": "^1.0.6"
} }
}, },
"node_modules/keyux": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/keyux/-/keyux-0.7.2.tgz",
"integrity": "sha512-Z8ULf9BhSx1hI2rKG2uNjcvMgQmza97ZW2w43phS5VaT4wiTka7tOL4i/GJSc79k65tbvpoTVNCZwam0pqoH6A==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"engines": {
"node": "^18.0.0 || >=20.0.0"
}
},
"node_modules/kleur": { "node_modules/kleur": {
"version": "4.1.5", "version": "4.1.5",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
@ -2960,6 +3232,36 @@
"@jridgewell/sourcemap-codec": "^1.5.0" "@jridgewell/sourcemap-codec": "^1.5.0"
} }
}, },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@ -2973,6 +3275,15 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/mri": { "node_modules/mri": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
@ -3592,6 +3903,24 @@
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/uploadcare": {
"version": "0.4.8",
"resolved": "https://registry.npmjs.org/uploadcare/-/uploadcare-0.4.8.tgz",
"integrity": "sha512-XhPOaKfM5hq27nbOCfN9BiGYtirRxPiNq6/PoOKNmmq6rlCGeuUGckoI4iR0CuH6Th0KIQ91wRLpl0Rg2L2YNw==",
"deprecated": "Please see https://www.npmjs.com/package/uploadcare#readme",
"dependencies": {
"async": "^1.5.2",
"form-data": "latest",
"minimist": "^1.2.0"
},
"bin": {
"uc": "bin/uploadcare.js",
"uploadcare": "bin/uploadcare.js"
},
"engines": {
"node": ">= v0.8.0"
}
},
"node_modules/vite": { "node_modules/vite": {
"version": "6.3.5", "version": "6.3.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
@ -3732,6 +4061,27 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1" "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
} }
}, },
"node_modules/ws": {
"version": "8.18.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz",
"integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/y18n": { "node_modules/y18n": {
"version": "5.0.8", "version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

View File

@ -27,10 +27,12 @@
}, },
"dependencies": { "dependencies": {
"@googlemaps/js-api-loader": "^1.16.8", "@googlemaps/js-api-loader": "^1.16.8",
"@uploadcare/file-uploader": "^1.16.2",
"d3": "^7.9.0", "d3": "^7.9.0",
"firebase": "^11.9.0", "firebase": "^11.9.0",
"openai": "^5.1.1", "openai": "^5.1.1",
"topojson-client": "^3.1.0", "topojson-client": "^3.1.0",
"topojson-server": "^3.0.1" "topojson-server": "^3.0.1",
"uploadcare": "^0.4.8"
} }
} }

View File

@ -6,26 +6,32 @@
import { Loader } from '@googlemaps/js-api-loader'; import { Loader } from '@googlemaps/js-api-loader';
import { ref, push, onValue } from 'firebase/database'; import { ref, push, onValue } from 'firebase/database';
import { db } from '../../firebase'; import { db } from '../../firebase';
import * as UC from '@uploadcare/file-uploader';
import "@uploadcare/file-uploader/web/uc-file-uploader-regular.min.css"
UC.defineComponents(UC);
export let showPopup = false; export let showPopup = false;
// export let onAddMemory = () => {};
export let onCancel = () => {}; export let onCancel = () => {};
let startDate = ''; let startDate = '';
let endDate = ''; let endDate = '';
let isGoogleLoaded = false; let isGoogleLoaded = false;
let dragActive = false;
let customLocation = ''; let customLocation = '';
let customLocationInput: HTMLInputElement; let customLocationInput: HTMLInputElement;
let images: File[] = [];
let showLocationError = false; let showLocationError = false;
let showImageError = false; let showImageError = false;
let hasAttemptedSubmit = false; let hasAttemptedSubmit = false;
let isFormValid = true; let isFormValid = true;
let selectedTripId = ''; //for dropdown let selectedTripId = ''; //for dropdown
let selectedLocation = ''; let selectedLocation = '';
let uploaderCtxEl: HTMLElement;
let uploaderCtx: any;
let tripOptions: { value: string; label: string }[] = []; let tripOptions: { value: string; label: string }[] = [];
let uploadedImageURLs: string[] = [];
onMount(() => { onMount(() => {
// reference to the trips node // reference to the trips node
@ -50,18 +56,28 @@
}); });
}); });
$: if (uploaderCtx) {
uploaderCtx.on('change', () => {
const urls = uploaderCtx.files().map(file => file?.cdnUrl).filter(Boolean);
uploadedImageURLs = urls;
console.log('uploadedImageURLs:', uploadedImageURLs);
$: if (hasAttemptedSubmit) { if (uploadedImageURLs.length > 0) {
isFormValid = ( showImageError = false;
(selectedLocation !== '' && (!isCustomLocation() || customLocation.trim() !== '')) && hasAttemptedSubmit = true;
images.length > 0
);
} }
});
}
$: isFormValid = (
(selectedLocation !== '' && (!isCustomLocation() || customLocation.trim() !== '')) &&
uploadedImageURLs.length > 0
);
$: if (selectedTripId && selectedTripId !== 'custom') { $: if (selectedTripId && selectedTripId !== 'custom') {
const trip = tripOptions.find(t => t.value === selectedTripId); const trip = tripOptions.find(t => t.value === selectedTripId);
if (trip) { if (trip) {
selectedLocation = trip.label.split(' (')[0]; // label에서 name 추출 selectedLocation = trip.label.split(' (')[0];
const tripRef = ref(db, `trips/${selectedTripId}`); const tripRef = ref(db, `trips/${selectedTripId}`);
onValue(tripRef, (snapshot) => { onValue(tripRef, (snapshot) => {
const val = snapshot.val(); const val = snapshot.val();
@ -111,12 +127,16 @@
}); });
} }
function handleFiles(files: FileList) { function reset() {
for (const file of files) { showPopup = false;
if (file.type.startsWith('image/')) { selectedLocation = '';
images = [...images, file]; customLocation = '';
} startDate = '';
} endDate = '';
showLocationError = false;
showImageError = false;
uploadedImageURLs = [];
hasAttemptedSubmit = false;
} }
function handleCancelClick() { function handleCancelClick() {
@ -124,38 +144,11 @@
reset(); reset();
} }
function handleDrop(event: DragEvent) {
event.preventDefault();
dragActive = false;
handleFiles(event.dataTransfer!.files);
}
function handleDragOver(event: DragEvent) {
event.preventDefault();
dragActive = true;
}
function handleDragLeave(event: DragEvent) {
event.preventDefault();
dragActive = false;
}
function handleInputChange(event: Event) {
const target = event.target as HTMLInputElement;
if (target.files) {
handleFiles(target.files);
}
}
function removeImage(imageToRemove: File) {
images = images.filter(img => img !== imageToRemove);
}
async function handleAddMemory() { async function handleAddMemory() {
hasAttemptedSubmit = true; hasAttemptedSubmit = true;
showLocationError = selectedLocation === '' || (isCustomLocation() && customLocation.trim() === ''); showLocationError = selectedLocation === '' || (isCustomLocation() && customLocation.trim() === '');
showImageError = images.length === 0; showImageError = uploadedImageURLs.length === 0;
if (showLocationError || showImageError) return; if (showLocationError || showImageError) return;
@ -166,7 +159,7 @@
location: finalLocation, location: finalLocation,
startDate, startDate,
endDate, endDate,
images: images.map(file => URL.createObjectURL(file)), images: uploadedImageURLs,
createdAt: new Date().toISOString() createdAt: new Date().toISOString()
}; };
try { try {
@ -176,8 +169,7 @@
location: finalLocation, location: finalLocation,
startDate: startDate, startDate: startDate,
endDate: endDate, endDate: endDate,
// TODO: change this to use non-local URL images: uploadedImageURLs,
images: images.map(file => URL.createObjectURL(file)),
createdAt: new Date().toISOString() createdAt: new Date().toISOString()
}; };
const addedRef = await push(memoryRef, newMemory); const addedRef = await push(memoryRef, newMemory);
@ -189,18 +181,6 @@
} }
} }
function reset() {
showPopup = false;
selectedLocation = '';
customLocation = '';
images = [];
startDate = '';
endDate = '';
showLocationError = false;
showImageError = false;
}
const locations = ['Paris', 'Tokyo', 'New York'];
</script> </script>
{#if showPopup} {#if showPopup}
@ -257,41 +237,28 @@
<p class="error-message">Please enter a location.</p> <p class="error-message">Please enter a location.</p>
{/if} {/if}
<div class="input-form"> <div class="input-form uploader-wrapper">
<!-- svelte-ignore a11y_label_has_associated_control -->
<label>Upload images</label> <label>Upload images</label>
<div class="drop-area {dragActive ? 'active' : ''}" <uc-config
role="button" ctx-name="my-uploader"
tabindex="0" source-list="local, camera, gdrive"
on:drop={handleDrop} pubkey="d4067f33e4ac8363f078"
on:dragover={handleDragOver} multiple="true"
on:dragleave={handleDragLeave} multiple-min= 1
>
<input ></uc-config>
type="file"
accept="image/*" <uc-file-uploader-minimal
multiple ctx-name="my-uploader"
on:change={handleInputChange} class="uc-dark uc-gray"
style="display: none;" ></uc-file-uploader-minimal>
id="fileInput"
/> <uc-upload-ctx-provider
<!-- svelte-ignore a11y_click_events_have_key_events --> ctx-name="my-uploader"
<div class="drop-label" role="button" tabindex="0" on:click={() => document.getElementById('fileInput')?.click()}> bind:this={uploaderCtxEl}
{#if images.length === 0} bind:ctx={uploaderCtx}
<span>Drop image here</span> ></uc-upload-ctx-provider>
{:else}
<div class="preview-list">
{#each images as img}
<div class="preview-item">
<button class="delete-button" on:click={() => removeImage(img)}>×</button>
<img src={URL.createObjectURL(img)} alt={img.name} />
<p>{img.name}</p>
</div>
{/each}
</div>
{/if}
</div>
</div>
{#if showImageError} {#if showImageError}
<p class="error-message">Please upload at least one image.</p> <p class="error-message">Please upload at least one image.</p>
{/if} {/if}
@ -301,7 +268,7 @@
<Button text="Cancel" type="gray" onClick={handleCancelClick} /> <Button text="Cancel" type="gray" onClick={handleCancelClick} />
<Button text="Add a new memory" type="orange" <Button text="Add a new memory" type="orange"
onClick={handleAddMemory} onClick={handleAddMemory}
disabled={hasAttemptedSubmit && !isFormValid}/> disabled={!isFormValid}/>
</div> </div>
</div> </div>
</div> </div>
@ -404,78 +371,6 @@
margin-bottom: 0; margin-bottom: 0;
} }
.preview-list {
display: flex;
flex-wrap: wrap;
gap: 1rem;
max-height: 200px;
overflow-y: auto;
padding-right: 0.5rem;
}
.preview-item {
position: relative;
width: 80px;
display: flex;
flex-direction: column;
align-items: center;
}
.preview-item img {
width: 100%;
border-radius: 6px;
object-fit: cover;
}
.preview-item p {
font-size: 0.75rem;
text-align: center;
margin-top: 0.3rem;
color: var(--gray-400);
}
.delete-button {
position: absolute;
top: 4px;
right: 4px;
background: rgba(38, 38, 38, 0.5);
border: none;
color: var(--white);
border-radius: 50%;
width: 18px;
height: 18px;
font-size: 0.9rem;
cursor: pointer;
z-index: 2;
}
.drop-area {
width: 100%;
min-height: 120px;
background: var(--gray-900);
border: 1px solid var(--gray-200);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: var(--white);
transition: border-color 0.2s;
cursor: pointer;
}
.drop-area.active {
border-color: var(--memory-500);
color: var(--memory-500);
}
.drop-label {
padding: 2rem 1rem;
text-align: center;
width: 100%;
cursor: pointer;
}
option.custom-option { option.custom-option {
color: var(--memory-500); color: var(--memory-500);
} }