@ubean/build 0.6.2 → 0.6.4
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/README.md +572 -0
- package/README.zh-CN.md +541 -0
- package/dist/actions-plugin.d.ts +2 -1
- package/dist/codegen/index.d.ts +21 -1
- package/dist/codegen/index.js +1 -2
- package/dist/{codegen-DNUCCW3C.js → codegen-BL0s5Pyq.js} +101 -2
- package/dist/env/plugin.d.ts +89 -0
- package/dist/env/plugin.js +80 -0
- package/dist/prerender.js +1 -1
- package/dist/production.js +1 -2
- package/dist/types-JZjwXWJd.js +160 -0
- package/dist/{vite-CrhHLCqC.js → vite-DR0qiIma.js} +43 -8
- package/dist/vite.d.ts +11 -6
- package/dist/vite.js +2 -2
- package/dist/{vue-DTMMMa4v.js → vue-MyIMqUw0.js} +30 -12
- package/dist/vue.js +1 -2
- package/package.json +23 -19
|
@@ -1,8 +1,89 @@
|
|
|
1
|
+
import { r as resolveEnvModules } from "./types-JZjwXWJd.js";
|
|
1
2
|
import { isAbsolute, join, normalize, relative } from "pathe";
|
|
2
3
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
4
|
import { glob } from "tinyglobby";
|
|
4
5
|
import { createUnimport, toTypeDeclarationFile } from "unimport";
|
|
5
6
|
import openapiTS, { astToString } from "openapi-typescript";
|
|
7
|
+
//#region src/env/codegen.ts
|
|
8
|
+
/**
|
|
9
|
+
* `.ubean/env.d.ts` 生成器。
|
|
10
|
+
*
|
|
11
|
+
* 两个职责:
|
|
12
|
+
* 1. 给 `ubean:env/client` / `ubean:env/server` 两个虚拟模块补类型(否则用户 import 时 TS2307)
|
|
13
|
+
* 2. 从 Vite 解析好的 `import.meta.env` 自动生成 `ImportMetaEnv`,替掉用户手写的那份
|
|
14
|
+
*
|
|
15
|
+
* 第 2 点顺手修掉一类漂移:手写 `ImportMetaEnv` 会漏 key。本仓库的实例是
|
|
16
|
+
* `src/env.ts` 读了 `import.meta.env.VITE_API_PROXY_KEYS`,而 `src/typings/env.d.ts`
|
|
17
|
+
* 里没有对应声明 —— 手写清单没有东西能提醒它过期。
|
|
18
|
+
*/
|
|
19
|
+
const VITE_BUILTIN_ENV_KEYS = /* @__PURE__ */ new Set([
|
|
20
|
+
"MODE",
|
|
21
|
+
"DEV",
|
|
22
|
+
"PROD",
|
|
23
|
+
"BASE_URL",
|
|
24
|
+
"SSR"
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* 产物文件名(单一来源:`generateEnvTypes()` 的默认值与 `CODEGEN_NON_CONTRACT_FILES`
|
|
28
|
+
* 都用它,免得改了一处漏另一处)。
|
|
29
|
+
*/
|
|
30
|
+
const ENV_TYPES_FILE_NAME = "env.d.ts";
|
|
31
|
+
function tsTypeOfLiteral(value) {
|
|
32
|
+
if (typeof value === "number") return "number";
|
|
33
|
+
if (typeof value === "boolean") return "boolean";
|
|
34
|
+
return "string";
|
|
35
|
+
}
|
|
36
|
+
function renderModuleTypes(moduleId, fields) {
|
|
37
|
+
if (fields.length === 0) return `declare module '${moduleId}' {\n // env.schema is empty\n}\n`;
|
|
38
|
+
return `declare module '${moduleId}' {\n${fields.map((f) => {
|
|
39
|
+
return ` export const ${f.key}: ${f.type}${f.optional ? " | undefined" : ""};`;
|
|
40
|
+
}).join("\n")}\n}\n`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 从 `import.meta.env` 快照生成 `ImportMetaEnv`。
|
|
44
|
+
*
|
|
45
|
+
* 值同时用于**类型**:字符串字面量能收窄成具体字符串 —— 但只在值是字面量时。这里选择
|
|
46
|
+
* 宽化到 `string` / `number` / `boolean`,因为 `.env` 里的值一律是字符串,写成裸字面量
|
|
47
|
+
* 会让 `VITE_API_ENV` 被推成 `"local"` 这种过窄类型,赋值时报错。
|
|
48
|
+
*/
|
|
49
|
+
function renderImportMetaEnv(importMetaEnv) {
|
|
50
|
+
const keys = Object.keys(importMetaEnv).filter((key) => key.startsWith("VITE_") || VITE_BUILTIN_ENV_KEYS.has(key)).sort();
|
|
51
|
+
if (keys.length === 0) return `interface ImportMetaEnv {\n readonly [key: string]: string | boolean | undefined;\n}\n`;
|
|
52
|
+
return `interface ImportMetaEnv {\n${keys.map((key) => {
|
|
53
|
+
const value = importMetaEnv[key];
|
|
54
|
+
if (VITE_BUILTIN_ENV_KEYS.has(key)) {
|
|
55
|
+
if (key === "MODE" || key === "BASE_URL") return ` readonly ${key}: string;`;
|
|
56
|
+
return ` readonly ${key}: boolean;`;
|
|
57
|
+
}
|
|
58
|
+
return ` readonly ${key}: ${tsTypeOfLiteral(value)};`;
|
|
59
|
+
}).join("\n")}\n}\n`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 生成 `.ubean/env.d.ts`。
|
|
63
|
+
*
|
|
64
|
+
* 顶层**不能**出现 `export {}`:`ImportMetaEnv` 的声明必须留在全局作用域,一旦文件变成
|
|
65
|
+
* 模块,TypeScript 的类型增强就失效(Vite 官方文档专门警告过这一点)。
|
|
66
|
+
* `declare module '...'` 块本身不需要文件是模块。
|
|
67
|
+
*/
|
|
68
|
+
async function generateEnvTypes(options) {
|
|
69
|
+
const { outDir, fileName = ENV_TYPES_FILE_NAME, modules, importMetaEnv = {} } = options;
|
|
70
|
+
const contents = `// Auto-generated by ubean from \`env.schema\` in ubean.config.ts — do not edit manually.
|
|
71
|
+
// Provides typed access to \`ubean:env/client\` / \`ubean:env/server\` and declares ImportMetaEnv.
|
|
72
|
+
/* eslint-disable */
|
|
73
|
+
/// <reference types="vite/client" />
|
|
74
|
+
|
|
75
|
+
${renderImportMetaEnv(importMetaEnv)}
|
|
76
|
+
interface ImportMeta {
|
|
77
|
+
readonly env: ImportMetaEnv;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
${renderModuleTypes("ubean:env/client", modules.client)}${renderModuleTypes("ubean:env/server", modules.server)}`;
|
|
81
|
+
await mkdir(outDir, { recursive: true });
|
|
82
|
+
const outPath = join(outDir, fileName);
|
|
83
|
+
await writeFile(outPath, contents, "utf8");
|
|
84
|
+
return outPath;
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
6
87
|
//#region src/codegen/auto-imports.ts
|
|
7
88
|
/** 将 `boolean | AutoImportOptions` 归一化为分库开关 + 透传选项。 */
|
|
8
89
|
function resolveAutoImportsConfig(input) {
|
|
@@ -851,8 +932,16 @@ const CODEGEN_FILES = [
|
|
|
851
932
|
types: []
|
|
852
933
|
}
|
|
853
934
|
];
|
|
935
|
+
/**
|
|
936
|
+
* `generateTypes()` 会写、但**不属于**外部冻结契约的产物。
|
|
937
|
+
*
|
|
938
|
+
* 存在的意义只为一个可执行断言服务:`test/codegen-doc-contract.test.ts` 断言「文档里列出的
|
|
939
|
+
* `*.d.ts` 必须在代码里真的产出」,而 `env.d.ts` 故意不进 `CODEGEN_FILES`(理由见那里),
|
|
940
|
+
* 于是它有产物、没契约条目。把名字登记在这里,比在测试里硬编码字符串更难漂移。
|
|
941
|
+
*/
|
|
942
|
+
const CODEGEN_NON_CONTRACT_FILES = [ENV_TYPES_FILE_NAME];
|
|
854
943
|
async function generateTypes(result, options) {
|
|
855
|
-
const { cwd, srcDir, buildDir, ...autoImportOptions } = options;
|
|
944
|
+
const { cwd, srcDir, buildDir, env, importMetaEnv, ...autoImportOptions } = options;
|
|
856
945
|
const outDir = join(cwd, buildDir);
|
|
857
946
|
await mkdir(outDir, { recursive: true });
|
|
858
947
|
const generated = [];
|
|
@@ -865,6 +954,15 @@ async function generateTypes(result, options) {
|
|
|
865
954
|
generated.push(pageTypesPath);
|
|
866
955
|
const i18nTypesPath = await generateI18nTypes(result, { outDir });
|
|
867
956
|
if (i18nTypesPath) generated.push(i18nTypesPath);
|
|
957
|
+
const envTypesPath = await generateEnvTypes({
|
|
958
|
+
outDir,
|
|
959
|
+
modules: resolveEnvModules({
|
|
960
|
+
schema: env?.schema ?? {},
|
|
961
|
+
importMetaEnv
|
|
962
|
+
}),
|
|
963
|
+
importMetaEnv
|
|
964
|
+
});
|
|
965
|
+
generated.push(envTypesPath);
|
|
868
966
|
const { autoImportsDtsPath, componentsDtsPath, virtualComponentsDtsPath } = await generateAutoImports(result, {
|
|
869
967
|
cwd,
|
|
870
968
|
srcDir,
|
|
@@ -890,8 +988,9 @@ async function generateTypes(result, options) {
|
|
|
890
988
|
autoImportsDtsPath,
|
|
891
989
|
componentsDtsPath,
|
|
892
990
|
virtualComponentsDtsPath,
|
|
991
|
+
envTypesPath,
|
|
893
992
|
generated
|
|
894
993
|
};
|
|
895
994
|
}
|
|
896
995
|
//#endregion
|
|
897
|
-
export {
|
|
996
|
+
export { getBuiltinComposables as C, resolveComponentsConfig as D, resolveAutoImportsConfig as E, toArray as O, getAutoImportPresets as S, getUbeanComponentsConfig as T, VUE_MACROS_PRESET as _, generateOpenApiTypes as a, generateAutoImports as b, generateRouteTypes as c, BUILTIN_PRESETS as d, COMPONENT_HALF_GLOBS as f, VUE_I18N_PRESET as g, UBEAN_SERVER_PRESET as h, generateTypes as i, generateI18nTypes as l, UBEAN_CLIENT_PRESET as m, CODEGEN_FILES as n, generateOpenApiTypesFromServer as o, HONO_OPENAPI_PRESET as p, CODEGEN_NON_CONTRACT_FILES as r, generatePageTypes as s, CODEGEN_CONTRACT_VERSION as t, messagesToTsType as u, VUE_PRESET as v, getUbeanAutoImportConfig as w, generateImportsTransform as x, VUE_ROUTER_PRESET as y };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { ResolvedConfig } from "@ubean/config";
|
|
2
|
+
import { Plugin } from "vite";
|
|
3
|
+
//#region src/env/types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* `env.schema` → 两个虚拟模块(`ubean:env/client` / `ubean:env/server`)的规范化与取值。
|
|
6
|
+
*
|
|
7
|
+
* 这一层刻意与 Vite 无耦合(纯函数 + 显式入参),因为同一个产物要服务两个环境:
|
|
8
|
+
* - **client 模块**:字段被内联成字面量,取值来自 Vite 已解析好的 `import.meta.env`(构建期)
|
|
9
|
+
* - **server 模块**:字段从 `process.env` 读(运行期),并在 `mode: 'throw'` 时于 import 期抛错
|
|
10
|
+
*
|
|
11
|
+
* 维度规则照抄 Astro `astro:env`:`client+public` / `server+public` / `server+secret` 三种合法,
|
|
12
|
+
* `client+secret` 在**规范化阶段**就抛错(配置期失败,比构建期失败早)。
|
|
13
|
+
*/
|
|
14
|
+
type EnvContext = 'client' | 'server';
|
|
15
|
+
type EnvAccess = 'public' | 'secret';
|
|
16
|
+
interface EnvFieldSpec {
|
|
17
|
+
key: string;
|
|
18
|
+
context: EnvContext;
|
|
19
|
+
access: EnvAccess;
|
|
20
|
+
/** TypeScript 字面量类型,直接写进 `.ubean/env.d.ts`。 */
|
|
21
|
+
type: string;
|
|
22
|
+
optional: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* 已解析的值:
|
|
25
|
+
* - `context: 'client'` → 构建期内联用的字面量(来自 `import.meta.env` / `.env`,已含 default 回退)
|
|
26
|
+
* - `context: 'server'` → **`default` 的回退值**(`process.env` 里没值时用)。
|
|
27
|
+
* 服务端的真实取值发生在运行期,这里只把回退值送到生成代码里。
|
|
28
|
+
* 字段没写 `default` 时保持 `undefined`,生成代码便能区分「有回退」与「无回退」。
|
|
29
|
+
*/
|
|
30
|
+
value?: unknown;
|
|
31
|
+
/** 生成代码里表达「值来自 process.env 的哪个键」——恒等于 `key`(保留字段便于日后加 alias)。 */
|
|
32
|
+
sourceKey: string;
|
|
33
|
+
}
|
|
34
|
+
interface ResolveEnvModulesInput {
|
|
35
|
+
/** 归一化 schema(`ResolvedConfig.env.schema`)。 */
|
|
36
|
+
schema: Record<string, unknown>;
|
|
37
|
+
/** Vite 解析后的 `import.meta.env`(`ResolvedConfig.env`),用于 client 字段取值。 */
|
|
38
|
+
importMetaEnv?: Record<string, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* `.env` 文件的原始内容(`loadEnv(mode, envDir, '')`)。
|
|
41
|
+
*
|
|
42
|
+
* 与 `importMetaEnv` 的分工:`import.meta.env` 只含 Vite 注入的 key(`VITE_*` + 内建),
|
|
43
|
+
* 而 `.env` 里有全量。优先 `importMetaEnv`,缺了才回落这里 —— 这样 `MODE` 这类构建期
|
|
44
|
+
* 派生值不会因为 `.env` 里也写了同名 key 被盖掉。
|
|
45
|
+
*/
|
|
46
|
+
dotEnv?: Record<string, string>;
|
|
47
|
+
/** 服务端侧来源,默认 `process.env`。测试可注入。 */
|
|
48
|
+
serverEnv?: Record<string, string | undefined>;
|
|
49
|
+
}
|
|
50
|
+
interface EnvModules {
|
|
51
|
+
client: EnvFieldSpec[];
|
|
52
|
+
server: EnvFieldSpec[];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 规范化 schema → 两个模块各自的字段清单。
|
|
56
|
+
*
|
|
57
|
+
* 值解析失败(缺必填、类型不符、枚举越界)**不在这里报错** —— 那是运行时校验(`resolveEnvSchema()`
|
|
58
|
+
* 与生成的 server 模块)的职责。这里只负责把维度与类型摊平,缺值时留 `undefined` 让下游决定。
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveEnvModules(input: ResolveEnvModulesInput): EnvModules;
|
|
61
|
+
/** 生成客户端虚拟模块源码:每个字段一个具名导出的字面量。 */
|
|
62
|
+
export declare function renderEnvClientModule(fields: EnvFieldSpec[]): string;
|
|
63
|
+
/**
|
|
64
|
+
* 生成服务端虚拟模块源码。
|
|
65
|
+
*
|
|
66
|
+
* 语义是 **static**(借 SvelteKit 的术语):模块求值时读一次 `process.env`,之后固定。
|
|
67
|
+
* 与 Astro `astro:env/server` 一致 —— 需要 per-request 动态读取时用 `getSecret()`(见下)。
|
|
68
|
+
*
|
|
69
|
+
* 校验失败时:`mode: 'throw'` 直接抛,`'warn'`(默认)打 warn 并把缺值放行。
|
|
70
|
+
* 选择在 import 期抛而不是返回 `undefined`:缺一个必填 secret 却静默跑下去,
|
|
71
|
+
* 会把「部署忘了配环境变量」拖到第一次请求才炸。
|
|
72
|
+
*/
|
|
73
|
+
export declare function renderEnvServerModule(fields: EnvFieldSpec[], mode?: 'warn' | 'throw'): string;
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/env/plugin.d.ts
|
|
76
|
+
export declare const ENV_CLIENT_ID = "ubean:env/client";
|
|
77
|
+
export declare const ENV_SERVER_ID = "ubean:env/server";
|
|
78
|
+
export interface UbeanEnvPluginOptions {
|
|
79
|
+
/** 已解析配置(`ensureUbeanConfig()` 的产物)。 */
|
|
80
|
+
config: ResolvedConfig;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 生成模块所需的信息在 `configResolved` 才能全部拿到:
|
|
84
|
+
* - `config.env`(Vite 解析后的 `import.meta.env` 快照)由 Vite 在钩子入参里给
|
|
85
|
+
* - 同一个钩子还会给出 `mode`,用于判定生产/开发(决定 warn 的措辞)
|
|
86
|
+
*/
|
|
87
|
+
export declare function ubeanEnvPlugin(options: UbeanEnvPluginOptions): Plugin;
|
|
88
|
+
//#endregion
|
|
89
|
+
export type { EnvFieldSpec, EnvModules, ResolveEnvModulesInput };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { n as renderEnvServerModule, r as resolveEnvModules, t as renderEnvClientModule } from "../types-JZjwXWJd.js";
|
|
2
|
+
import { loadEnv } from "vite";
|
|
3
|
+
//#region src/env/plugin.ts
|
|
4
|
+
/**
|
|
5
|
+
* `ubean:env/*` 虚拟模块插件(Astro `astro:env` 的 Vite 版)。
|
|
6
|
+
*
|
|
7
|
+
* 提供两个模块:
|
|
8
|
+
* - `ubean:env/client` — 客户端可见字段,构建期内联成字面量。任何环境都能 import。
|
|
9
|
+
* - `ubean:env/server` — 服务端字段,运行期读 `process.env`。**在客户端环境 import 直接让构建失败**
|
|
10
|
+
* (这是抄 SvelteKit `$env/static/private` 的护栏;比 Astro 的「类型上没有」更强一层)。
|
|
11
|
+
*
|
|
12
|
+
* 与 `ubean:core` 的关系:本插件**不**进 `VIRTUAL_MODULES` 数组(那是 core 的私有清单),
|
|
13
|
+
* 自己处理 `resolveId`/`load`。好处是两条路径(CLI 自建 builder / 裸 `vite build`)都只需
|
|
14
|
+
* 在 `ubeanPlugin()` 里加一行,core 的 resolveId 顺序不受影响 —— 只要本插件排在 core **之后**
|
|
15
|
+
* 即可(core 只会拦它自己那份清单,不会碰 `ubean:env/*`)。
|
|
16
|
+
*/
|
|
17
|
+
const ENV_CLIENT_ID = "ubean:env/client";
|
|
18
|
+
const ENV_SERVER_ID = "ubean:env/server";
|
|
19
|
+
const RESOLVED_CLIENT = "\0ubean:env/client";
|
|
20
|
+
const RESOLVED_SERVER = "\0ubean:env/server";
|
|
21
|
+
/** 客户端环境名(`createBuildEnvironments()` 里注册的那个)。 */
|
|
22
|
+
const CLIENT_ENVIRONMENT = "client";
|
|
23
|
+
/**
|
|
24
|
+
* 生成模块所需的信息在 `configResolved` 才能全部拿到:
|
|
25
|
+
* - `config.env`(Vite 解析后的 `import.meta.env` 快照)由 Vite 在钩子入参里给
|
|
26
|
+
* - 同一个钩子还会给出 `mode`,用于判定生产/开发(决定 warn 的措辞)
|
|
27
|
+
*/
|
|
28
|
+
function ubeanEnvPlugin(options) {
|
|
29
|
+
const { config } = options;
|
|
30
|
+
let importMetaEnv = {};
|
|
31
|
+
/**
|
|
32
|
+
* `.env` 文件的原始内容(`loadEnv(mode, envDir, '')`,**不过 prefix 过滤**)。
|
|
33
|
+
*
|
|
34
|
+
* 服务端字段的解析来源:`configResolved` 里把它合进 `process.env`,生成的
|
|
35
|
+
* `ubean:env/server` 模块才能读到 `.env`。不合并的话,`process.env` 里只有真实导出的
|
|
36
|
+
* 环境变量,`.env` 里写的 `SERVER_PORT` / `JWT_SECRET` 全是 undefined。
|
|
37
|
+
*/
|
|
38
|
+
let fileEnv = {};
|
|
39
|
+
let modules = null;
|
|
40
|
+
/**
|
|
41
|
+
* 幂等构建(dev 下 client / ubean 两个环境各跑一次钩子,但结果一致 —— 缓存即可)。
|
|
42
|
+
*
|
|
43
|
+
* **不缓存**会被服务端环境污染:`resolveEnvModules()` 的 server 分支会读 `process.env`
|
|
44
|
+
* 来决定 optional,而两次调用之间 `.env` 不会变,所以缓存是安全的。
|
|
45
|
+
*/
|
|
46
|
+
function ensureModules() {
|
|
47
|
+
if (modules) return modules;
|
|
48
|
+
modules = resolveEnvModules({
|
|
49
|
+
schema: config.env?.schema ?? {},
|
|
50
|
+
dotEnv: fileEnv,
|
|
51
|
+
importMetaEnv
|
|
52
|
+
});
|
|
53
|
+
return modules;
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
name: "ubean:env",
|
|
57
|
+
enforce: "post",
|
|
58
|
+
configResolved(resolved) {
|
|
59
|
+
importMetaEnv = resolved.env;
|
|
60
|
+
fileEnv = loadEnv(resolved.mode, resolved.envDir ?? resolved.root, "");
|
|
61
|
+
for (const [key, value] of Object.entries(fileEnv)) if (process.env[key] === void 0) process.env[key] = value;
|
|
62
|
+
modules = null;
|
|
63
|
+
},
|
|
64
|
+
resolveId(id) {
|
|
65
|
+
if (id === "ubean:env/client") return RESOLVED_CLIENT;
|
|
66
|
+
if (id === "ubean:env/server") return RESOLVED_SERVER;
|
|
67
|
+
},
|
|
68
|
+
load(id) {
|
|
69
|
+
if (id === RESOLVED_CLIENT) return renderEnvClientModule(ensureModules().client);
|
|
70
|
+
if (id === RESOLVED_SERVER) {
|
|
71
|
+
if (this.environment?.name === CLIENT_ENVIRONMENT) throw new Error(`[ubean:env] \`${ENV_SERVER_ID}\` cannot be imported from client code.\nServer env (including \`access: 'secret'\` fields) is never sent to the browser.
|
|
72
|
+
Move the read into server-only code (\`src/routes/**\`, \`src/services/**\`, \`src/db/**\`),
|
|
73
|
+
or declare the field with \`context: 'client', access: 'public'\` if it is safe to inline.`);
|
|
74
|
+
return renderEnvServerModule(ensureModules().server, config.env?.mode ?? "warn");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
export { ENV_CLIENT_ID, ENV_SERVER_ID, renderEnvClientModule, renderEnvServerModule, resolveEnvModules, ubeanEnvPlugin };
|
package/dist/prerender.js
CHANGED
|
@@ -2,8 +2,8 @@ import { STATIC_NOT_FOUND_ROUTE } from "./static-render.js";
|
|
|
2
2
|
import { dirname, isAbsolute, join } from "pathe";
|
|
3
3
|
import { resolvePrerenderConfig } from "@ubean/config";
|
|
4
4
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
5
|
-
import { DATA_PAYLOAD_ID } from "@ubean/pages";
|
|
6
5
|
import { matchGlob } from "@ubean/shared";
|
|
6
|
+
import { DATA_PAYLOAD_ID } from "@ubean/pages";
|
|
7
7
|
//#region src/prerender.ts
|
|
8
8
|
const LINK_REGEX = /<a[^>]+href=["']([^"']+)["'][^>]*>/gi;
|
|
9
9
|
/**
|
package/dist/production.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { buildWithEnvironments, createIslandsSsrStubPlugin, generateCloudflareWorkerEntry, generateNodeServerEntry, generateStandardHandlerEntry, generateVirtualModulesToDisk, getPresetBuildConfig, serializePagesForEntry };
|
|
1
|
+
export { T as buildWithEnvironments, v as createIslandsSsrStubPlugin, y as generateCloudflareWorkerEntry, b as generateNodeServerEntry, x as generateStandardHandlerEntry, S as generateVirtualModulesToDisk, C as getPresetBuildConfig, w as serializePagesForEntry } from "./vite-DR0qiIma.js";
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { isEnvFieldMeta } from "@ubean/shared";
|
|
2
|
+
//#region src/env/types.ts
|
|
3
|
+
/**
|
|
4
|
+
* `env.schema` → 两个虚拟模块(`ubean:env/client` / `ubean:env/server`)的规范化与取值。
|
|
5
|
+
*
|
|
6
|
+
* 这一层刻意与 Vite 无耦合(纯函数 + 显式入参),因为同一个产物要服务两个环境:
|
|
7
|
+
* - **client 模块**:字段被内联成字面量,取值来自 Vite 已解析好的 `import.meta.env`(构建期)
|
|
8
|
+
* - **server 模块**:字段从 `process.env` 读(运行期),并在 `mode: 'throw'` 时于 import 期抛错
|
|
9
|
+
*
|
|
10
|
+
* 维度规则照抄 Astro `astro:env`:`client+public` / `server+public` / `server+secret` 三种合法,
|
|
11
|
+
* `client+secret` 在**规范化阶段**就抛错(配置期失败,比构建期失败早)。
|
|
12
|
+
*/
|
|
13
|
+
function typeOfField(def) {
|
|
14
|
+
if (isEnvFieldMeta(def)) {
|
|
15
|
+
if (def.type === "enum") return (def.values ?? []).map((v) => JSON.stringify(v)).join(" | ") || "string";
|
|
16
|
+
if (def.type === "number") return "number";
|
|
17
|
+
if (def.type === "boolean") return "boolean";
|
|
18
|
+
return "string";
|
|
19
|
+
}
|
|
20
|
+
const legacy = def;
|
|
21
|
+
if (legacy.type === Number) return "number";
|
|
22
|
+
if (legacy.type === Boolean) return "boolean";
|
|
23
|
+
if (legacy.type === String) return "string";
|
|
24
|
+
return "unknown";
|
|
25
|
+
}
|
|
26
|
+
function dimensionsOf(def) {
|
|
27
|
+
if (isEnvFieldMeta(def)) return {
|
|
28
|
+
context: def.context,
|
|
29
|
+
access: def.access
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
context: "server",
|
|
33
|
+
access: "secret"
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 规范化 schema → 两个模块各自的字段清单。
|
|
38
|
+
*
|
|
39
|
+
* 值解析失败(缺必填、类型不符、枚举越界)**不在这里报错** —— 那是运行时校验(`resolveEnvSchema()`
|
|
40
|
+
* 与生成的 server 模块)的职责。这里只负责把维度与类型摊平,缺值时留 `undefined` 让下游决定。
|
|
41
|
+
*/
|
|
42
|
+
function resolveEnvModules(input) {
|
|
43
|
+
const { schema, importMetaEnv = {}, dotEnv = {}, serverEnv = process.env } = input;
|
|
44
|
+
const client = [];
|
|
45
|
+
const server = [];
|
|
46
|
+
for (const [key, def] of Object.entries(schema)) {
|
|
47
|
+
const { context, access } = dimensionsOf(def);
|
|
48
|
+
if (context === "client" && access === "secret") throw new Error(`Invalid env field "${key}": context 'client' cannot be combined with access 'secret'. Secrets never reach the client — use \`{ context: 'server', access: 'secret' }\`.`);
|
|
49
|
+
const meta = isEnvFieldMeta(def) ? def : null;
|
|
50
|
+
const optional = meta ? meta.optional === true : false;
|
|
51
|
+
const spec = {
|
|
52
|
+
key,
|
|
53
|
+
context,
|
|
54
|
+
access,
|
|
55
|
+
type: typeOfField(def),
|
|
56
|
+
optional,
|
|
57
|
+
sourceKey: key
|
|
58
|
+
};
|
|
59
|
+
if (context === "client") {
|
|
60
|
+
const raw = importMetaEnv[key] ?? dotEnv[key];
|
|
61
|
+
const resolved = raw === void 0 || raw === "" ? meta?.default : raw;
|
|
62
|
+
if (resolved !== void 0) spec.value = resolved;
|
|
63
|
+
client.push(spec);
|
|
64
|
+
} else {
|
|
65
|
+
const hasDefault = meta ? meta.default !== void 0 : def.default !== void 0;
|
|
66
|
+
const rawServer = serverEnv[key];
|
|
67
|
+
spec.optional = optional || !hasDefault && (rawServer === void 0 || rawServer === "");
|
|
68
|
+
if (hasDefault) spec.value = meta ? meta.default : def.default;
|
|
69
|
+
server.push(spec);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
client,
|
|
74
|
+
server
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** 生成客户端虚拟模块源码:每个字段一个具名导出的字面量。 */
|
|
78
|
+
function renderEnvClientModule(fields) {
|
|
79
|
+
const lines = ["// Generated by ubean from `env.schema` in ubean.config.ts — do not edit.", "// Values are inlined at build time from Vite-resolved `import.meta.env`."];
|
|
80
|
+
for (const field of fields) {
|
|
81
|
+
if (field.value === void 0) {
|
|
82
|
+
lines.push(`// ${field.key}: no value resolved at build time${field.optional ? " (optional)" : ""}`);
|
|
83
|
+
lines.push(`export const ${field.key} = undefined;`);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
lines.push(`export const ${field.key} = ${JSON.stringify(field.value)};`);
|
|
87
|
+
}
|
|
88
|
+
return `${lines.join("\n")}\n`;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 生成服务端虚拟模块源码。
|
|
92
|
+
*
|
|
93
|
+
* 语义是 **static**(借 SvelteKit 的术语):模块求值时读一次 `process.env`,之后固定。
|
|
94
|
+
* 与 Astro `astro:env/server` 一致 —— 需要 per-request 动态读取时用 `getSecret()`(见下)。
|
|
95
|
+
*
|
|
96
|
+
* 校验失败时:`mode: 'throw'` 直接抛,`'warn'`(默认)打 warn 并把缺值放行。
|
|
97
|
+
* 选择在 import 期抛而不是返回 `undefined`:缺一个必填 secret 却静默跑下去,
|
|
98
|
+
* 会把「部署忘了配环境变量」拖到第一次请求才炸。
|
|
99
|
+
*/
|
|
100
|
+
function renderEnvServerModule(fields, mode = "warn") {
|
|
101
|
+
const specs = fields.map((f) => ({
|
|
102
|
+
key: f.key,
|
|
103
|
+
type: f.type === "number" ? "number" : f.type === "boolean" ? "boolean" : "string",
|
|
104
|
+
optional: f.optional,
|
|
105
|
+
default: f.value
|
|
106
|
+
}));
|
|
107
|
+
return `// Generated by ubean from \`env.schema\` in ubean.config.ts — do not edit.
|
|
108
|
+
// Reads \`process.env\` once, at module evaluation time (static semantics).
|
|
109
|
+
|
|
110
|
+
const __specs = ${JSON.stringify(specs)};
|
|
111
|
+
const __source = typeof process !== 'undefined' && process.env ? process.env : {};
|
|
112
|
+
const __errors = [];
|
|
113
|
+
const __values = {};
|
|
114
|
+
|
|
115
|
+
for (const spec of __specs) {
|
|
116
|
+
const raw = __source[spec.key];
|
|
117
|
+
if (raw === undefined || raw === '') {
|
|
118
|
+
if (spec.default !== undefined) {
|
|
119
|
+
__values[spec.key] = spec.default;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (!spec.optional) __errors.push(\` - \${spec.key}: Missing required env\`);
|
|
123
|
+
__values[spec.key] = undefined;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (spec.type === 'number') {
|
|
127
|
+
const n = Number(raw);
|
|
128
|
+
if (Number.isNaN(n)) {
|
|
129
|
+
__errors.push(\` - \${spec.key}: must be a number, got \${raw}\`);
|
|
130
|
+
__values[spec.key] = undefined;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
__values[spec.key] = n;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (spec.type === 'boolean') {
|
|
137
|
+
__values[spec.key] = raw === 'true' || raw === '1';
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
__values[spec.key] = raw;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (__errors.length > 0) {
|
|
144
|
+
const message = 'Environment validation failed:\\n' + __errors.join('\\n');
|
|
145
|
+
if (${JSON.stringify(mode)} === 'throw') throw new Error(message);
|
|
146
|
+
// eslint-disable-next-line no-console
|
|
147
|
+
console.warn('[ubean:env/server] ' + message);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export const __env = __values;
|
|
151
|
+
${fields.map((f) => `export const ${f.key} = __values[${JSON.stringify(f.key)}];`).join("\n")}
|
|
152
|
+
|
|
153
|
+
/** 读取未在 \`env.schema\` 里声明的变量(动态 / per-request 场景)。 */
|
|
154
|
+
export function getSecret(key) {
|
|
155
|
+
return __source[key];
|
|
156
|
+
}
|
|
157
|
+
`;
|
|
158
|
+
}
|
|
159
|
+
//#endregion
|
|
160
|
+
export { renderEnvServerModule as n, resolveEnvModules as r, renderEnvClientModule as t };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { a as ssrSingletonProdOptimizeExclude, m as createVirtualRegistry, o as ssrSingletonProdSsr, y as __exportAll } from "./ssr-singleton-Bbds29jS.js";
|
|
2
2
|
import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-BK0L1Op-.js";
|
|
3
|
-
import {
|
|
4
|
-
import { _ as toWebRequest, a as createVueAppEntryVirtualModule, b as getDevScanCoordinator, g as sendWebResponse, i as createServerEntryVirtualModule, n as ubeanVite, o as createVuePagesVirtualModule, r as createClientEntryVirtualModule, u as ensureDevApp } from "./vue-
|
|
3
|
+
import { a as generateOpenApiTypes, i as generateTypes } from "./codegen-BL0s5Pyq.js";
|
|
4
|
+
import { _ as toWebRequest, a as createVueAppEntryVirtualModule, b as getDevScanCoordinator, g as sendWebResponse, i as createServerEntryVirtualModule, n as ubeanVite, o as createVuePagesVirtualModule, r as createClientEntryVirtualModule, u as ensureDevApp } from "./vue-MyIMqUw0.js";
|
|
5
5
|
import { createStaticSsgRenderer } from "./static-render.js";
|
|
6
6
|
import { prerender, resolvePrerenderStaticDir } from "./prerender.js";
|
|
7
7
|
import { dirname, join, relative, resolve } from "pathe";
|
|
8
8
|
import * as nodeFs from "node:fs";
|
|
9
9
|
import { existsSync, readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
|
|
10
|
-
import { loadUbeanConfig, resolveModules, resolvePrerenderConfig, tryGetConfig } from "@ubean/config";
|
|
10
|
+
import { checkProjectDependenciesOnce, loadUbeanConfig, resolveModules, resolvePrerenderConfig, tryGetConfig } from "@ubean/config";
|
|
11
11
|
import { isEphemeralCachePreset, registerBuiltinPresets, resolvePresetByName, resolveProductionCacheStore } from "@ubean/preset";
|
|
12
12
|
import { createServerRouter } from "@ubean/routes";
|
|
13
13
|
import { scanProject } from "@ubean/scan";
|
|
@@ -356,8 +356,14 @@ const RESOLVED_ID = `\0${ASSET_MANIFEST_VIRTUAL_ID}`;
|
|
|
356
356
|
/**
|
|
357
357
|
* 从 client manifest 算出资产标签。
|
|
358
358
|
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
359
|
+
* CSS 取**全量 chunk 的并集**,而不是只读 entry:代码分割后页面/布局的样式落在各自的 chunk 上,
|
|
360
|
+
* entry 的 `css` 常常是空的(实测 `examples/ubean-test` 为 0 条),只读 entry 会让生产 HTML
|
|
361
|
+
* 首帧无样式(FOUC)—— 与 dev 侧 `collectDevCssLinks` 读 client 图为空是同一类缺陷。
|
|
362
|
+
* entry 自己的 css 排在前面,其余按文件名排序,保证构建可重现。
|
|
363
|
+
*
|
|
364
|
+
* 代价:会多加载未访问页面的 CSS(实测 ubean-test 15 个 chunk 共 12.0KB、docs 仅 +0.3KB)。
|
|
365
|
+
* 若要收敛到「只注入当前页实际用到的」,需要走 ssr-manifest + 渲染期收集(见 dev 侧的
|
|
366
|
+
* `isCssModuleUrl` 路径),属于更大的改造。
|
|
361
367
|
*/
|
|
362
368
|
function computeAssetTags(manifest, favicon) {
|
|
363
369
|
const tags = {
|
|
@@ -366,10 +372,16 @@ function computeAssetTags(manifest, favicon) {
|
|
|
366
372
|
body: "",
|
|
367
373
|
favicon: favicon ?? null
|
|
368
374
|
};
|
|
369
|
-
const
|
|
375
|
+
const entries = manifest ? Object.values(manifest) : [];
|
|
376
|
+
const entry = entries.find((item) => item.isEntry);
|
|
370
377
|
if (!entry) return tags;
|
|
371
378
|
tags.body = `<script type="module" src="/${entry.file}"><\/script>`;
|
|
372
|
-
|
|
379
|
+
const cssFiles = /* @__PURE__ */ new Set();
|
|
380
|
+
for (const css of entry.css ?? []) cssFiles.add(css);
|
|
381
|
+
const rest = /* @__PURE__ */ new Set();
|
|
382
|
+
for (const item of entries) for (const css of item.css ?? []) if (!cssFiles.has(css)) rest.add(css);
|
|
383
|
+
for (const css of [...rest].sort()) cssFiles.add(css);
|
|
384
|
+
if (cssFiles.size > 0) tags.css = [...cssFiles].map((css) => `<link rel="stylesheet" href="/${css}">`).join("\n");
|
|
373
385
|
return tags;
|
|
374
386
|
}
|
|
375
387
|
/** 从磁盘读 client manifest(`<publicDir>/.vite/manifest.json`)。 */
|
|
@@ -2490,6 +2502,14 @@ function ubeanPlugin(options) {
|
|
|
2490
2502
|
/** 已跑过 codegen 的扫描结果(`buildStart` 会在两个环境各跑一次)。 */
|
|
2491
2503
|
let lastCodegenScan = null;
|
|
2492
2504
|
/**
|
|
2505
|
+
* 本插件实例拿到的 Vite 解析后环境变量快照(`configResolved` 钩子填充)。
|
|
2506
|
+
*
|
|
2507
|
+
* 为什么不在 `runProjectCodegen` 里自己 `loadEnv()`:Vite 已经在 `configResolved` 把
|
|
2508
|
+
* **合并完 `.env` / `.env.local` / `.env.[mode]` / 进程环境**的结果给了插件,再自己读一遍
|
|
2509
|
+
* 就多一份可能漂移的实现(优先级规则容易抄错),而且与 `import.meta.env` 的实际内容未必一致。
|
|
2510
|
+
*/
|
|
2511
|
+
let resolvedImportMetaEnv = {};
|
|
2512
|
+
/**
|
|
2493
2513
|
* dev 扫描协调器(`configureServer` 建立、`buildStart` 用)。
|
|
2494
2514
|
*
|
|
2495
2515
|
* Vite 的顺序是 `configureServer` → `buildStart`,且 dev 下每个环境各跑一次 `buildStart`
|
|
@@ -2538,6 +2558,16 @@ function ubeanPlugin(options) {
|
|
|
2538
2558
|
ubeanConfig = await loadUbeanConfig();
|
|
2539
2559
|
ensureDerived();
|
|
2540
2560
|
}
|
|
2561
|
+
if (!process.env.UBEAN_SKIP_DEP_CHECK) await checkProjectDependenciesOnce({
|
|
2562
|
+
cwd: ubeanConfig.rootDir,
|
|
2563
|
+
config: ubeanConfig,
|
|
2564
|
+
srcDir: ubeanConfig.srcDir,
|
|
2565
|
+
mode: "prompt",
|
|
2566
|
+
logger: {
|
|
2567
|
+
info: (message) => logger.info(message),
|
|
2568
|
+
warn: (message) => logger.warn(message)
|
|
2569
|
+
}
|
|
2570
|
+
});
|
|
2541
2571
|
if (process.env.UBEAN_BUILD_DRIVEN_BY_CLI === "1") return void 0;
|
|
2542
2572
|
return {
|
|
2543
2573
|
/**
|
|
@@ -2574,6 +2604,9 @@ function ubeanPlugin(options) {
|
|
|
2574
2604
|
environments: await buildEnvironmentsForConfig(ubeanConfig)
|
|
2575
2605
|
};
|
|
2576
2606
|
},
|
|
2607
|
+
configResolved(resolved) {
|
|
2608
|
+
resolvedImportMetaEnv = resolved.env;
|
|
2609
|
+
},
|
|
2577
2610
|
async buildStart() {
|
|
2578
2611
|
if (!ubeanConfig) {
|
|
2579
2612
|
ubeanConfig = await loadUbeanConfig();
|
|
@@ -2756,7 +2789,9 @@ function ubeanPlugin(options) {
|
|
|
2756
2789
|
buildDir: ".ubean",
|
|
2757
2790
|
dirs: ubeanConfig.dir,
|
|
2758
2791
|
autoImports: ubeanConfig.autoImports,
|
|
2759
|
-
components: ubeanConfig.components
|
|
2792
|
+
components: ubeanConfig.components,
|
|
2793
|
+
env: ubeanConfig.env,
|
|
2794
|
+
importMetaEnv: resolvedImportMetaEnv
|
|
2760
2795
|
});
|
|
2761
2796
|
} catch (err) {
|
|
2762
2797
|
logger.warn(`Failed to generate type definitions: ${err instanceof Error ? err.message : String(err)}`);
|
package/dist/vite.d.ts
CHANGED
|
@@ -135,16 +135,21 @@ export declare function isFrameworkHtmlPage(url: string): boolean;
|
|
|
135
135
|
*/
|
|
136
136
|
export declare function isViteResourceRequest(url: string, headers?: IncomingMessage['headers']): boolean;
|
|
137
137
|
/**
|
|
138
|
-
*
|
|
138
|
+
* 收集 render-blocking CSS 链接。
|
|
139
139
|
*
|
|
140
|
-
* dev 下由 JS 引入的 CSS
|
|
141
|
-
*
|
|
142
|
-
*
|
|
140
|
+
* dev 下由 JS 引入的 CSS 要等模块图执行完才生效,SSR HTML 在这段间隙是**无样式**的(FOUC)。
|
|
141
|
+
* 把同一批 CSS 以阻塞 `<link>` 注入,浏览器可与 JS 并行抓取,首屏即有样式。
|
|
142
|
+
*
|
|
143
|
+
* 数据源是 **ssr + client 两个模块图**,缺一不可:
|
|
144
|
+
* - `client` 提供客户端入口 import 的全局样式(虚拟 uno.css、`@vean/ui/styles.css`);
|
|
145
|
+
* - `ssr` 提供 SFC `<style>` 块,且**首次页面请求时 client 图是空的**(它由浏览器后续请求
|
|
146
|
+
* 客户端入口才填充)—— 只读 client 图等于首个请求永远注入 0 个链接,正是 FOUC 的来源。
|
|
143
147
|
*
|
|
144
148
|
* `?direct` 让 Vite 的 transform 中间件返回原始 CSS(`Content-Type: text/css`)而不是注入式 JS
|
|
145
|
-
*
|
|
149
|
+
* 包装。它必须紧跟路径(`?direct&vue&…`):Vite 的 `CSS_LANGS_RE` 只认 `.css` 结尾或紧跟
|
|
150
|
+
* `?`,写成 `&lang.css&direct` 会落到 JS 分支,浏览器拒绝把 JS 当样式表。
|
|
146
151
|
*/
|
|
147
|
-
export declare function collectDevCssLinks(
|
|
152
|
+
export declare function collectDevCssLinks(server: ViteDevServer): string[];
|
|
148
153
|
/** 在 `</head>` 前插入阻塞样式链接。 */
|
|
149
154
|
export declare function injectStylesheetLinks(html: string, hrefs: string[]): string;
|
|
150
155
|
interface DevRequestRouterOptions {
|
package/dist/vite.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { m as createVirtualRegistry } from "./ssr-singleton-Bbds29jS.js";
|
|
2
|
-
import { A as toVueRouterPagePath, C as bootstrapDevApp, D as resolveLocaleVueParam, E as resolveDevSecurityHeaders, O as enhanceDevApp, S as peekDevScanCoordinator, T as createDevAppReady, _ as toWebRequest, b as getDevScanCoordinator, c as collectDevCssLinks, d as getDevApp, f as injectStylesheetLinks, g as sendWebResponse, h as ubeanDevRequestPlugin, k as buildDevSsrRoutes, l as createUbeanRequestHandlers, m as isViteResourceRequest, p as isFrameworkHtmlPage, s as DEVTOOLS_PASS_THROUGH_PREFIXES, u as ensureDevApp, v as DEV_SCAN_DIRS, w as createDevApp, x as onDevScan, y as createDevScanCoordinator } from "./vue-
|
|
3
|
-
import { D as createCloudflarePreviewRunner, E as MINIFLARE_INSTALL_HINT, O as defaultLoadMiniflare, _ as ubeanPreviewPlugin, a as createEnvRunnerTransport, c as getDevWorkerEntrySource, d as attachPreviewMiddleware, f as createPreviewMiddleware, g as sendPreviewStatus, h as sendPreviewFile, i as bridgeEnvRunnerInvokes, k as readCompatibilityDate, l as invalidateDevWorkerModules, m as resolvePreviewFile, n as UBEAN_DEV_ENV_NAME, o as createUbeanDevEnvironmentFactory, p as previewMimeType, r as UbeanDevEnvironment, s as DEV_WORKER_FILE, t as ubeanPlugin, u as writeDevWorkerEntry } from "./vite-
|
|
2
|
+
import { A as toVueRouterPagePath, C as bootstrapDevApp, D as resolveLocaleVueParam, E as resolveDevSecurityHeaders, O as enhanceDevApp, S as peekDevScanCoordinator, T as createDevAppReady, _ as toWebRequest, b as getDevScanCoordinator, c as collectDevCssLinks, d as getDevApp, f as injectStylesheetLinks, g as sendWebResponse, h as ubeanDevRequestPlugin, k as buildDevSsrRoutes, l as createUbeanRequestHandlers, m as isViteResourceRequest, p as isFrameworkHtmlPage, s as DEVTOOLS_PASS_THROUGH_PREFIXES, u as ensureDevApp, v as DEV_SCAN_DIRS, w as createDevApp, x as onDevScan, y as createDevScanCoordinator } from "./vue-MyIMqUw0.js";
|
|
3
|
+
import { D as createCloudflarePreviewRunner, E as MINIFLARE_INSTALL_HINT, O as defaultLoadMiniflare, _ as ubeanPreviewPlugin, a as createEnvRunnerTransport, c as getDevWorkerEntrySource, d as attachPreviewMiddleware, f as createPreviewMiddleware, g as sendPreviewStatus, h as sendPreviewFile, i as bridgeEnvRunnerInvokes, k as readCompatibilityDate, l as invalidateDevWorkerModules, m as resolvePreviewFile, n as UBEAN_DEV_ENV_NAME, o as createUbeanDevEnvironmentFactory, p as previewMimeType, r as UbeanDevEnvironment, s as DEV_WORKER_FILE, t as ubeanPlugin, u as writeDevWorkerEntry } from "./vite-DR0qiIma.js";
|
|
4
4
|
export { DEVTOOLS_PASS_THROUGH_PREFIXES, DEV_SCAN_DIRS, DEV_WORKER_FILE, MINIFLARE_INSTALL_HINT, UBEAN_DEV_ENV_NAME, UbeanDevEnvironment, attachPreviewMiddleware, bootstrapDevApp, bridgeEnvRunnerInvokes, buildDevSsrRoutes, collectDevCssLinks, createCloudflarePreviewRunner, createDevApp, createDevAppReady, createDevScanCoordinator, createEnvRunnerTransport, createPreviewMiddleware, createUbeanDevEnvironmentFactory, createUbeanRequestHandlers, createVirtualRegistry, defaultLoadMiniflare, enhanceDevApp, ensureDevApp, getDevApp, getDevScanCoordinator, getDevWorkerEntrySource, injectStylesheetLinks, invalidateDevWorkerModules, isFrameworkHtmlPage, isViteResourceRequest, onDevScan, peekDevScanCoordinator, previewMimeType, readCompatibilityDate, resolveDevSecurityHeaders, resolveLocaleVueParam, resolvePreviewFile, sendPreviewFile, sendPreviewStatus, sendWebResponse, toVueRouterPagePath, toWebRequest, ubeanDevRequestPlugin, ubeanPlugin, ubeanPreviewPlugin, writeDevWorkerEntry };
|