Compare commits
2 Commits
renovate/l
...
rolldown-v
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e82b8575d1 | ||
![]() |
3b76e57df5 |
29
.github/workflows/ci-cd.yaml
vendored
29
.github/workflows/ci-cd.yaml
vendored
@@ -12,7 +12,7 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
lint-build-and-typecheck:
|
||||
runs-on: ubuntu-latest
|
||||
container: gitea/runner-images:ubuntu-latest-slim # https://github.com/cloudflare/wrangler-action/issues/329#issuecomment-3046747722
|
||||
|
||||
@@ -44,8 +44,33 @@ jobs:
|
||||
- name: ✅ 类型检查
|
||||
run: pnpm run type-check # 要先 build,保证 components.d.ts 存在
|
||||
|
||||
- name: 🚀 部署到 Cloudflare
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
needs: lint-build-and-typecheck
|
||||
if: github.ref == 'refs/heads/main'
|
||||
|
||||
# https://github.com/cloudflare/wrangler-action/issues/329#issuecomment-3046747722
|
||||
container:
|
||||
image: gitea/runner-images:ubuntu-latest-slim
|
||||
|
||||
steps:
|
||||
- name: 🛠️ 设置Node环境
|
||||
uses: yanhao98/composite-actions/setup-node-environment@25eb4dc0c134cc9df2b7c569aa54140a366b45a8
|
||||
|
||||
- name: 📦 构建项目
|
||||
run: pnpm run build-only
|
||||
env:
|
||||
VITE_BUILD_COMMIT: ${{ github.sha }}
|
||||
|
||||
# - name: 🚀 上传版本到 Cloudflare
|
||||
# uses: cloudflare/wrangler-action@v3
|
||||
# id: upload
|
||||
# with:
|
||||
# apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
# accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
# command: versions upload --tag "${{ github.sha }}" --message "Deploy commit ${{ github.sha }} from ${{ github.ref_name }}"
|
||||
|
||||
- name: 🚀 部署到 Cloudflare
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
|
2
.github/workflows/playwright.yaml
vendored
2
.github/workflows/playwright.yaml
vendored
@@ -18,6 +18,8 @@ jobs:
|
||||
uses: yanhao98/composite-actions/setup-node-environment@25eb4dc0c134cc9df2b7c569aa54140a366b45a8
|
||||
# - name: 📥 安装 Playwright 浏览器
|
||||
# run: pnpm exec playwright install --with-deps
|
||||
- name: 🔄 更新依赖
|
||||
run: pnpm update --latest
|
||||
- name: 📦 构建项目
|
||||
run: pnpm run build-only
|
||||
- name: ▶️ 运行 Playwright 测试
|
||||
|
2
.npmrc
2
.npmrc
@@ -1,4 +1,4 @@
|
||||
# registry=https://registry.npmmirror.com/
|
||||
registry=https://registry.npmmirror.com/
|
||||
|
||||
# https://pnpm.io/zh/npmrc#node-mirrorltreleasedir
|
||||
use-node-version=24.7.0
|
||||
|
@@ -55,5 +55,6 @@ test.describe('Vue App', () => {
|
||||
await page.goto('/')
|
||||
const appLayout = page.locator('.app-layout')
|
||||
await expect(appLayout).toBeVisible()
|
||||
await expect(appLayout).toContainText('AppLayout')
|
||||
})
|
||||
})
|
||||
|
@@ -17,7 +17,7 @@ export default defineConfigWithVueTs(
|
||||
files: ['**/*.{ts,mts,tsx,vue}'],
|
||||
},
|
||||
|
||||
globalIgnores(['worker-configuration.d.ts', '**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
|
||||
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
|
||||
|
||||
pluginVue.configs['flat/essential'],
|
||||
vueTsConfigs.recommended,
|
||||
|
15
package.json
15
package.json
@@ -33,7 +33,6 @@
|
||||
"wrangler:deploy": "pnpm run build && wrangler deploy",
|
||||
"wrangler:versions:upload": "pnpm run build && wrangler versions upload",
|
||||
"cf-typegen": "wrangler types",
|
||||
"postinstall": "wrangler types",
|
||||
"_dep:dedupe": "pnpm dedupe",
|
||||
"_dep:update": "pnpm dlx taze major --interactive",
|
||||
"_sizecheck:Treemap": "pnpm dlx vite-bundle-visualizer -t treemap",
|
||||
@@ -50,7 +49,9 @@
|
||||
]
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {}
|
||||
"overrides": {
|
||||
"vite": "$vite"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@commitlint/cli": "^19.8.1",
|
||||
@@ -70,7 +71,7 @@
|
||||
"vue-router": "^4.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/vite-plugin": "^1.13.2",
|
||||
"@cloudflare/vite-plugin": "^1.12.4",
|
||||
"@commitlint/types": "^19.8.1",
|
||||
"@intlify/unplugin-vue-i18n": "^11.0.0",
|
||||
"@playwright/test": "^1.55.0",
|
||||
@@ -89,7 +90,7 @@
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@vue/tsconfig": "^0.8.1",
|
||||
"eslint": "^9.35.0",
|
||||
"eslint-plugin-oxlint": "~1.15.0",
|
||||
"eslint-plugin-oxlint": "~1.14.0",
|
||||
"eslint-plugin-playwright": "^2.2.2",
|
||||
"eslint-plugin-vue": "~10.4.0",
|
||||
"husky": "^9.1.7",
|
||||
@@ -98,7 +99,7 @@
|
||||
"lint-staged": "^16.1.6",
|
||||
"npm-run-all2": "^8.0.4",
|
||||
"nprogress": "^0.2.0",
|
||||
"oxlint": "~1.15.0",
|
||||
"oxlint": "~1.14.0",
|
||||
"prettier": "3.6.2",
|
||||
"typescript": "~5.9.2",
|
||||
"unocss": "^66.5.1",
|
||||
@@ -108,7 +109,7 @@
|
||||
"unplugin-vue-components": "^29.0.0",
|
||||
"unplugin-vue-markdown": "^29.1.0",
|
||||
"unplugin-vue-router": "^0.15.0",
|
||||
"vite": "^7.1.5",
|
||||
"vite": "npm:rolldown-vite@^7.1.9",
|
||||
"vite-plugin-checker": "^0.10.3",
|
||||
"vite-plugin-fake-server": "^2.2.0",
|
||||
"vite-plugin-image-optimizer": "^2.0.2",
|
||||
@@ -118,6 +119,6 @@
|
||||
"vitest": "^3.2.4",
|
||||
"vue-macros": "3.0.0-beta.23",
|
||||
"vue-tsc": "^3.0.6",
|
||||
"wrangler": "^4.37.1"
|
||||
"wrangler": "^4.35.0"
|
||||
}
|
||||
}
|
||||
|
947
pnpm-lock.yaml
generated
947
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
36
src/App.vue
36
src/App.vue
@@ -11,37 +11,19 @@ const getName = async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="app-container bg-slate-50 min-h-screen">
|
||||
<div class="container mx-auto px-6 py-8">
|
||||
<h1 class="text-4xl font-extrabold text-emerald-600 mb-6 text-center">You did it!</h1>
|
||||
<div class="bg-white rounded-lg shadow-lg p-8 mb-8">
|
||||
<p class="text-lg text-gray-700 mb-6 text-center">
|
||||
Visit
|
||||
<a
|
||||
href="https://vuejs.org/"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="text-emerald-500 hover:text-emerald-700 underline font-semibold"
|
||||
>
|
||||
vuejs.org
|
||||
</a>
|
||||
to read the documentation
|
||||
<div>
|
||||
<h1>You did it!</h1>
|
||||
<p>
|
||||
Visit <a href="https://vuejs.org/" target="_blank" rel="noopener">vuejs.org</a> to read the
|
||||
documentation
|
||||
</p>
|
||||
<div class="flex justify-center">
|
||||
<button
|
||||
class="bg-emerald-500 hover:bg-emerald-600 text-white font-bold py-3 px-6 rounded-lg transition-colors duration-200 shadow-md hover:shadow-lg"
|
||||
@click="getName"
|
||||
aria-label="get name"
|
||||
>
|
||||
<button class="green" @click="getName" aria-label="get name">
|
||||
Name from API is: {{ name }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DynamicDialog />
|
||||
<ConfirmDialog />
|
||||
<Toast />
|
||||
<DynamicDialog /> <ConfirmDialog /> <Toast />
|
||||
<RouterView />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
@@ -1,10 +1,9 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div class="app-layout min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100">
|
||||
<main class="max-w-7xl mx-auto px-4 py-8">
|
||||
<div class="app-layout">
|
||||
<div>AppLayout</div>
|
||||
<router-view />
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@@ -1,31 +1,7 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="hero-section bg-gradient-to-r from-purple-400 via-pink-500 to-red-500 rounded-xl p-8 shadow-2xl"
|
||||
>
|
||||
<div class="text-center">
|
||||
<h2 class="text-3xl font-bold text-white mb-4 animate-bounce">🎉 This is the index page</h2>
|
||||
<p class="text-white/90 text-lg mb-6">Welcome to your awesome Vue.js application!</p>
|
||||
<div class="flex justify-center space-x-4">
|
||||
<div
|
||||
class="bg-white/20 backdrop-blur-sm rounded-lg p-4 hover:bg-white/30 transition-all duration-300"
|
||||
>
|
||||
<span class="text-white font-semibold">Feature 1</span>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white/20 backdrop-blur-sm rounded-lg p-4 hover:bg-white/30 transition-all duration-300"
|
||||
>
|
||||
<span class="text-white font-semibold">Feature 2</span>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white/20 backdrop-blur-sm rounded-lg p-4 hover:bg-white/30 transition-all duration-300"
|
||||
>
|
||||
<span class="text-white font-semibold">Feature 3</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
166
worker-configuration.d.ts
vendored
166
worker-configuration.d.ts
vendored
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable */
|
||||
// Generated by Wrangler by running `wrangler types` (hash: a5d3a0d06638640f4072385a766cb44d)
|
||||
// Runtime types generated with workerd@1.20250906.0 2025-09-09
|
||||
// Runtime types generated with workerd@1.20250902.0 2025-09-09
|
||||
declare namespace Cloudflare {
|
||||
interface Env {
|
||||
KV: KVNamespace;
|
||||
@@ -414,7 +414,7 @@ interface DurableObjectId {
|
||||
equals(other: DurableObjectId): boolean;
|
||||
readonly name?: string;
|
||||
}
|
||||
declare abstract class DurableObjectNamespace<T extends Rpc.DurableObjectBranded | undefined = undefined> {
|
||||
interface DurableObjectNamespace<T extends Rpc.DurableObjectBranded | undefined = undefined> {
|
||||
newUniqueId(options?: DurableObjectNamespaceNewUniqueIdOptions): DurableObjectId;
|
||||
idFromName(name: string): DurableObjectId;
|
||||
idFromString(id: string): DurableObjectId;
|
||||
@@ -432,7 +432,6 @@ interface DurableObjectNamespaceGetDurableObjectOptions {
|
||||
}
|
||||
interface DurableObjectState {
|
||||
waitUntil(promise: Promise<any>): void;
|
||||
props: any;
|
||||
readonly id: DurableObjectId;
|
||||
readonly storage: DurableObjectStorage;
|
||||
container?: Container;
|
||||
@@ -475,7 +474,6 @@ interface DurableObjectStorage {
|
||||
deleteAlarm(options?: DurableObjectSetAlarmOptions): Promise<void>;
|
||||
sync(): Promise<void>;
|
||||
sql: SqlStorage;
|
||||
kv: SyncKvStorage;
|
||||
transactionSync<T>(closure: () => T): T;
|
||||
getCurrentBookmark(): Promise<string>;
|
||||
getBookmarkForTime(timestamp: number | Date): Promise<string>;
|
||||
@@ -2047,7 +2045,6 @@ interface TraceItem {
|
||||
readonly scriptVersion?: ScriptVersion;
|
||||
readonly dispatchNamespace?: string;
|
||||
readonly scriptTags?: string[];
|
||||
readonly durableObjectId?: string;
|
||||
readonly outcome: string;
|
||||
readonly executionModel: string;
|
||||
readonly truncated: boolean;
|
||||
@@ -2569,23 +2566,6 @@ declare class MessageChannel {
|
||||
interface MessagePortPostMessageOptions {
|
||||
transfer?: any[];
|
||||
}
|
||||
interface SyncKvStorage {
|
||||
get<T = unknown>(key: string): T | undefined;
|
||||
list<T = unknown>(options?: SyncKvListOptions): Iterable<[
|
||||
string,
|
||||
T
|
||||
]>;
|
||||
put<T>(key: string, value: T): void;
|
||||
delete(key: string): boolean;
|
||||
}
|
||||
interface SyncKvListOptions {
|
||||
start?: string;
|
||||
startAfter?: string;
|
||||
end?: string;
|
||||
prefix?: string;
|
||||
reverse?: boolean;
|
||||
limit?: number;
|
||||
}
|
||||
type AiImageClassificationInput = {
|
||||
image: number[];
|
||||
};
|
||||
@@ -5460,7 +5440,7 @@ type AIGatewayHeaders = {
|
||||
[key: string]: string | number | boolean | object;
|
||||
};
|
||||
type AIGatewayUniversalRequest = {
|
||||
provider: AIGatewayProviders | string; // eslint-disable-line
|
||||
provider: AIGatewayProviders | string;
|
||||
endpoint: string;
|
||||
headers: Partial<AIGatewayHeaders>;
|
||||
query: unknown;
|
||||
@@ -5476,7 +5456,7 @@ declare abstract class AiGateway {
|
||||
gateway?: UniversalGatewayOptions;
|
||||
extraHeaders?: object;
|
||||
}): Promise<Response>;
|
||||
getUrl(provider?: AIGatewayProviders | string): Promise<string>; // eslint-disable-line
|
||||
getUrl(provider?: AIGatewayProviders | string): Promise<string>;
|
||||
}
|
||||
interface AutoRAGInternalError extends Error {
|
||||
}
|
||||
@@ -6575,7 +6555,6 @@ type ImageOutputOptions = {
|
||||
format: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp' | 'image/avif' | 'rgb' | 'rgba';
|
||||
quality?: number;
|
||||
background?: string;
|
||||
anim?: boolean;
|
||||
};
|
||||
interface ImagesBinding {
|
||||
/**
|
||||
@@ -6634,108 +6613,6 @@ interface ImagesError extends Error {
|
||||
readonly message: string;
|
||||
readonly stack?: string;
|
||||
}
|
||||
/**
|
||||
* Media binding for transforming media streams.
|
||||
* Provides the entry point for media transformation operations.
|
||||
*/
|
||||
interface MediaBinding {
|
||||
/**
|
||||
* Creates a media transformer from an input stream.
|
||||
* @param media - The input media bytes
|
||||
* @returns A MediaTransformer instance for applying transformations
|
||||
*/
|
||||
input(media: ReadableStream<Uint8Array>): MediaTransformer;
|
||||
}
|
||||
/**
|
||||
* Media transformer for applying transformation operations to media content.
|
||||
* Handles sizing, fitting, and other input transformation parameters.
|
||||
*/
|
||||
interface MediaTransformer {
|
||||
/**
|
||||
* Applies transformation options to the media content.
|
||||
* @param transform - Configuration for how the media should be transformed
|
||||
* @returns A generator for producing the transformed media output
|
||||
*/
|
||||
transform(transform: MediaTransformationInputOptions): MediaTransformationGenerator;
|
||||
}
|
||||
/**
|
||||
* Generator for producing media transformation results.
|
||||
* Configures the output format and parameters for the transformed media.
|
||||
*/
|
||||
interface MediaTransformationGenerator {
|
||||
/**
|
||||
* Generates the final media output with specified options.
|
||||
* @param output - Configuration for the output format and parameters
|
||||
* @returns The final transformation result containing the transformed media
|
||||
*/
|
||||
output(output: MediaTransformationOutputOptions): MediaTransformationResult;
|
||||
}
|
||||
/**
|
||||
* Result of a media transformation operation.
|
||||
* Provides multiple ways to access the transformed media content.
|
||||
*/
|
||||
interface MediaTransformationResult {
|
||||
/**
|
||||
* Returns the transformed media as a readable stream of bytes.
|
||||
* @returns A stream containing the transformed media data
|
||||
*/
|
||||
media(): ReadableStream<Uint8Array>;
|
||||
/**
|
||||
* Returns the transformed media as an HTTP response object.
|
||||
* @returns The transformed media as a Response, ready to store in cache or return to users
|
||||
*/
|
||||
response(): Response;
|
||||
/**
|
||||
* Returns the MIME type of the transformed media.
|
||||
* @returns The content type string (e.g., 'image/jpeg', 'video/mp4')
|
||||
*/
|
||||
contentType(): string;
|
||||
}
|
||||
/**
|
||||
* Configuration options for transforming media input.
|
||||
* Controls how the media should be resized and fitted.
|
||||
*/
|
||||
type MediaTransformationInputOptions = {
|
||||
/** How the media should be resized to fit the specified dimensions */
|
||||
fit?: 'contain' | 'cover' | 'scale-down';
|
||||
/** Target width in pixels */
|
||||
width?: number;
|
||||
/** Target height in pixels */
|
||||
height?: number;
|
||||
};
|
||||
/**
|
||||
* Configuration options for Media Transformations output.
|
||||
* Controls the format, timing, and type of the generated output.
|
||||
*/
|
||||
type MediaTransformationOutputOptions = {
|
||||
/**
|
||||
* Output mode determining the type of media to generate
|
||||
*/
|
||||
mode?: 'video' | 'spritesheet' | 'frame' | 'audio';
|
||||
/** Whether to include audio in the output */
|
||||
audio?: boolean;
|
||||
/**
|
||||
* Starting timestamp for frame extraction or start time for clips. (e.g. '2s').
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* Duration for video clips, audio extraction, and spritesheet generation (e.g. '5s').
|
||||
*/
|
||||
duration?: string;
|
||||
/**
|
||||
* Output format for the generated media.
|
||||
*/
|
||||
format?: 'jpg' | 'png' | 'm4a';
|
||||
};
|
||||
/**
|
||||
* Error object for media transformation operations.
|
||||
* Extends the standard Error interface with additional media-specific information.
|
||||
*/
|
||||
interface MediaError extends Error {
|
||||
readonly code: number;
|
||||
readonly message: string;
|
||||
readonly stack?: string;
|
||||
}
|
||||
type Params<P extends string = any> = Record<P, string | string[]>;
|
||||
type EventContext<Env, P extends string, Data> = {
|
||||
request: Request<unknown, IncomingRequestCfProperties<unknown>>;
|
||||
@@ -7122,17 +6999,21 @@ declare namespace TailStream {
|
||||
readonly tag?: string;
|
||||
readonly message?: string;
|
||||
}
|
||||
interface Trigger {
|
||||
readonly traceId: string;
|
||||
readonly invocationId: string;
|
||||
readonly spanId: string;
|
||||
}
|
||||
interface Onset {
|
||||
readonly type: "onset";
|
||||
readonly attributes: Attribute[];
|
||||
// id for the span being opened by this Onset event.
|
||||
readonly spanId: string;
|
||||
readonly dispatchNamespace?: string;
|
||||
readonly entrypoint?: string;
|
||||
readonly executionModel: string;
|
||||
readonly scriptName?: string;
|
||||
readonly scriptTags?: string[];
|
||||
readonly scriptVersion?: ScriptVersion;
|
||||
readonly trigger?: Trigger;
|
||||
readonly info: FetchEventInfo | JsRpcEventInfo | ScheduledEventInfo | AlarmEventInfo | QueueEventInfo | EmailEventInfo | TraceEventInfo | HibernatableWebSocketEventInfo | CustomEventInfo;
|
||||
}
|
||||
interface Outcome {
|
||||
@@ -7144,8 +7025,6 @@ declare namespace TailStream {
|
||||
interface SpanOpen {
|
||||
readonly type: "spanOpen";
|
||||
readonly name: string;
|
||||
// id for the span being opened by this SpanOpen event.
|
||||
readonly spanId: string;
|
||||
readonly info?: FetchEventInfo | JsRpcEventInfo | Attributes;
|
||||
}
|
||||
interface SpanClose {
|
||||
@@ -7168,10 +7047,6 @@ declare namespace TailStream {
|
||||
readonly level: "debug" | "error" | "info" | "log" | "warn";
|
||||
readonly message: object;
|
||||
}
|
||||
// This marks the worker handler return information.
|
||||
// This is separate from Outcome because the worker invocation can live for a long time after
|
||||
// returning. For example - Websockets that return an http upgrade response but then continue
|
||||
// streaming information or SSE http connections.
|
||||
interface Return {
|
||||
readonly type: "return";
|
||||
readonly info?: FetchResponseInfo;
|
||||
@@ -7185,28 +7060,9 @@ declare namespace TailStream {
|
||||
readonly info: Attribute[];
|
||||
}
|
||||
type EventType = Onset | Outcome | SpanOpen | SpanClose | DiagnosticChannelEvent | Exception | Log | Return | Attributes;
|
||||
// Context in which this trace event lives.
|
||||
interface SpanContext {
|
||||
// Single id for the entire top-level invocation
|
||||
// This should be a new traceId for the first worker stage invoked in the eyeball request and then
|
||||
// same-account service-bindings should reuse the same traceId but cross-account service-bindings
|
||||
// should use a new traceId.
|
||||
readonly traceId: string;
|
||||
// spanId in which this event is handled
|
||||
// for Onset and SpanOpen events this would be the parent span id
|
||||
// for Outcome and SpanClose these this would be the span id of the opening Onset and SpanOpen events
|
||||
// For Hibernate and Mark this would be the span under which they were emitted.
|
||||
// spanId is not set ONLY if:
|
||||
// 1. This is an Onset event
|
||||
// 2. We are not inherting any SpanContext. (e.g. this is a cross-account service binding or a new top-level invocation)
|
||||
readonly spanId?: string;
|
||||
}
|
||||
interface TailEvent<Event extends EventType> {
|
||||
// invocation id of the currently invoked worker stage.
|
||||
// invocation id will always be unique to every Onset event and will be the same until the Outcome event.
|
||||
readonly invocationId: string;
|
||||
// Inherited spanContext for this event.
|
||||
readonly spanContext: SpanContext;
|
||||
readonly spanId: string;
|
||||
readonly timestamp: Date;
|
||||
readonly sequence: number;
|
||||
readonly event: Event;
|
||||
|
Reference in New Issue
Block a user