mirror of https://github.com/langgenius/dify.git
Merge remote-tracking branch 'origin/main' into feat/trigger
This commit is contained in:
commit
5cf4afd7b2
|
|
@ -14,10 +14,25 @@ from services.file_service import FileService
|
|||
|
||||
@files_ns.route("/<uuid:file_id>/image-preview")
|
||||
class ImagePreviewApi(Resource):
|
||||
"""
|
||||
Deprecated
|
||||
"""
|
||||
"""Deprecated endpoint for retrieving image previews."""
|
||||
|
||||
@files_ns.doc("get_image_preview")
|
||||
@files_ns.doc(description="Retrieve a signed image preview for a file")
|
||||
@files_ns.doc(
|
||||
params={
|
||||
"file_id": "ID of the file to preview",
|
||||
"timestamp": "Unix timestamp used in the signature",
|
||||
"nonce": "Random string used in the signature",
|
||||
"sign": "HMAC signature verifying the request",
|
||||
}
|
||||
)
|
||||
@files_ns.doc(
|
||||
responses={
|
||||
200: "Image preview returned successfully",
|
||||
400: "Missing or invalid signature parameters",
|
||||
415: "Unsupported file type",
|
||||
}
|
||||
)
|
||||
def get(self, file_id):
|
||||
file_id = str(file_id)
|
||||
|
||||
|
|
@ -43,6 +58,25 @@ class ImagePreviewApi(Resource):
|
|||
|
||||
@files_ns.route("/<uuid:file_id>/file-preview")
|
||||
class FilePreviewApi(Resource):
|
||||
@files_ns.doc("get_file_preview")
|
||||
@files_ns.doc(description="Download a file preview or attachment using signed parameters")
|
||||
@files_ns.doc(
|
||||
params={
|
||||
"file_id": "ID of the file to preview",
|
||||
"timestamp": "Unix timestamp used in the signature",
|
||||
"nonce": "Random string used in the signature",
|
||||
"sign": "HMAC signature verifying the request",
|
||||
"as_attachment": "Whether to download the file as an attachment",
|
||||
}
|
||||
)
|
||||
@files_ns.doc(
|
||||
responses={
|
||||
200: "File stream returned successfully",
|
||||
400: "Missing or invalid signature parameters",
|
||||
404: "File not found",
|
||||
415: "Unsupported file type",
|
||||
}
|
||||
)
|
||||
def get(self, file_id):
|
||||
file_id = str(file_id)
|
||||
|
||||
|
|
@ -101,6 +135,20 @@ class FilePreviewApi(Resource):
|
|||
|
||||
@files_ns.route("/workspaces/<uuid:workspace_id>/webapp-logo")
|
||||
class WorkspaceWebappLogoApi(Resource):
|
||||
@files_ns.doc("get_workspace_webapp_logo")
|
||||
@files_ns.doc(description="Fetch the custom webapp logo for a workspace")
|
||||
@files_ns.doc(
|
||||
params={
|
||||
"workspace_id": "Workspace identifier",
|
||||
}
|
||||
)
|
||||
@files_ns.doc(
|
||||
responses={
|
||||
200: "Logo returned successfully",
|
||||
404: "Webapp logo not configured",
|
||||
415: "Unsupported file type",
|
||||
}
|
||||
)
|
||||
def get(self, workspace_id):
|
||||
workspace_id = str(workspace_id)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,26 @@ from extensions.ext_database import db as global_db
|
|||
|
||||
@files_ns.route("/tools/<uuid:file_id>.<string:extension>")
|
||||
class ToolFileApi(Resource):
|
||||
@files_ns.doc("get_tool_file")
|
||||
@files_ns.doc(description="Download a tool file by ID using signed parameters")
|
||||
@files_ns.doc(
|
||||
params={
|
||||
"file_id": "Tool file identifier",
|
||||
"extension": "Expected file extension",
|
||||
"timestamp": "Unix timestamp used in the signature",
|
||||
"nonce": "Random string used in the signature",
|
||||
"sign": "HMAC signature verifying the request",
|
||||
"as_attachment": "Whether to download the file as an attachment",
|
||||
}
|
||||
)
|
||||
@files_ns.doc(
|
||||
responses={
|
||||
200: "Tool file stream returned successfully",
|
||||
403: "Forbidden - invalid signature",
|
||||
404: "File not found",
|
||||
415: "Unsupported file type",
|
||||
}
|
||||
)
|
||||
def get(self, file_id, extension):
|
||||
file_id = str(file_id)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
"dev": "cross-env NODE_OPTIONS='--inspect' next dev --turbopack",
|
||||
"build": "next build",
|
||||
"build:docker": "next build && node scripts/optimize-standalone.js",
|
||||
"start": "cp -r .next/static .next/standalone/.next/static && cp -r public .next/standalone/public && cross-env PORT=$npm_config_port HOSTNAME=$npm_config_host node .next/standalone/server.js",
|
||||
"start": "node ./scripts/copy-and-start.mjs",
|
||||
"lint": "eslint --cache --cache-location node_modules/.cache/eslint/.eslint-cache",
|
||||
"lint:fix": "eslint --cache --cache-location node_modules/.cache/eslint/.eslint-cache --fix",
|
||||
"lint:quiet": "eslint --cache --cache-location node_modules/.cache/eslint/.eslint-cache --quiet",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* This script copies static files to the target directory and starts the server.
|
||||
* It is intended to be used as a replacement for `next start`.
|
||||
*/
|
||||
|
||||
import { cp, mkdir, stat } from 'node:fs/promises'
|
||||
import { spawn } from 'node:child_process'
|
||||
import path from 'node:path'
|
||||
|
||||
// Configuration for directories to copy
|
||||
const DIRS_TO_COPY = [
|
||||
{
|
||||
src: path.join('.next', 'static'),
|
||||
dest: path.join('.next', 'standalone', '.next', 'static'),
|
||||
},
|
||||
{
|
||||
src: 'public',
|
||||
dest: path.join('.next', 'standalone', 'public'),
|
||||
},
|
||||
]
|
||||
|
||||
// Path to the server script
|
||||
const SERVER_SCRIPT_PATH = path.join('.next', 'standalone', 'server.js')
|
||||
|
||||
// Function to check if a path exists
|
||||
const pathExists = async (path) => {
|
||||
try {
|
||||
console.debug(`Checking if path exists: ${path}`)
|
||||
await stat(path)
|
||||
console.debug(`Path exists: ${path}`)
|
||||
return true
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.warn(`Path does not exist: ${path}`)
|
||||
return false
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// Function to recursively copy directories
|
||||
const copyDir = async (src, dest) => {
|
||||
console.debug(`Copying directory from ${src} to ${dest}`)
|
||||
await cp(src, dest, { recursive: true })
|
||||
console.info(`Successfully copied ${src} to ${dest}`)
|
||||
}
|
||||
|
||||
// Process each directory copy operation
|
||||
const copyAllDirs = async () => {
|
||||
console.debug('Starting directory copy operations')
|
||||
for (const { src, dest } of DIRS_TO_COPY) {
|
||||
try {
|
||||
// Instead of pre-creating destination directory, we ensure parent directory exists
|
||||
const destParent = path.dirname(dest)
|
||||
console.debug(`Ensuring destination parent directory exists: ${destParent}`)
|
||||
await mkdir(destParent, { recursive: true })
|
||||
if (await pathExists(src)) {
|
||||
await copyDir(src, dest)
|
||||
}
|
||||
else {
|
||||
console.error(`Error: ${src} directory does not exist. This is a required build artifact.`)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error(`Error processing ${src}:`, err.message)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
console.debug('Finished directory copy operations')
|
||||
}
|
||||
|
||||
// Run copy operations and start server
|
||||
const main = async () => {
|
||||
console.debug('Starting copy-and-start script')
|
||||
await copyAllDirs()
|
||||
|
||||
// Start server
|
||||
const port = process.env.npm_config_port || process.env.PORT || '3000'
|
||||
const host = process.env.npm_config_host || process.env.HOSTNAME || '0.0.0.0'
|
||||
|
||||
console.info(`Starting server on ${host}:${port}`)
|
||||
console.debug(`Server script path: ${SERVER_SCRIPT_PATH}`)
|
||||
console.debug(`Environment variables - PORT: ${port}, HOSTNAME: ${host}`)
|
||||
|
||||
const server = spawn(
|
||||
process.execPath,
|
||||
[SERVER_SCRIPT_PATH],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
PORT: port,
|
||||
HOSTNAME: host,
|
||||
},
|
||||
stdio: 'inherit',
|
||||
},
|
||||
)
|
||||
|
||||
server.on('error', (err) => {
|
||||
console.error('Failed to start server:', err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
server.on('exit', (code) => {
|
||||
console.debug(`Server exited with code: ${code}`)
|
||||
process.exit(code || 0)
|
||||
})
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error('Unexpected error:', err)
|
||||
process.exit(1)
|
||||
})
|
||||
Loading…
Reference in New Issue