@fire-spark/cli 0.13.2 → 0.13.3
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/package.json +3 -1
- package/src/commands/doctor/client/admin.flow.ts +553 -0
- package/src/commands/doctor/client/checkout.flow.ts +400 -0
- package/src/commands/doctor/client/content.flow.ts +450 -0
- package/src/commands/doctor/client/copy.ts +22 -2
- package/src/commands/doctor/client/flow.ts +182 -0
- package/src/commands/doctor/client/log.flow.ts +410 -0
- package/src/commands/doctor/client/men.flow.ts +412 -0
- package/src/commands/doctor/client/ops.flow.ts +312 -0
- package/src/commands/doctor/client/ord.flow.ts +445 -0
- package/src/commands/doctor/client/order.ts +1 -1
- package/src/commands/doctor/client/pay.flow.ts +772 -0
- package/src/commands/doctor/client/repo.scan.ts +142 -0
- package/src/commands/doctor/client/runner.ts +21 -1
- package/src/commands/doctor/client/sdk.flow.ts +630 -0
- package/src/commands/doctor/client/store.flow.ts +577 -0
- package/src/commands/doctor/live/http.ts +10 -18
- package/src/commands/doctor/live/live.session.ts +13 -6
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
|
|
4
|
+
const SKIP = new Set(["node_modules", ".git", "coverage"]);
|
|
5
|
+
const MAX_FILES = 2000;
|
|
6
|
+
const MAX_BYTES = 512000;
|
|
7
|
+
|
|
8
|
+
export interface SourceFile {
|
|
9
|
+
rel: string;
|
|
10
|
+
body: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const textName = (name: string) => {
|
|
14
|
+
return /\.(json|ts|tsx|js|jsx|mjs|cjs|md|html|css|txt)$/.test(name);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const readSources = async (root: string) => {
|
|
18
|
+
const found: SourceFile[] = [];
|
|
19
|
+
const visit = async (dir: string) => {
|
|
20
|
+
if (found.length >= MAX_FILES) return;
|
|
21
|
+
let names: { name: string; isDirectory: () => boolean }[] = [];
|
|
22
|
+
try {
|
|
23
|
+
names = await readdir(dir, { withFileTypes: true });
|
|
24
|
+
} catch {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
for (const entry of names) {
|
|
28
|
+
if (found.length >= MAX_FILES) return;
|
|
29
|
+
if (SKIP.has(entry.name)) continue;
|
|
30
|
+
const path = join(dir, entry.name);
|
|
31
|
+
if (entry.isDirectory()) {
|
|
32
|
+
await visit(path);
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (!textName(entry.name)) continue;
|
|
36
|
+
let body = "";
|
|
37
|
+
try {
|
|
38
|
+
body = await readFile(path, "utf8");
|
|
39
|
+
} catch {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (body.length > MAX_BYTES) continue;
|
|
43
|
+
found.push({ rel: relative(root, path), body });
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
await visit(root);
|
|
47
|
+
return found;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const HEADING = /^##\s+v?(\d+\.\d+\.\d+)\s*(?:[-–:]\s*(.*))?$/;
|
|
51
|
+
|
|
52
|
+
export interface ChangeNote {
|
|
53
|
+
version: string;
|
|
54
|
+
title: string;
|
|
55
|
+
description: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const changelogNotes = (body: string) => {
|
|
59
|
+
const notes: ChangeNote[] = [];
|
|
60
|
+
let current: ChangeNote | null = null;
|
|
61
|
+
for (const line of body.split(/\r?\n/)) {
|
|
62
|
+
const match = HEADING.exec(line.trim());
|
|
63
|
+
if (match) {
|
|
64
|
+
if (current) notes.push(current);
|
|
65
|
+
const version = match[1] ?? "";
|
|
66
|
+
const title = match[2]?.trim() ?? "";
|
|
67
|
+
current = { version, title, description: "" };
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (!current || current.description || !line.trim()) continue;
|
|
71
|
+
current.description = line.trim();
|
|
72
|
+
}
|
|
73
|
+
if (current) notes.push(current);
|
|
74
|
+
return notes;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const semverCmp = (left: string, right: string) => {
|
|
78
|
+
const a = left.split(".").map(part => Number(part));
|
|
79
|
+
const b = right.split(".").map(part => Number(part));
|
|
80
|
+
for (let i = 0; i < 3; i += 1) {
|
|
81
|
+
const av = a[i] ?? 0;
|
|
82
|
+
const bv = b[i] ?? 0;
|
|
83
|
+
if (Number.isNaN(av) || Number.isNaN(bv)) return 0;
|
|
84
|
+
if (av === bv) continue;
|
|
85
|
+
if (av > bv) return 1;
|
|
86
|
+
return -1;
|
|
87
|
+
}
|
|
88
|
+
return 0;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const SCOPES = ["dependencies", "devDependencies", "peerDependencies"];
|
|
92
|
+
|
|
93
|
+
const isRecord = (value: unknown): value is Record<string, unknown> => {
|
|
94
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const workspaceIssues = (files: SourceFile[]) => {
|
|
98
|
+
const issues: string[] = [];
|
|
99
|
+
for (const file of files) {
|
|
100
|
+
if (!file.rel.endsWith("package.json")) continue;
|
|
101
|
+
let json: unknown;
|
|
102
|
+
try {
|
|
103
|
+
json = JSON.parse(file.body);
|
|
104
|
+
} catch {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (!isRecord(json)) continue;
|
|
108
|
+
for (const scope of SCOPES) {
|
|
109
|
+
const bag = json[scope];
|
|
110
|
+
if (!isRecord(bag)) continue;
|
|
111
|
+
for (const [name, version] of Object.entries(bag)) {
|
|
112
|
+
if (!name.startsWith("@fire-spark/")) continue;
|
|
113
|
+
if (name === "@fire-spark/rn-ui") continue;
|
|
114
|
+
if (typeof version !== "string") continue;
|
|
115
|
+
if (!version.startsWith("workspace:")) continue;
|
|
116
|
+
issues.push(`${file.rel}: ${name}@${version}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return issues;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export const declaresDep = (
|
|
124
|
+
files: SourceFile[],
|
|
125
|
+
relPrefix: string,
|
|
126
|
+
name: string
|
|
127
|
+
) => {
|
|
128
|
+
const docs = files.filter(file => file.rel.endsWith("package.json"));
|
|
129
|
+
for (const file of docs) {
|
|
130
|
+
const inApp = file.rel.startsWith(relPrefix);
|
|
131
|
+
const atRoot = file.rel === "package.json";
|
|
132
|
+
if (!inApp && !atRoot) continue;
|
|
133
|
+
if (file.body.includes(`"${name}"`)) return true;
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const importsLib = (body: string, lib: string) => {
|
|
139
|
+
if (body.includes(`"${lib}"`) || body.includes(`'${lib}'`)) return true;
|
|
140
|
+
if (body.includes(`"${lib}/`) || body.includes(`'${lib}/`)) return true;
|
|
141
|
+
return false;
|
|
142
|
+
};
|
|
@@ -2,12 +2,22 @@ import type { Locale } from "../../../core/i18n";
|
|
|
2
2
|
import { translate } from "../../../core/i18n";
|
|
3
3
|
import type { Output } from "../../../core/output";
|
|
4
4
|
import type { Redactor } from "../../../core/redact";
|
|
5
|
+
import { ADMIN_BINDINGS } from "./admin.flow";
|
|
5
6
|
import type { CatalogCheck } from "./catalog";
|
|
7
|
+
import { CHECKOUT_BINDINGS } from "./checkout.flow";
|
|
8
|
+
import { CONTENT_BINDINGS } from "./content.flow";
|
|
6
9
|
import { COPY } from "./copy";
|
|
10
|
+
import { LOG_BINDINGS } from "./log.flow";
|
|
7
11
|
import { listManifests, manifestProblem } from "./manifests";
|
|
8
12
|
import { parseLegacyManifest } from "./manifests";
|
|
9
13
|
import type { ManifestFile } from "./manifests";
|
|
14
|
+
import { MEN_BINDINGS } from "./men.flow";
|
|
15
|
+
import { OPS_BINDINGS } from "./ops.flow";
|
|
16
|
+
import { ORD_BINDINGS } from "./ord.flow";
|
|
10
17
|
import { ORDER_CHECK_ID, fixOrder, runOrder } from "./order";
|
|
18
|
+
import { PAY_BINDINGS } from "./pay.flow";
|
|
19
|
+
import { SDK_BINDINGS } from "./sdk.flow";
|
|
20
|
+
import { STORE_BINDINGS } from "./store.flow";
|
|
11
21
|
import type { YamlChannel } from "./yaml";
|
|
12
22
|
|
|
13
23
|
export interface Outcome {
|
|
@@ -93,7 +103,17 @@ export interface CheckBinding {
|
|
|
93
103
|
}
|
|
94
104
|
|
|
95
105
|
export const BINDINGS: Record<string, CheckBinding> = {
|
|
96
|
-
"SDK-11": { kind: "script", run: runSdk11, fix: fixSdk11 }
|
|
106
|
+
"SDK-11": { kind: "script", run: runSdk11, fix: fixSdk11 },
|
|
107
|
+
...SDK_BINDINGS,
|
|
108
|
+
...PAY_BINDINGS,
|
|
109
|
+
...ORD_BINDINGS,
|
|
110
|
+
...MEN_BINDINGS,
|
|
111
|
+
...CHECKOUT_BINDINGS,
|
|
112
|
+
...LOG_BINDINGS,
|
|
113
|
+
...CONTENT_BINDINGS,
|
|
114
|
+
...STORE_BINDINGS,
|
|
115
|
+
...OPS_BINDINGS,
|
|
116
|
+
...ADMIN_BINDINGS
|
|
97
117
|
};
|
|
98
118
|
|
|
99
119
|
export const runOne = async (
|