@4399ywkf/core 5.1.6 → 5.3.1

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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { G as GeneratorContext, e as PluginHooks, Y as YwkfConfig, f as PluginConfig } from './schema-Ba1qfYz_.js';
2
- export { A as AnalyticsPluginOptions, h as BiomePluginOptions, j as BrowserCheckPluginOptions, k as BrowserMinVersions, y as BuildHooks, C as CodeInjection, D as DevServerConfig, E as EnvConfig, m as GarfishPluginOptions, F as GeneratedFile, J as GeneratorHooks, H as HtmlConfig, I as I18nPluginOptions, M as MicroFrontendConfig, q as MockPluginOptions, b as OutputConfig, P as PerformanceConfig, K as PluginContext, s as ReactQueryPluginOptions, R as RouterConfig, L as RouterHooks, N as RuntimeHooks, S as StyleConfig, u as TailwindPluginOptions, v as ThemePluginOptions, T as ToolsConfig, Q as YwkfPlugin, Z as ZustandPluginOptions, g as analyticsPlugin, i as biomePlugin, l as browserCheckPlugin, d as defaultConfig, a as defineConfig, n as garfishPlugin, o as getDefaultBiomeConfig, p as i18nPlugin, r as mockPlugin, t as reactQueryPlugin, w as tailwindPlugin, x as themePlugin, z as zustandPlugin } from './schema-Ba1qfYz_.js';
1
+ import { G as GeneratorContext, e as PluginHooks, Y as YwkfConfig, f as PluginConfig } from './schema-Ade9gA3U.js';
2
+ export { A as AnalyticsPluginOptions, h as BiomePluginOptions, j as BrowserCheckPluginOptions, k as BrowserMinVersions, y as BuildHooks, C as CodeInjection, D as DevServerConfig, E as EnvConfig, m as GarfishPluginOptions, F as GeneratedFile, J as GeneratorHooks, H as HtmlConfig, I as I18nPluginOptions, M as MicroFrontendConfig, q as MockPluginOptions, b as OutputConfig, P as PerformanceConfig, K as PluginContext, s as ReactQueryPluginOptions, R as RouterConfig, L as RouterHooks, N as RuntimeHooks, S as StyleConfig, u as TailwindPluginOptions, v as ThemePluginOptions, T as ToolsConfig, Q as YwkfPlugin, Z as ZustandPluginOptions, g as analyticsPlugin, i as biomePlugin, l as browserCheckPlugin, d as defaultConfig, a as defineConfig, n as garfishPlugin, o as getDefaultBiomeConfig, p as i18nPlugin, r as mockPlugin, t as reactQueryPlugin, w as tailwindPlugin, x as themePlugin, z as zustandPlugin } from './schema-Ade9gA3U.js';
3
3
  import { Compiler } from '@rspack/core';
4
4
  export { PluginManager, createPlugin, definePlugin } from './plugin/index.js';
5
5
  export { ConventionalRouteGenerator, ConventionalRoutePlugin, ConventionalRoutePluginOptions, GeneratorOptions, RouteConfig, generateConventionalRoutes } from './router/index.js';
