@lark-apaas/fullstack-cli 1.1.60 → 1.1.61-alpha.20260818172555

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.
@@ -76,49 +76,13 @@ function isStylelintTarget(filePath) {
76
76
  return filePath.endsWith('.css');
77
77
  }
78
78
 
79
- const STYLELINT_CONFIG_FILES = [
80
- '.stylelintrc',
81
- '.stylelintrc.js',
82
- '.stylelintrc.cjs',
83
- '.stylelintrc.json',
84
- 'stylelint.config.js',
85
- ];
86
-
87
- /**
88
- * 老模板(fullstack-nestjs-template 1.x 时代)的应用跑不了 stylelint,跑了就挂、把 pre-commit
89
- * 卡死。两种形态都实测过:
90
- *
91
- * - 缺 scripts.stylelint → `npm error Missing script: "stylelint"`
92
- * - 缺 .stylelintrc.* → `ConfigurationError: No configuration provided`
93
- *
94
- * 注意光判断 stylelint 装没装拦不住:@lark-apaas/fullstack-presets 的 dependencies 里有
95
- * stylelint,只要 dep 了 presets 二进制就在。缺任一件就跳过这一步。
96
- */
97
- function canRunStylelint() {
98
- let pkg;
99
- try {
100
- pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8'));
101
- } catch {
102
- return false;
103
- }
104
-
105
- if (!pkg.scripts || !pkg.scripts.stylelint) return false;
106
-
107
- return STYLELINT_CONFIG_FILES.some(file => fs.existsSync(path.join(cwd, file)));
108
- }
109
-
110
79
  async function runDefaultLint() {
111
80
  const taskSpecs = [
112
81
  [getBinName('npm'), ['run', 'eslint']],
113
82
  [getBinName('npm'), ['run', 'type:check']],
83
+ [getBinName('npm'), ['run', 'stylelint']],
114
84
  ];
115
85
 
116
- if (canRunStylelint()) {
117
- taskSpecs.push([getBinName('npm'), ['run', 'stylelint']]);
118
- } else {
119
- console.warn('[lint] Skip stylelint: missing scripts.stylelint or stylelint config');
120
- }
121
-
122
86
  process.exit(await runTasksSerially(taskSpecs));
123
87
  }
124
88
 
@@ -156,9 +120,7 @@ async function runSelectiveLint(inputFiles) {
156
120
  taskSpecs.push([getBinName('npx'), ['eslint', '--quiet', ...eslintFiles]]);
157
121
  }
158
122
 
