@lark-apaas/fullstack-cli 1.1.15 → 1.1.16-alpha.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/config/drizzle.config.js +24 -1
- package/dist/index.js +90 -26
- package/package.json +2 -3
|
@@ -7,8 +7,31 @@ var envSchemaFilter = process.env.DRIZZLE_SCHEMA_FILTER;
|
|
|
7
7
|
var urlSchemaFilter = parsedUrl.searchParams.get("schema");
|
|
8
8
|
var schemaFilter = (envSchemaFilter ?? urlSchemaFilter ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
9
9
|
parsedUrl.searchParams.delete("schema");
|
|
10
|
+
var SYSTEM_OBJECTS_EXCLUSIONS = [
|
|
11
|
+
"!spatial_ref_sys",
|
|
12
|
+
// PostGIS 空间参考系统表
|
|
13
|
+
"!geography_columns",
|
|
14
|
+
// PostGIS 地理列视图
|
|
15
|
+
"!geometry_columns",
|
|
16
|
+
// PostGIS 几何列视图
|
|
17
|
+
"!raster_columns",
|
|
18
|
+
// PostGIS 栅格列视图
|
|
19
|
+
"!raster_overviews",
|
|
20
|
+
// PostGIS 栅格概览视图
|
|
21
|
+
"!pg_stat_statements",
|
|
22
|
+
// pg_stat_statements 扩展
|
|
23
|
+
"!pg_stat_statements_info",
|
|
24
|
+
// pg_stat_statements 扩展
|
|
25
|
+
"!part_config",
|
|
26
|
+
// pg_partman 分区配置表
|
|
27
|
+
"!part_config_sub",
|
|
28
|
+
// pg_partman 子分区配置表
|
|
29
|
+
"!table_privs"
|
|
30
|
+
// 系统权限视图
|
|
31
|
+
];
|
|
10
32
|
var envTablesFilter = process.env.DRIZZLE_TABLES_FILTER;
|
|
11
|
-
var
|
|
33
|
+
var userTablesFilter = (envTablesFilter ?? "*").split(",").map((s) => s.trim()).filter(Boolean);
|
|
34
|
+
var tablesFilter = [...userTablesFilter, ...SYSTEM_OBJECTS_EXCLUSIONS];
|
|
12
35
|
var config = {
|
|
13
36
|
schema: schemaPath,
|
|
14
37
|
out: outputDir,
|
package/dist/index.js
CHANGED
|
@@ -128,19 +128,28 @@ import fs2 from "fs";
|
|
|
128
128
|
import path from "path";
|
|
129
129
|
|
|
130
130
|
// src/commands/db/gen-dbschema/helper/header-format.ts
|
|
131
|
+
var ESLINT_DISABLE = "/* eslint-disable */";
|
|
131
132
|
var HEADER_COMMENT = "/** auto generated, do not edit */";
|
|
133
|
+
var FULL_HEADER = `${ESLINT_DISABLE}
|
|
134
|
+
${HEADER_COMMENT}`;
|
|
132
135
|
function ensureHeaderComment(source) {
|
|
133
136
|
let text = source.startsWith("\uFEFF") ? source.slice(1) : source;
|
|
137
|
+
while (text.startsWith(ESLINT_DISABLE)) {
|
|
138
|
+
text = text.slice(ESLINT_DISABLE.length);
|
|
139
|
+
text = stripLeadingNewlines(text);
|
|
140
|
+
}
|
|
134
141
|
while (text.startsWith(HEADER_COMMENT)) {
|
|
135
142
|
text = text.slice(HEADER_COMMENT.length);
|
|
136
143
|
text = stripLeadingNewlines(text);
|
|
137
144
|
}
|
|
138
145
|
const trimmed = stripLeadingNewlines(text);
|
|
139
146
|
if (trimmed.length === 0) {
|
|
140
|
-
return `${
|
|
147
|
+
return `${ESLINT_DISABLE}
|
|
148
|
+
${HEADER_COMMENT}
|
|
141
149
|
`;
|
|
142
150
|
}
|
|
143
|
-
return `${
|
|
151
|
+
return `${ESLINT_DISABLE}
|
|
152
|
+
${HEADER_COMMENT}
|
|
144
153
|
${trimmed}`;
|
|
145
154
|
}
|
|
146
155
|
function stripLeadingNewlines(value) {
|
|
@@ -186,14 +195,16 @@ function convertSchemaTableInvocations(source) {
|
|
|
186
195
|
// src/commands/db/gen-dbschema/helper/table-rename.ts
|
|
187
196
|
import { pinyin } from "pinyin-pro";
|
|
188
197
|
function renamePgTableConstants(source) {
|
|
189
|
-
const pgTableRegex = /export const\s+([
|
|
198
|
+
const pgTableRegex = /export const\s+("?)([^"'\s=]+)\1\s*=\s*(?:\w+\.)?(table|view|materializedView|enum|sequence|pgTable|pgView|pgMaterializedView|pgEnum|pgSequence)\(\s*["'`]([^"'`]+)["'`]/gu;
|
|
190
199
|
const renames = [];
|
|
191
|
-
const updated = source.replace(pgTableRegex, (match, currentName, factory, tableName) => {
|
|
200
|
+
const updated = source.replace(pgTableRegex, (match, quote, currentName, factory, tableName) => {
|
|
192
201
|
const sanitized = sanitizeIdentifier(tableName);
|
|
193
|
-
|
|
202
|
+
const needsRename = quote === '"' || sanitized !== currentName;
|
|
203
|
+
if (!needsRename) {
|
|
194
204
|
return match;
|
|
195
205
|
}
|
|
196
|
-
|
|
206
|
+
const originalRef = quote === '"' ? currentName : currentName;
|
|
207
|
+
renames.push({ from: originalRef, to: sanitized });
|
|
197
208
|
const equalsIndex = match.indexOf("=");
|
|
198
209
|
const suffix = equalsIndex >= 0 ? match.slice(equalsIndex) : ` = ${factory}("${tableName}"`;
|
|
199
210
|
const normalizedSuffix = suffix.trimStart();
|
|
@@ -209,8 +220,13 @@ function updateTableReferenceIdentifiers(source, renames) {
|
|
|
209
220
|
if (!rename.from || rename.from === rename.to) {
|
|
210
221
|
return acc;
|
|
211
222
|
}
|
|
212
|
-
const pattern = new RegExp(`\\b${escapeRegExp(rename.from)}(\\s
|
|
213
|
-
|
|
223
|
+
const pattern = new RegExp(`\\b${escapeRegExp(rename.from)}(\\s*[.(])`, "g");
|
|
224
|
+
let result = acc.replace(pattern, `${rename.to}$1`);
|
|
225
|
+
const quotedCallPattern = new RegExp(`"${escapeRegExp(rename.from)}"(\\s*\\()`, "g");
|
|
226
|
+
result = result.replace(quotedCallPattern, `${rename.to}$1`);
|
|
227
|
+
const quotedDotPattern = new RegExp(`"${escapeRegExp(rename.from)}"(\\s*\\.)`, "g");
|
|
228
|
+
result = result.replace(quotedDotPattern, `${rename.to}$1`);
|
|
229
|
+
return result;
|
|
214
230
|
}, source);
|
|
215
231
|
}
|
|
216
232
|
function escapeRegExp(value) {
|
|
@@ -256,16 +272,18 @@ function toAsciiName(name) {
|
|
|
256
272
|
|
|
257
273
|
// src/commands/db/gen-dbschema/helper/custom-types.ts
|
|
258
274
|
var CUSTOM_TYPE_PATTERN = /\/\/ TODO: failed to parse database type '(?:\w+\.)?(user_profile|file_attachment)(\[\])?'/;
|
|
275
|
+
var UNKNOWN_TYPE_TODO_PATTERN = /\/\/ TODO: failed to parse database type '([^']+)'/;
|
|
259
276
|
function replaceUnknownColumns(source) {
|
|
260
277
|
const lines = source.split("\n");
|
|
261
278
|
const result = [];
|
|
262
279
|
let replaced = 0;
|
|
280
|
+
let fallbackToText = 0;
|
|
263
281
|
const unmatched = [];
|
|
264
282
|
for (let i = 0; i < lines.length; i += 1) {
|
|
265
283
|
const line = lines[i];
|
|
266
|
-
const
|
|
267
|
-
if (
|
|
268
|
-
const typeName =
|
|
284
|
+
const knownMatch = line.match(CUSTOM_TYPE_PATTERN);
|
|
285
|
+
if (knownMatch) {
|
|
286
|
+
const typeName = knownMatch[1];
|
|
269
287
|
const factory = typeName === "user_profile" ? "userProfile" : "fileAttachment";
|
|
270
288
|
const replacedLine = replaceFollowingUnknown(lines[i + 1], factory);
|
|
271
289
|
if (replacedLine) {
|
|
@@ -278,6 +296,19 @@ function replaceUnknownColumns(source) {
|
|
|
278
296
|
}
|
|
279
297
|
continue;
|
|
280
298
|
}
|
|
299
|
+
const unknownMatch = line.match(UNKNOWN_TYPE_TODO_PATTERN);
|
|
300
|
+
if (unknownMatch) {
|
|
301
|
+
const replacedLine = replaceFollowingUnknown(lines[i + 1], "text");
|
|
302
|
+
if (replacedLine) {
|
|
303
|
+
result.push(replacedLine);
|
|
304
|
+
fallbackToText += 1;
|
|
305
|
+
i += 1;
|
|
306
|
+
} else {
|
|
307
|
+
unmatched.push(line.trim());
|
|
308
|
+
result.push(line);
|
|
309
|
+
}
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
281
312
|
if (line.includes("unknown(")) {
|
|
282
313
|
unmatched.push(line.trim());
|
|
283
314
|
}
|
|
@@ -286,6 +317,7 @@ function replaceUnknownColumns(source) {
|
|
|
286
317
|
return {
|
|
287
318
|
text: result.join("\n"),
|
|
288
319
|
replaced,
|
|
320
|
+
fallbackToText,
|
|
289
321
|
unmatched
|
|
290
322
|
};
|
|
291
323
|
}
|
|
@@ -355,7 +387,7 @@ function inlineFromTemplateContent(text, templateContent) {
|
|
|
355
387
|
text = text.slice(0, insertPoint) + "import { sql } from 'drizzle-orm';\n" + text.slice(insertPoint);
|
|
356
388
|
}
|
|
357
389
|
}
|
|
358
|
-
const headerPrefix = `${
|
|
390
|
+
const headerPrefix = `${FULL_HEADER}
|
|
359
391
|
`;
|
|
360
392
|
let insertionPoint = 0;
|
|
361
393
|
if (text.startsWith(headerPrefix)) {
|
|
@@ -582,10 +614,13 @@ function postprocessDrizzleSchema(targetPath) {
|
|
|
582
614
|
console.info(`[postprocess-drizzle-schema] Patched ${patchResult.fixed} drizzle-kit defects (.default(') -> .default(''))`);
|
|
583
615
|
}
|
|
584
616
|
if (replacement.replaced > 0) {
|
|
585
|
-
console.info(`[postprocess-drizzle-schema] Replaced ${replacement.replaced} unknown columns`);
|
|
617
|
+
console.info(`[postprocess-drizzle-schema] Replaced ${replacement.replaced} unknown columns with custom types`);
|
|
618
|
+
}
|
|
619
|
+
if (replacement.fallbackToText > 0) {
|
|
620
|
+
console.info(`[postprocess-drizzle-schema] Replaced ${replacement.fallbackToText} unknown columns with text (fallback)`);
|
|
586
621
|
}
|
|
587
622
|
if (replacement.unmatched.length > 0) {
|
|
588
|
-
console.warn("[postprocess-drizzle-schema] Unmatched
|
|
623
|
+
console.warn("[postprocess-drizzle-schema] Unmatched unknown columns:", replacement.unmatched.length);
|
|
589
624
|
replacement.unmatched.forEach((line) => console.warn(` ${line}`));
|
|
590
625
|
}
|
|
591
626
|
if (tableConversion.converted > 0) {
|
|
@@ -599,6 +634,7 @@ function postprocessDrizzleSchema(targetPath) {
|
|
|
599
634
|
}
|
|
600
635
|
return {
|
|
601
636
|
replacedUnknown: replacement.replaced,
|
|
637
|
+
fallbackToText: replacement.fallbackToText,
|
|
602
638
|
unmatchedUnknown: replacement.unmatched,
|
|
603
639
|
patchedDefects: patchResult.fixed,
|
|
604
640
|
replacedTimestamps: timestampReplacement.replaced,
|
|
@@ -1832,10 +1868,13 @@ function getHttpClient() {
|
|
|
1832
1868
|
enabled: true
|
|
1833
1869
|
}
|
|
1834
1870
|
});
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1871
|
+
const canaryEnv = process.env.FORCE_FRAMEWORK_CLI_CANARY_ENV;
|
|
1872
|
+
if (canaryEnv) {
|
|
1873
|
+
clientInstance.interceptors.request.use((req) => {
|
|
1874
|
+
req.headers["x-tt-env"] = canaryEnv;
|
|
1875
|
+
return req;
|
|
1876
|
+
});
|
|
1877
|
+
}
|
|
1839
1878
|
}
|
|
1840
1879
|
return clientInstance;
|
|
1841
1880
|
}
|
|
@@ -2303,7 +2342,7 @@ function listCapabilityIds() {
|
|
|
2303
2342
|
return [];
|
|
2304
2343
|
}
|
|
2305
2344
|
const files = fs8.readdirSync(dir);
|
|
2306
|
-
return files.filter((f) => f.endsWith(".json")).map((f) => f.replace(/\.json$/, ""));
|
|
2345
|
+
return files.filter((f) => f.endsWith(".json") && f !== "capabilities.json").map((f) => f.replace(/\.json$/, ""));
|
|
2307
2346
|
}
|
|
2308
2347
|
function readCapability(id) {
|
|
2309
2348
|
const filePath = getCapabilityPath(id);
|
|
@@ -2322,7 +2361,19 @@ function readCapability(id) {
|
|
|
2322
2361
|
}
|
|
2323
2362
|
function readAllCapabilities() {
|
|
2324
2363
|
const ids = listCapabilityIds();
|
|
2325
|
-
|
|
2364
|
+
const capabilities = [];
|
|
2365
|
+
for (const id of ids) {
|
|
2366
|
+
try {
|
|
2367
|
+
const capability = readCapability(id);
|
|
2368
|
+
if (!capability.pluginKey) {
|
|
2369
|
+
continue;
|
|
2370
|
+
}
|
|
2371
|
+
capabilities.push(capability);
|
|
2372
|
+
} catch {
|
|
2373
|
+
continue;
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
return capabilities;
|
|
2326
2377
|
}
|
|
2327
2378
|
function readPluginManifest(pluginKey) {
|
|
2328
2379
|
const manifestPath = getPluginManifestPath(pluginKey);
|
|
@@ -2557,10 +2608,21 @@ function detectJsonMigration() {
|
|
|
2557
2608
|
try {
|
|
2558
2609
|
const content = fs11.readFileSync(oldFilePath, "utf-8");
|
|
2559
2610
|
const parsed = JSON.parse(content);
|
|
2560
|
-
|
|
2611
|
+
if (!Array.isArray(parsed)) {
|
|
2612
|
+
return {
|
|
2613
|
+
needsMigration: false,
|
|
2614
|
+
reason: "capabilities.json is not a valid array"
|
|
2615
|
+
};
|
|
2616
|
+
}
|
|
2617
|
+
if (parsed.length === 0) {
|
|
2618
|
+
return {
|
|
2619
|
+
needsMigration: false,
|
|
2620
|
+
reason: "capabilities.json is an empty array"
|
|
2621
|
+
};
|
|
2622
|
+
}
|
|
2561
2623
|
return {
|
|
2562
2624
|
needsMigration: true,
|
|
2563
|
-
oldCapabilities:
|
|
2625
|
+
oldCapabilities: parsed,
|
|
2564
2626
|
oldFilePath
|
|
2565
2627
|
};
|
|
2566
2628
|
} catch (error) {
|
|
@@ -3161,13 +3223,15 @@ function analyzeClass(sourceFile) {
|
|
|
3161
3223
|
if (!name) continue;
|
|
3162
3224
|
const isInjectable = hasDecorator(classDecl, "Injectable");
|
|
3163
3225
|
const isController = hasDecorator(classDecl, "Controller");
|
|
3164
|
-
|
|
3226
|
+
const isAutomation = hasDecorator(classDecl, "Automation");
|
|
3227
|
+
if (classInfo && classInfo.isInjectable && !isInjectable && !isController && !isAutomation) {
|
|
3165
3228
|
continue;
|
|
3166
3229
|
}
|
|
3167
3230
|
const info = {
|
|
3168
3231
|
name,
|
|
3169
3232
|
isInjectable,
|
|
3170
3233
|
isController,
|
|
3234
|
+
isAutomation,
|
|
3171
3235
|
constructorParamCount: 0
|
|
3172
3236
|
};
|
|
3173
3237
|
const classBody = classDecl.getChildSyntaxListOrThrow();
|
|
@@ -3186,7 +3250,7 @@ function analyzeClass(sourceFile) {
|
|
|
3186
3250
|
info.constructorParamsEnd = ctor.getStart();
|
|
3187
3251
|
}
|
|
3188
3252
|
}
|
|
3189
|
-
if (isInjectable || isController || !classInfo) {
|
|
3253
|
+
if (isInjectable || isController || isAutomation || !classInfo) {
|
|
3190
3254
|
classInfo = info;
|
|
3191
3255
|
}
|
|
3192
3256
|
}
|
|
@@ -3199,10 +3263,10 @@ function canAutoMigrate(classInfo) {
|
|
|
3199
3263
|
reason: "No class found in file"
|
|
3200
3264
|
};
|
|
3201
3265
|
}
|
|
3202
|
-
if (!classInfo.isInjectable && !classInfo.isController) {
|
|
3266
|
+
if (!classInfo.isInjectable && !classInfo.isController && !classInfo.isAutomation) {
|
|
3203
3267
|
return {
|
|
3204
3268
|
canMigrate: false,
|
|
3205
|
-
reason: `Class "${classInfo.name}" is not @Injectable or @
|
|
3269
|
+
reason: `Class "${classInfo.name}" is not @Injectable, @Controller or @Automation`
|
|
3206
3270
|
};
|
|
3207
3271
|
}
|
|
3208
3272
|
return { canMigrate: true };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lark-apaas/fullstack-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.16-alpha.1",
|
|
4
4
|
"description": "CLI tool for fullstack template management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -52,6 +52,5 @@
|
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"typescript": "^5.9.2"
|
|
54
54
|
},
|
|
55
|
-
"migrationVersion": 1
|
|
56
|
-
"gitHead": "01b6e36136d5e8aee0960b9b90091c8c3f66537a"
|
|
55
|
+
"migrationVersion": 1
|
|
57
56
|
}
|