package/dist/index.js CHANGED
@@ -765,7 +765,7 @@ function scaffoldI18nRc(cwd, localesDir, defaultLocale, locales, logger) {
765
765
  const filePath = join3(cwd, ".i18nrc.js");
766
766
  if (existsSync3(filePath)) return;
767
767
  const outputLocales = locales.filter((l) => l !== defaultLocale).map((l) => `"${l}"`).join(", ");
768
- const content = `const { defineConfig } = require("@lobehub/i18n-cli");
768
+ const content = `const { defineConfig } = require("@4399ywkf/i18n");
769
769
 
770
770
  module.exports = defineConfig({
771
771
  entry: "${localesDir}/${defaultLocale}",
@@ -775,7 +775,7 @@ module.exports = defineConfig({
775
775
  });
776
776
  `;
777
777
  writeFileSync2(filePath, content, "utf-8");
778
- logger.info("\u5DF2\u751F\u6210\u7FFB\u8BD1\u914D\u7F6E: .i18nrc.js\uFF08@lobehub/i18n-cli\uFF09");
778
+ logger.info("\u5DF2\u751F\u6210\u7FFB\u8BD1\u914D\u7F6E: .i18nrc.js\uFF08\u9700\u5B89\u88C5 @4399ywkf/i18n\uFF09");
779
779
  }
780
780
  function scaffoldLocaleJsonDirs(cwd, localesDir, locales, defaultLocale, namespaces, logger) {
781
781
  const baseDir = join3(cwd, localesDir);
@@ -876,7 +876,7 @@ function createMockMiddleware(mockPath, options) {
876
876
  scanMockFiles(mockPath);
877
877
  return async (_req, _res, next) => {
878
878
  if (delay > 0) {
879
- await new Promise((resolve5) => setTimeout(resolve5, delay));
879
+ await new Promise((resolve6) => setTimeout(resolve6, delay));
880
880
  }
881
881
  next();
882
882
  };
@@ -1830,11 +1830,11 @@ var zustandPlugin = createPlugin((options = {}) => ({
1830
1830
  const hooks = {
1831
1831
  modifyRspackConfig(rspackConfig) {
1832
1832
  logger.info("Zustand \u5DF2\u542F\u7528");
1833
- const resolve5 = rspackConfig.resolve || {};
1834
- const alias = resolve5.alias || {};
1833
+ const resolve6 = rspackConfig.resolve || {};
1834
+ const alias = resolve6.alias || {};
1835
1835
  alias["@store"] = storePath;
1836
- resolve5.alias = alias;
1837
- rspackConfig.resolve = resolve5;
1836
+ resolve6.alias = alias;
1837
+ rspackConfig.resolve = resolve6;
1838
1838
  return rspackConfig;
1839
1839
  },
1840
1840
  generateFiles(_ctx) {
@@ -2175,7 +2175,9 @@ var defaultConfig = {
2175
2175
  tools: {},
2176
2176
  env: {
2177
2177
  publicEnvFile: "config/env/.env.public",
2178
- envDir: "config/env"
2178
+ envDir: "config/env",
2179
+ expose: [],
2180
+ exposePrefixes: ["YWKF_PUBLIC_", "NEXT_PUBLIC_"]
2179
2181
  },
2180
2182
  alias: {},
2181
2183
  plugins: []
@@ -3440,6 +3442,69 @@ var YwkfGeneratorPlugin = class {
3440
3442
  }
3441
3443
  };
3442
3444
 
3445
+ // src/rspack/client-env.ts
3446
+ import { existsSync as existsSync12, readFileSync as readFileSync4 } from "fs";
3447
+ import { resolve as resolve3 } from "path";
3448
+ import dotenv from "dotenv";
3449
+ var FRAMEWORK_ENV_KEYS = [
3450
+ "APP_CNAME",
3451
+ "APP_HOST",
3452
+ "APP_MODE",
3453
+ "APP_NAME",
3454
+ "APP_PORT",
3455
+ "DEBUG",
3456
+ "NODE_ENV",
3457
+ "OUTPUT_PATH",
3458
+ "PUBLIC_PATH",
3459
+ "YWKF_BUILD_ID",
3460
+ "YWKF_PREFIX_CLS"
3461
+ ];
3462
+ var DEFAULT_EXPOSE_PREFIXES = ["YWKF_PUBLIC_", "NEXT_PUBLIC_"];
3463
+ var SECRET_KEY_PATTERN = /TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|PRIVATE|AUTH|ACCESS_KEY|API_KEY|SIGNING_KEY/i;
3464
+ var SECRET_VALUE_PATTERN = /^(sntry[su]_|sk-|ghp_|gho_|ghu_|ghs_|github_pat_|glpat-|xox[abprs]-|AKIA|ya29\.)/;
3465
+ function readEnvFileKeys(filePath) {
3466
+ if (!existsSync12(filePath)) return [];
3467
+ try {
3468
+ return Object.keys(dotenv.parse(readFileSync4(filePath, "utf-8")));
3469
+ } catch {
3470
+ return [];
3471
+ }
3472
+ }
3473
+ function collectClientEnvKeys(options) {
3474
+ const { cwd, env = {}, mode = process.env.APP_MODE || "development" } = options;
3475
+ const keys = new Set(FRAMEWORK_ENV_KEYS);
3476
+ const files = [
3477
+ env.publicEnvFile ?? "config/env/.env.public",
3478
+ ".env.public",
3479
+ ".env",
3480
+ `${env.envDir ?? "config/env"}/.env.${mode}`,
3481
+ `.env.${mode}`
3482
+ ];
3483
+ for (const file of files) {
3484
+ for (const key of readEnvFileKeys(resolve3(cwd, file))) keys.add(key);
3485
+ }
3486
+ for (const key of env.expose ?? []) keys.add(key);
3487
+ return keys;
3488
+ }
3489
+ function buildClientEnv(options) {
3490
+ const { cwd, env = {}, mode, processEnv = process.env } = options;
3491
+ const prefixes = env.exposePrefixes ?? DEFAULT_EXPOSE_PREFIXES;
3492
+ const allowed = collectClientEnvKeys({ cwd, env, mode });
3493
+ const result = {};
3494
+ const dropped = [];
3495
+ for (const [key, value] of Object.entries(processEnv)) {
3496
+ if (value === void 0) continue;
3497
+ const isAllowed = allowed.has(key) || prefixes.some((prefix) => key.startsWith(prefix));
3498
+ if (!isAllowed) continue;
3499
+ if (SECRET_KEY_PATTERN.test(key) || SECRET_VALUE_PATTERN.test(value)) {
3500
+ dropped.push(key);
3501
+ continue;
3502
+ }
3503
+ result[key] = value;
3504
+ }
3505
+ return { env: result, dropped };
3506
+ }
3507
+
3443
3508
  // src/rspack/base.ts
3444
3509
  var require2 = createRequire(import.meta.url);
3445
3510
  var __dirname = dirname(fileURLToPath(import.meta.url));
@@ -3458,6 +3523,12 @@ function createBaseConfig(config, cwd, options = {}) {
3458
3523
  const { resolveApp } = createPathResolver(cwd);
3459
3524
  const { appName, appCName, output, html, alias: userAlias, microFrontend, router, reactCompiler } = config;
3460
3525
  const buildId = resolveYwkfBuildId(appName);
3526
+ const { env: clientEnv, dropped: droppedEnvKeys } = buildClientEnv({ cwd, env: config.env });
3527
+ if (droppedEnvKeys.length > 0) {
3528
+ console.warn(
3529
+ `[ywkf] \u4EE5\u4E0B\u73AF\u5883\u53D8\u91CF\u7591\u4F3C\u5BC6\u94A5,\u5DF2\u4ECE\u5BA2\u6237\u7AEF\u4EA7\u7269\u4E2D\u5254\u9664:${droppedEnvKeys.join(", ")}\u3002\u5982\u786E\u4E3A\u516C\u5F00\u914D\u7F6E,\u8BF7\u91CD\u547D\u540D\u6216\u8C03\u6574 env.expose\u3002`
3530
+ );
3531
+ }
3461
3532
  const ywkfOutputDir = resolveApp(".ywkf");
3462
3533
  const defaultAlias = {
3463
3534
  "@": resolveApp("src"),
@@ -3582,7 +3653,10 @@ function createBaseConfig(config, cwd, options = {}) {
3582
3653
  }),
3583
3654
  new rspack2.DefinePlugin({
3584
3655
  "globalThis.__YWKF_BUILD_ID__": JSON.stringify(buildId),
3585
- "process.env": JSON.stringify(process.env)
3656
+ // 只内联白名单内的公开配置。整包 process.env 会把构建机环境(CI 凭据、内网地址)
3657
+ // 写进公网可下载的产物,见 client-env.ts。外层括号不可省:该值以 `{` 开头,
3658
+ // `() => process.env.X` 会被替换成 `() => {…}` 而当成函数块体,导致整条 chunk 语法失败。
3659
+ "process.env": `(${JSON.stringify(clientEnv)})`
3586
3660
  }),
3587
3661
  new rspack2.HtmlRspackPlugin({
3588
3662
  template: resolveApp(html.template ?? "public/index.html"),
@@ -4100,28 +4174,28 @@ function createRspackConfig(config, cwd, options = {}) {
4100
4174
  }
4101
4175
 
4102
4176
  // src/cli/env.ts
4103
- import { existsSync as existsSync12, readFileSync as readFileSync4 } from "fs";
4104
- import { resolve as resolve3 } from "path";
4105
- import dotenv from "dotenv";
4177
+ import { existsSync as existsSync13, readFileSync as readFileSync5 } from "fs";
4178
+ import { resolve as resolve4 } from "path";
4179
+ import dotenv2 from "dotenv";
4106
4180
  function preloadEnv(cwd, mode, nodeEnv) {
4107
4181
  process.env.NODE_ENV = nodeEnv;
4108
4182
  process.env.APP_MODE = mode;
4109
4183
  const defaultPaths = [
4110
- resolve3(cwd, "config/env/.env.public"),
4111
- resolve3(cwd, ".env.public"),
4112
- resolve3(cwd, ".env")
4184
+ resolve4(cwd, "config/env/.env.public"),
4185
+ resolve4(cwd, ".env.public"),
4186
+ resolve4(cwd, ".env")
4113
4187
  ];
4114
4188
  for (const envPath of defaultPaths) {
4115
- if (existsSync12(envPath)) {
4116
- dotenv.config({ path: envPath });
4189
+ if (existsSync13(envPath)) {
4190
+ dotenv2.config({ path: envPath });
4117
4191
  break;
4118
4192
  }
4119
4193
  }
4120
- const modeEnvPaths = [resolve3(cwd, `config/env/.env.${mode}`), resolve3(cwd, `.env.${mode}`)];
4194
+ const modeEnvPaths = [resolve4(cwd, `config/env/.env.${mode}`), resolve4(cwd, `.env.${mode}`)];
4121
4195
  for (const envPath of modeEnvPaths) {
4122
- if (existsSync12(envPath)) {
4123
- const envContent = readFileSync4(envPath, "utf-8");
4124
- const parsed = dotenv.parse(envContent);
4196
+ if (existsSync13(envPath)) {
4197
+ const envContent = readFileSync5(envPath, "utf-8");
4198
+ const parsed = dotenv2.parse(envContent);
4125
4199
  for (const key in parsed) {
4126
4200
  process.env[key] = parsed[key];
4127
4201
  }
@@ -4133,14 +4207,14 @@ function preloadEnv(cwd, mode, nodeEnv) {
4133
4207
  }
4134
4208
  function loadEnv(config, cwd, mode, nodeEnv) {
4135
4209
  const { env } = config;
4136
- const publicEnvPath = resolve3(cwd, env.publicEnvFile ?? "config/env/.env.public");
4137
- if (existsSync12(publicEnvPath)) {
4138
- dotenv.config({ path: publicEnvPath });
4139
- }
4140
- const modeEnvPath = resolve3(cwd, env.envDir ?? "config/env", `.env.${mode}`);
4141
- if (existsSync12(modeEnvPath)) {
4142
- const envContent = readFileSync4(modeEnvPath, "utf-8");
4143
- const parsed = dotenv.parse(envContent);
4210
+ const publicEnvPath = resolve4(cwd, env.publicEnvFile ?? "config/env/.env.public");
4211
+ if (existsSync13(publicEnvPath)) {
4212
+ dotenv2.config({ path: publicEnvPath });
4213
+ }
4214
+ const modeEnvPath = resolve4(cwd, env.envDir ?? "config/env", `.env.${mode}`);
4215
+ if (existsSync13(modeEnvPath)) {
4216
+ const envContent = readFileSync5(modeEnvPath, "utf-8");
4217
+ const parsed = dotenv2.parse(envContent);
4144
4218
  for (const key in parsed) {
4145
4219
  process.env[key] = parsed[key];
4146
4220
  }
@@ -4418,7 +4492,7 @@ async function build(options = {}) {
4418
4492
  rspackConfig.stats = "none";
4419
4493
  rspackConfig.infrastructureLogging = { level: "none" };
4420
4494
  const compiler = rspack4(rspackConfig);
4421
- const stats = await new Promise((resolve5, reject) => {
4495
+ const stats = await new Promise((resolve6, reject) => {
4422
4496
  compiler.run((err, stats2) => {
4423
4497
  if (err) {
4424
4498
  reject(err);
@@ -4428,13 +4502,13 @@ async function build(options = {}) {
4428
4502
  reject(new Error("Build failed: no stats available"));
4429
4503
  return;
4430
4504
  }
4431
- resolve5(stats2);
4505
+ resolve6(stats2);
4432
4506
  });
4433
4507
  });
4434
- await new Promise((resolve5, reject) => {
4508
+ await new Promise((resolve6, reject) => {
4435
4509
  compiler.close((err) => {
4436
4510
  if (err) reject(err);
4437
- else resolve5();
4511
+ else resolve6();
4438
4512
  });
4439
4513
  });
4440
4514
  const hasErrors = stats.hasErrors();
@@ -4476,7 +4550,7 @@ var PortInUseError = class extends Error {
4476
4550
  }
4477
4551
  };
4478
4552
  function ensurePortAvailable(port, host) {
4479
- return new Promise((resolve5, reject) => {
4553
+ return new Promise((resolve6, reject) => {
4480
4554
  const server = net.createServer();
4481
4555
  server.once("error", (err) => {
4482
4556
  if (err.code === "EADDRINUSE") {
@@ -4486,7 +4560,7 @@ function ensurePortAvailable(port, host) {
4486
4560
  }
4487
4561
  });
4488
4562
  server.once("listening", () => {
4489
- server.close(() => resolve5());
4563
+ server.close(() => resolve6());
4490
4564
  });
4491
4565
  server.listen(port, host);
4492
4566
  });
@@ -4534,8 +4608,8 @@ function parseWindowsNetstatPid(stdout, port) {
4534
4608
  }
4535
4609
 
4536
4610
  // src/cli/restart-watcher.ts
4537
- import { existsSync as existsSync13, watch as watch2 } from "fs";
4538
- import { resolve as resolve4 } from "path";
4611
+ import { existsSync as existsSync14, watch as watch2 } from "fs";
4612
+ import { resolve as resolve5 } from "path";
4539
4613
  function isTriggerFile(filename, mode) {
4540
4614
  if (!filename) return false;
4541
4615
  if (CONFIG_FILES.includes(filename)) return true;
@@ -4565,8 +4639,8 @@ function watchForRestart(opts) {
4565
4639
  }, debounceMs);
4566
4640
  };
4567
4641
  watchers.push(watch2(cwd, { recursive: false }, (_event, filename) => trigger(filename)));
4568
- const envDir = resolve4(cwd, "config/env");
4569
- if (existsSync13(envDir)) {
4642
+ const envDir = resolve5(cwd, "config/env");
4643
+ if (existsSync14(envDir)) {
4570
4644
  watchers.push(watch2(envDir, { recursive: false }, (_event, filename) => trigger(filename)));
4571
4645
  }
4572
4646
  return {
@@ -4673,10 +4747,10 @@ async function startDevServer(cwd, config) {
4673
4747
  if (closed) return;
4674
4748
  closed = true;
4675
4749
  await server.stop();
4676
- await new Promise((resolve5, reject) => {
4750
+ await new Promise((resolve6, reject) => {
4677
4751
  compiler.close((err) => {
4678
4752
  if (err) reject(err);
4679
- else resolve5();
4753
+ else resolve6();
4680
4754
  });
4681
4755
  });
4682
4756
  };
@@ -4771,7 +4845,7 @@ async function dev(options = {}) {
4771
4845
  }
4772
4846
 
4773
4847
  // src/router/plugin.ts
4774
- import { existsSync as existsSync14, watch as watch3 } from "fs";
4848
+ import { existsSync as existsSync15, watch as watch3 } from "fs";
4775
4849
  import { join as join14 } from "path";
4776
4850
  var ConventionalRoutePlugin = class {
4777
4851
  options;
@@ -4827,7 +4901,7 @@ var ConventionalRoutePlugin = class {
4827
4901
  * 监听页面目录变化
4828
4902
  */
4829
4903
  watchPages(compiler) {
4830
- if (!existsSync14(this.options.pagesDir)) {
4904
+ if (!existsSync15(this.options.pagesDir)) {
4831
4905
  return;
4832
4906
  }
4833
4907
  this.isWatching = true;