159
- if (stylelintFiles.length > 0 && !canRunStylelint()) {
160
- console.warn('[lint] Skip stylelint: missing scripts.stylelint or stylelint config');
161
- } else if (stylelintFiles.length > 0) {
123
+ if (stylelintFiles.length > 0) {
162
124
  taskSpecs.push([getBinName('npx'), ['stylelint', '--quiet', ...stylelintFiles]]);
163
125
  }
164
126
 
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env node
2
+
3
+ import crypto from 'node:crypto';
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+
7
+ const runtimeRoot = path.resolve(
8
+ process.argv[2] ||
9
+ process.env.MIAODA_PLATFORM_RUNTIME_ROOT ||
10
+ '/opt/miaoda/preview-runtime'
11
+ );
12
+ const vitePackageFile = path.join(
13
+ runtimeRoot,
14
+ 'node_modules',
15
+ 'vite',
16
+ 'package.json'
17
+ );
18
+ const targetFile = path.join(
19
+ runtimeRoot,
20
+ 'node_modules',
21
+ 'vite',
22
+ 'dist',
23
+ 'node',
24
+ 'chunks',
25
+ 'node.js'
26
+ );
27
+ const markerFile = path.join(
28
+ runtimeRoot,
29
+ '.miaoda-vite-dependency-hash-patch.json'
30
+ );
31
+ const expectedVersion = '8.1.5';
32
+ const patchId = 'vite-8.1.5-cache-runtime-identity-v4';
33
+ const expectedTargetSha256 =
34
+ '3968fab97a9d0882f0e2e754bd0d5b417f0a84596e293179a9a6e585919f041c';
35
+ const originalLockfileHash = `function getLockfileHash(environment) {
36
+ \tconst lockfilePath = lookupFile(environment.config.root, lockfilePaths);`;
37
+ const patchedLockfileHash = `function getLockfileHash(environment) {
38
+ \tconst miaodaClientDependencyGraphHash = process.env.MIAODA_VITE_DEPENDENCY_GRAPH_HASH;
39
+ \tif (miaodaClientDependencyGraphHash !== void 0) {
40
+ \t\tif (!/^[a-f0-9]{64}$/.test(miaodaClientDependencyGraphHash)) throw new Error("MIAODA_VITE_DEPENDENCY_GRAPH_HASH_INVALID");
41
+ \t\treturn miaodaClientDependencyGraphHash;
42
+ \t}
43
+ \tconst lockfilePath = lookupFile(environment.config.root, lockfilePaths);`;
44
+ const originalConfigBundleRoot = `async function bundleConfigFile(fileName, isESM) {
45
+ \tlet importMetaResolverRegistered = false;
46
+ \tconst root = path.dirname(fileName);
47
+ \tconst dirnameVarName = "__vite_injected_original_dirname";`;
48
+ const patchedConfigBundleRoot = `async function bundleConfigFile(fileName, isESM) {
49
+ \tlet importMetaResolverRegistered = false;
50
+ \tconst root = path.dirname(fileName);
51
+ \tlet miaodaConfigPackageAliases = Object.create(null);
52
+ \tconst miaodaConfigPackageAliasesRaw = process.env.MIAODA_VITE_CONFIG_PACKAGE_ALIASES;
53
+ \tconst miaodaConfigRuntimeRoot = process.env.MIAODA_PLATFORM_RUNTIME_ROOT;
54
+ \tif (process.env.MIAODA_CACHE_BOOTSTRAP_ENABLED === "true" && miaodaConfigPackageAliasesRaw !== void 0) {
55
+ \t\ttry {
56
+ \t\t\tconst parsed = JSON.parse(miaodaConfigPackageAliasesRaw);
57
+ \t\t\tconst realRuntimeRoot = fs.realpathSync(miaodaConfigRuntimeRoot);
58
+ \t\t\tif (!parsed || Array.isArray(parsed) || typeof parsed !== "object") throw new Error("aliases");
59
+ \t\t\tfor (const [packageName, entry] of Object.entries(parsed)) {
60
+ \t\t\t\tif (!/^(?:@[a-z0-9][a-z0-9._~-]*\\/)?[a-z0-9][a-z0-9._~-]*$/i.test(packageName) || typeof entry !== "string" || !path.isAbsolute(entry)) throw new Error("entry");
61
+ \t\t\t\tconst realEntry = fs.realpathSync(entry);
62
+ \t\t\t\tconst relative = path.relative(realRuntimeRoot, realEntry);
63
+ \t\t\t\tif (relative === ".." || relative.startsWith(\`..\${path.sep}\`) || path.isAbsolute(relative)) throw new Error("path");
64
+ \t\t\t\tmiaodaConfigPackageAliases[packageName] = realEntry;
65
+ \t\t\t}
66
+ \t\t} catch {
67
+ \t\t\tthrow new Error("MIAODA_VITE_CONFIG_PACKAGE_ALIASES_INVALID");
68
+ \t\t}
69
+ \t}
70
+ \tconst dirnameVarName = "__vite_injected_original_dirname";`;
71
+ const originalConfigPackageResolve = `idFsPath = nodeResolveWithVite(id, importer, {`;
72
+ const patchedConfigPackageResolve = `idFsPath = Object.hasOwn(miaodaConfigPackageAliases, id) ? miaodaConfigPackageAliases[id] : nodeResolveWithVite(id, importer, {`;
73
+
74
+ for (const file of [vitePackageFile, targetFile]) {
75
+ if (!fs.existsSync(file)) {
76
+ throw new Error(`MIAODA_VITE_PATCH_INPUT_MISSING: ${file}`);
77
+ }
78
+ }
79
+ const vitePackage = JSON.parse(fs.readFileSync(vitePackageFile, 'utf8'));
80
+ if (vitePackage.version !== expectedVersion) {
81
+ throw new Error(
82
+ `MIAODA_VITE_PATCH_VERSION_MISMATCH: expected=${expectedVersion} actual=${vitePackage.version}`
83
+ );
84
+ }
85
+
86
+ let source = fs.readFileSync(targetFile, 'utf8');
87
+ const alreadyPatched =
88
+ source.includes(patchedLockfileHash) &&
89
+ source.includes(patchedConfigBundleRoot) &&
90
+ source.includes(patchedConfigPackageResolve);
91
+ if (alreadyPatched) {
92
+ if (
93
+ source.includes(originalLockfileHash) ||
94
+ source.includes(originalConfigBundleRoot) ||
95
+ source.includes(originalConfigPackageResolve)
96
+ ) {
97
+ throw new Error('MIAODA_VITE_PATCH_STATE_INVALID');
98
+ }
99
+ } else {
100
+ const targetSha256 = crypto.createHash('sha256').update(source).digest('hex');
101
+ if (targetSha256 !== expectedTargetSha256) {
102
+ throw new Error(
103
+ `MIAODA_VITE_PATCH_TARGET_SHA_MISMATCH: expected=${expectedTargetSha256} actual=${targetSha256}`
104
+ );
105
+ }
106
+ const sentinels = [
107
+ originalLockfileHash,
108
+ originalConfigBundleRoot,
109
+ originalConfigPackageResolve,
110
+ ];
111
+ if (sentinels.some(sentinel => source.split(sentinel).length - 1 !== 1)) {
112
+ throw new Error(
113
+ 'MIAODA_VITE_PATCH_SENTINEL_MISMATCH: expected exactly one of each sentinel'
114
+ );
115
+ }
116
+ source = source
117
+ .replace(originalLockfileHash, patchedLockfileHash)
118
+ .replace(originalConfigBundleRoot, patchedConfigBundleRoot)
119
+ .replace(originalConfigPackageResolve, patchedConfigPackageResolve);
120
+ fs.writeFileSync(targetFile, source);
121
+ }
122
+
123
+ const targetSha256 = crypto
124
+ .createHash('sha256')
125
+ .update(fs.readFileSync(targetFile))
126
+ .digest('hex');
127
+ fs.writeFileSync(
128
+ markerFile,
129
+ `${JSON.stringify(
130
+ {
131
+ schemaVersion: 1,
132
+ patchId,
133
+ viteVersion: expectedVersion,
134
+ target: 'node_modules/vite/dist/node/chunks/node.js',
135
+ targetSha256,
136
+ },
137
+ null,
138
+ 2
139
+ )}\n`
140
+ );
141
+ process.stdout.write(`${patchId}\n`);
@@ -0,0 +1,63 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+ const Module = require('node:module');
6
+ const { createRequire, isBuiltin } = Module;
7
+
8
+ const configuredCacheNodeModules = path.resolve(
9
+ process.env.MIAODA_SERVER_CACHE_NODE_MODULES || ''
10
+ );
11
+ if (
12
+ !process.env.MIAODA_SERVER_CACHE_NODE_MODULES ||
13
+ !fs.existsSync(configuredCacheNodeModules) ||
14
+ !fs.statSync(configuredCacheNodeModules).isDirectory()
15
+ ) {
16
+ throw new Error('MIAODA_SERVER_CACHE_NODE_MODULES_INVALID');
17
+ }
18
+ const cacheNodeModules = fs.realpathSync(configuredCacheNodeModules);
19
+
20
+ const cacheRequire = createRequire(
21
+ path.join(path.dirname(cacheNodeModules), 'cache-runtime-entry.cjs')
22
+ );
23
+ const originalResolveFilename = Module._resolveFilename;
24
+
25
+ function isBarePackageRequest(request) {
26
+ return (
27
+ typeof request === 'string' &&
28
+ request.length > 0 &&
29
+ !isBuiltin(request) &&
30
+ !request.startsWith('.') &&
31
+ !path.isAbsolute(request) &&
32
+ !request.startsWith('#')
33
+ );
34
+ }
35
+
36
+ function isInsideCache(filename) {
37
+ if (typeof filename !== 'string' || !filename) return false;
38
+ const relative = path.relative(cacheNodeModules, filename);
39
+ return (
40
+ relative === '' ||
41
+ (!relative.startsWith('..') && !path.isAbsolute(relative))
42
+ );
43
+ }
44
+
45
+ Module._resolveFilename = function miaodaCacheFirstResolve(
46
+ request,
47
+ parent,
48
+ isMain,
49
+ options
50
+ ) {
51
+ // Packages already executing from the cache must keep Node's native lookup
52
+ // order so their nested dependency versions win over the cache root. Only a
53
+ // bare import originating in workspace source needs the cache entrypoint.
54
+ if (isBarePackageRequest(request) && !isInsideCache(parent?.filename)) {
55
+ try {
56
+ return cacheRequire.resolve(request);
57
+ } catch {
58
+ // Workspace aliases such as @server/* are intentionally delegated to
59
+ // tsconfig-paths and Node's original resolver.
60
+ }
61
+ }
62
+ return originalResolveFilename.call(this, request, parent, isMain, options);
63
+ };