/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* @file misc.ts
* @description 各種通用類型的定義
*/
export type RequestMethod = 'POST' | 'GET' | 'DELETE' | 'PATCH' | 'PUT';
export type RequestOptions = {
method: RequestMethod;
headers?: Record<string, string>;
cache?: RequestCache;
params?: Record<string, any>;
body?: string;
data?: any;
};
/* eslint-disable @typescript-eslint/no-explicit-any */
"use server";
import { ApiLocales } from '@/configs/i18n';
import { RequestOptions } from './types/misc';
import { cookies, headers } from 'next/headers';
import UnauthorizedError from '@/errors/UnauthorizedError';
export async function request<T = any>(url: string, opts: RequestOptions = { method: 'GET' }): Promise<T> {
const apiDomain = process.env.NEXT_PUBLIC_ZEUSCMS_API_URL;
const cookieManager = cookies();
const head = headers();
const locale = head.get("locale");
url = `${apiDomain}${url}`;
// 如果沒有設定緩存策略,則預設啟用 no-cache
if (!opts.cache) {
opts.cache = 'no-cache';
}
// 如果有設置 params,則將其轉換為 query string
if (opts.params) {
const params = new URLSearchParams(opts.params);
url = `${url}?${params.toString()}`;
delete opts.params;
}
if (opts.data) {
opts.body = JSON.stringify(opts.data);
delete opts.data;
}
const token = cookieManager.get('token');
const Language = ApiLocales[locale as 'en'|'pt'|'zh-hant'|'zh-hans'];
if (token) {
opts.headers = {
...opts.headers,
'Api-Key': token?.value,
'Api-Language': Language
};
}
const response = await fetch(url, { ...opts });
if (response.ok) {
return response.json();
} else {
if (response.status === 401) {
throw new UnauthorizedError();
}
const errorObject: any = { status: response.status, statusText: response.statusText };
try {
errorObject.data = await response.json();
} catch (_) {}
return Promise.reject(errorObject);
}
}
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug server-side",
"type": "node-terminal",
"request": "launch",
"command": "pnpm run start"
},
{
"name": "Next.js: debug client-side",
"type": "node-terminal",
"request": "launch",
"command": "pnpm run dev"
},
{
"name": "Next.js: debug full stack",
"type": "node-terminal",
"request": "launch",
"command": "pnpm run dev",
"serverReadyAction": {
"pattern": "- Local:.+(https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}
i18n-convertor.js
const axios = require('axios');
const csv = require('csv-parser');
const fs = require('fs');
const path = require('path');
// Google Sheets CSV 导出链接
const url = '写入你的谷歌文档链接';
// 目标文件夹路径
const outputDir = path.join(__dirname, '/src/locales');
console.log('outputDir', outputDir);
// 如果文件夹不存在,则创建它
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir);
}
async function fetchCSV() {
try {
const response = await axios.get(url, {
responseType: 'stream'
});
const languages = {
zh: {},
pt: {},
en: {}
};
response.data
.pipe(csv())
.on('data', row => {
const key = row['key'];
const keys = key.split('.'); // 按照 '.' 分割键
// 选择语言并填充数据
const langKeys = ['zh_TW', 'pt_PT', 'en'];
langKeys.forEach(lang => {
let current = languages[lang.slice(0, 2)]; // 获取对应语言的对象
keys.forEach((k, index) => {
if (index === keys.length - 1) {
// 如果是最后一个键,赋值
current[k] = row[lang];
} else {
// 如果不是最后一个键,确保对象存在
if (!current[k]) {
current[k] = {};
}
current = current[k]; // 进入下一个层级
}
});
});
})
.on('end', () => {
// 保存文件到 messages 目录下
fs.writeFileSync(path.join(outputDir, 'zh.json'), JSON.stringify(languages.zh, null, 2));
fs.writeFileSync(path.join(outputDir, 'pt.json'), JSON.stringify(languages.pt, null, 2));
fs.writeFileSync(path.join(outputDir, 'en.json'), JSON.stringify(languages.en, null, 2));
console.log('JSON files have been saved to the messages directory!');
});
} catch (error) {
console.error('Error fetching the CSV:', error);
}
}
fetchCSV();
- 搜索引擎:devv
- 编辑器:vscode
- 截图:Snipaste
- Branch:Sourcetree
- MD编辑器:Typora
- NVM:nvm-desktop
- 终端模拟器: