@singbox-iac/cli 0.1.5 → 0.1.7

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.
Files changed (79) hide show
  1. package/README-en.md +22 -2
  2. package/README.md +22 -2
  3. package/dist/cli/command-helpers.js +1 -1
  4. package/dist/cli/command-helpers.js.map +1 -1
  5. package/dist/cli/commands/apply.js +21 -9
  6. package/dist/cli/commands/apply.js.map +1 -1
  7. package/dist/cli/commands/author.d.ts +28 -0
  8. package/dist/cli/commands/author.js +119 -121
  9. package/dist/cli/commands/author.js.map +1 -1
  10. package/dist/cli/commands/build.js +7 -34
  11. package/dist/cli/commands/build.js.map +1 -1
  12. package/dist/cli/commands/go.d.ts +2 -0
  13. package/dist/cli/commands/go.js +38 -0
  14. package/dist/cli/commands/go.js.map +1 -0
  15. package/dist/cli/commands/history.d.ts +2 -0
  16. package/dist/cli/commands/history.js +21 -0
  17. package/dist/cli/commands/history.js.map +1 -0
  18. package/dist/cli/commands/rollback.d.ts +2 -0
  19. package/dist/cli/commands/rollback.js +38 -0
  20. package/dist/cli/commands/rollback.js.map +1 -0
  21. package/dist/cli/commands/update.js +16 -2
  22. package/dist/cli/commands/update.js.map +1 -1
  23. package/dist/cli/commands/use.d.ts +2 -0
  24. package/dist/cli/commands/use.js +45 -0
  25. package/dist/cli/commands/use.js.map +1 -0
  26. package/dist/cli/commands/verify.js +72 -20
  27. package/dist/cli/commands/verify.js.map +1 -1
  28. package/dist/cli/index.js +45 -2
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/domain/dns-plan.d.ts +27 -0
  31. package/dist/domain/dns-plan.js +2 -0
  32. package/dist/domain/dns-plan.js.map +1 -0
  33. package/dist/domain/intent.d.ts +61 -0
  34. package/dist/domain/intent.js +2 -0
  35. package/dist/domain/intent.js.map +1 -0
  36. package/dist/domain/transaction.d.ts +12 -0
  37. package/dist/domain/transaction.js +2 -0
  38. package/dist/domain/transaction.js.map +1 -0
  39. package/dist/domain/verification-plan.d.ts +34 -0
  40. package/dist/domain/verification-plan.js +2 -0
  41. package/dist/domain/verification-plan.js.map +1 -0
  42. package/dist/modules/authoring/index.d.ts +2 -0
  43. package/dist/modules/authoring/index.js +32 -17
  44. package/dist/modules/authoring/index.js.map +1 -1
  45. package/dist/modules/build/index.d.ts +3 -0
  46. package/dist/modules/build/index.js +8 -1
  47. package/dist/modules/build/index.js.map +1 -1
  48. package/dist/modules/compiler/index.d.ts +2 -2
  49. package/dist/modules/compiler/index.js +45 -60
  50. package/dist/modules/compiler/index.js.map +1 -1
  51. package/dist/modules/dns-plan/index.d.ts +10 -0
  52. package/dist/modules/dns-plan/index.js +104 -0
  53. package/dist/modules/dns-plan/index.js.map +1 -0
  54. package/dist/modules/fetcher/index.d.ts +1 -0
  55. package/dist/modules/fetcher/index.js +66 -19
  56. package/dist/modules/fetcher/index.js.map +1 -1
  57. package/dist/modules/intent/index.d.ts +7 -0
  58. package/dist/modules/intent/index.js +101 -0
  59. package/dist/modules/intent/index.js.map +1 -0
  60. package/dist/modules/manager/index.d.ts +1 -0
  61. package/dist/modules/manager/index.js +15 -0
  62. package/dist/modules/manager/index.js.map +1 -1
  63. package/dist/modules/natural-language/index.js +2 -1
  64. package/dist/modules/natural-language/index.js.map +1 -1
  65. package/dist/modules/transactions/index.d.ts +20 -0
  66. package/dist/modules/transactions/index.js +150 -0
  67. package/dist/modules/transactions/index.js.map +1 -0
  68. package/dist/modules/update/index.d.ts +2 -0
  69. package/dist/modules/update/index.js +25 -6
  70. package/dist/modules/update/index.js.map +1 -1
  71. package/dist/modules/verification/index.d.ts +57 -0
  72. package/dist/modules/verification/index.js +326 -23
  73. package/dist/modules/verification/index.js.map +1 -1
  74. package/dist/modules/verification-plan/index.d.ts +9 -0
  75. package/dist/modules/verification-plan/index.js +117 -0
  76. package/dist/modules/verification-plan/index.js.map +1 -0
  77. package/docs/runtime-on-macos.md +21 -5
  78. package/examples/builder.config.yaml +7 -26
  79. package/package.json +1 -1
@@ -0,0 +1,150 @@
1
+ import { constants } from "node:fs";
2
+ import { access, copyFile, mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ export async function applyWithTransaction(input) {
5
+ const txId = createTxId();
6
+ const historyPath = resolveTransactionHistoryPath(input.config);
7
+ const snapshotsDir = resolveSnapshotsDir(input.config);
8
+ await mkdir(path.dirname(historyPath), { recursive: true });
9
+ await mkdir(snapshotsDir, { recursive: true });
10
+ const liveExists = await pathExists(input.livePath);
11
+ const snapshotPath = liveExists ? path.join(snapshotsDir, `${txId}.json`) : undefined;
12
+ if (snapshotPath) {
13
+ await copyFile(input.livePath, snapshotPath);
14
+ }
15
+ if (input.backupPath && liveExists) {
16
+ await mkdir(path.dirname(input.backupPath), { recursive: true });
17
+ await copyFile(input.livePath, input.backupPath);
18
+ }
19
+ const pending = {
20
+ txId,
21
+ generatedPath: input.generatedPath,
22
+ livePath: input.livePath,
23
+ backupPath: input.backupPath,
24
+ ...(snapshotPath ? { snapshotPath } : {}),
25
+ startedAt: new Date().toISOString(),
26
+ status: "pending",
27
+ verificationSummary: input.verificationSummary,
28
+ };
29
+ await appendTransaction(historyPath, pending);
30
+ try {
31
+ await input.apply();
32
+ const applied = {
33
+ ...pending,
34
+ completedAt: new Date().toISOString(),
35
+ status: "applied",
36
+ };
37
+ await replaceLatestTransaction(historyPath, applied);
38
+ await trimSnapshots(historyPath, snapshotsDir, input.retainSnapshots ?? 5);
39
+ return applied;
40
+ }
41
+ catch (error) {
42
+ if (snapshotPath && (await pathExists(snapshotPath))) {
43
+ await copyFile(snapshotPath, input.livePath);
44
+ const rolledBack = {
45
+ ...pending,
46
+ completedAt: new Date().toISOString(),
47
+ status: "rolled-back",
48
+ error: error instanceof Error ? error.message : String(error),
49
+ };
50
+ await replaceLatestTransaction(historyPath, rolledBack);
51
+ }
52
+ else {
53
+ const failed = {
54
+ ...pending,
55
+ completedAt: new Date().toISOString(),
56
+ status: "failed",
57
+ error: error instanceof Error ? error.message : String(error),
58
+ };
59
+ await replaceLatestTransaction(historyPath, failed);
60
+ }
61
+ throw error;
62
+ }
63
+ }
64
+ export async function listTransactionHistory(config) {
65
+ return (await loadTransactionLog(resolveTransactionHistoryPath(config))).entries;
66
+ }
67
+ export async function rollbackToPrevious(input) {
68
+ const config = input.config;
69
+ const livePath = input.livePath ?? config.output.livePath;
70
+ const historyPath = resolveTransactionHistoryPath(config);
71
+ const log = await loadTransactionLog(historyPath);
72
+ const previous = log.entries.find((entry) => entry.status === "applied" && entry.snapshotPath);
73
+ if (!previous?.snapshotPath) {
74
+ throw new Error("No previous snapshot is available for rollback.");
75
+ }
76
+ if (!(await pathExists(previous.snapshotPath))) {
77
+ throw new Error(`The previous snapshot is missing: ${previous.snapshotPath}`);
78
+ }
79
+ await mkdir(path.dirname(livePath), { recursive: true });
80
+ await copyFile(previous.snapshotPath, livePath);
81
+ if (input.afterRestore) {
82
+ await input.afterRestore();
83
+ }
84
+ const tx = {
85
+ txId: createTxId(),
86
+ generatedPath: previous.snapshotPath,
87
+ livePath,
88
+ backupPath: config.output.backupPath,
89
+ snapshotPath: previous.snapshotPath,
90
+ startedAt: new Date().toISOString(),
91
+ completedAt: new Date().toISOString(),
92
+ status: "rolled-back",
93
+ verificationSummary: {
94
+ rollbackTo: previous.txId,
95
+ },
96
+ };
97
+ await appendTransaction(historyPath, tx);
98
+ return tx;
99
+ }
100
+ export function resolveTransactionHistoryPath(config) {
101
+ return path.join(path.dirname(config.output.stagingPath), "transactions.json");
102
+ }
103
+ function resolveSnapshotsDir(config) {
104
+ return path.join(path.dirname(config.output.stagingPath), "snapshots");
105
+ }
106
+ async function loadTransactionLog(historyPath) {
107
+ if (!(await pathExists(historyPath))) {
108
+ return { version: 1, entries: [] };
109
+ }
110
+ return JSON.parse(await readFile(historyPath, "utf8"));
111
+ }
112
+ async function appendTransaction(historyPath, entry) {
113
+ const log = await loadTransactionLog(historyPath);
114
+ await writeFile(historyPath, `${JSON.stringify({ version: 1, entries: [entry, ...log.entries] }, null, 2)}\n`, "utf8");
115
+ }
116
+ async function replaceLatestTransaction(historyPath, entry) {
117
+ const log = await loadTransactionLog(historyPath);
118
+ const [, ...rest] = log.entries;
119
+ await writeFile(historyPath, `${JSON.stringify({ version: 1, entries: [entry, ...rest] }, null, 2)}\n`, "utf8");
120
+ }
121
+ async function trimSnapshots(historyPath, snapshotsDir, retainSnapshots) {
122
+ const log = await loadTransactionLog(historyPath);
123
+ const keep = new Set(log.entries
124
+ .filter((entry) => entry.snapshotPath)
125
+ .slice(0, retainSnapshots)
126
+ .map((entry) => entry.snapshotPath));
127
+ if (!(await pathExists(snapshotsDir))) {
128
+ return;
129
+ }
130
+ const files = await readdir(snapshotsDir);
131
+ await Promise.all(files.map(async (fileName) => {
132
+ const filePath = path.join(snapshotsDir, fileName);
133
+ if (!keep.has(filePath)) {
134
+ await rm(filePath, { force: true });
135
+ }
136
+ }));
137
+ }
138
+ async function pathExists(filePath) {
139
+ try {
140
+ await access(filePath, constants.F_OK);
141
+ return true;
142
+ }
143
+ catch {
144
+ return false;
145
+ }
146
+ }
147
+ function createTxId() {
148
+ return `tx-${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
149
+ }
150
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/transactions/index.ts"],"names":[],"mappings":"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"}
@@ -18,5 +18,7 @@ export interface UpdateResult {
18
18
  readonly verification?: VerificationReport;
19
19
  readonly livePath: string;
20
20
  readonly backupPath?: string;
21
+ readonly reloaded: boolean;
22
+ readonly transactionId: string;
21
23
  }
22
24
  export declare function runUpdate(input: RunUpdateInput): Promise<UpdateResult>;
@@ -1,5 +1,7 @@
1
1
  import { buildConfigArtifact } from "../build/index.js";
2
2
  import { applyConfig } from "../manager/index.js";
3
+ import { shouldAutoReloadRuntime } from "../manager/index.js";
4
+ import { applyWithTransaction } from "../transactions/index.js";
3
5
  import { assertVerificationReportPassed, verifyConfigRoutes, } from "../verification/index.js";
4
6
  export async function runUpdate(input) {
5
7
  const build = await buildConfigArtifact({
@@ -20,19 +22,36 @@ export async function runUpdate(input) {
20
22
  }
21
23
  const livePath = input.livePath ?? input.config.output.livePath;
22
24
  const backupPath = input.backupPath ?? input.config.output.backupPath;
23
- await applyConfig({
24
- stagingPath: build.outputPath,
25
+ const reloaded = input.reload ?? (await shouldAutoReloadRuntime(input.config.runtime.reload));
26
+ const transaction = await applyWithTransaction({
27
+ config: input.config,
28
+ generatedPath: build.outputPath,
25
29
  livePath,
26
- ...(backupPath ? { backupPath } : {}),
27
- ...(input.singBoxBinary ? { singBoxBinary: input.singBoxBinary } : {}),
28
- reload: input.reload ?? false,
29
- runtime: input.config.runtime.reload,
30
+ backupPath,
31
+ verificationSummary: verification
32
+ ? {
33
+ routeScenariosPassed: verification.scenarios.filter((scenario) => scenario.passed).length,
34
+ routeScenariosTotal: verification.scenarios.length,
35
+ }
36
+ : { routeScenariosSkipped: true },
37
+ apply: async () => {
38
+ await applyConfig({
39
+ stagingPath: build.outputPath,
40
+ livePath,
41
+ ...(backupPath ? { backupPath } : {}),
42
+ ...(input.singBoxBinary ? { singBoxBinary: input.singBoxBinary } : {}),
43
+ reload: reloaded,
44
+ runtime: input.config.runtime.reload,
45
+ });
46
+ },
30
47
  });
31
48
  return {
32
49
  build,
33
50
  ...(verification ? { verification } : {}),
34
51
  livePath,
35
52
  ...(backupPath ? { backupPath } : {}),
53
+ reloaded,
54
+ transactionId: transaction.txId,
36
55
  };
37
56
  }
38
57
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/update/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAEL,8BAA8B,EAC9B,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAsBlC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAqB;IACnD,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC;QACtC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7E,CAAC,CAAC;IAEH,IAAI,YAA4C,CAAC;IACjD,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC3B,YAAY,GAAG,MAAM,kBAAkB,CAAC;YACtC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,mBAAmB,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS;SACzD,CAAC,CAAC;QACH,8BAA8B,CAAC,YAAY,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAChE,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;IAEtE,MAAM,WAAW,CAAC;QAChB,WAAW,EAAE,KAAK,CAAC,UAAU;QAC7B,QAAQ;QACR,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK;QAC7B,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM;KACrC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK;QACL,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,QAAQ;QACR,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/update/index.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  import type { BuilderConfig } from "../../config/schema.js";
2
+ import type { DNSPlan } from "../../domain/dns-plan.js";
3
+ import type { VerificationPlan } from "../../domain/verification-plan.js";
2
4
  type JsonObject = Record<string, unknown>;
3
5
  export interface VerifyConfigRoutesInput {
4
6
  readonly configPath: string;
@@ -40,12 +42,51 @@ export interface VisibleChromeLaunch {
40
42
  readonly urls: readonly string[];
41
43
  readonly userDataDir: string;
42
44
  }
45
+ export interface DnsVerificationResult {
46
+ readonly domain: string;
47
+ readonly passed: boolean;
48
+ readonly expectedMode: "fake-ip" | "real-ip";
49
+ readonly actualMode: "fake-ip" | "real-ip";
50
+ readonly resolver: string;
51
+ }
52
+ export interface AppVerificationResult {
53
+ readonly app: string;
54
+ readonly passed: boolean;
55
+ readonly expectedInbound: "in-proxifier" | "in-default";
56
+ readonly expectedOutboundGroup: string;
57
+ readonly details: string;
58
+ }
59
+ export interface ProtocolVerificationResult {
60
+ readonly target: string;
61
+ readonly passed: boolean;
62
+ readonly expectTCPOnly: boolean;
63
+ readonly details: string;
64
+ }
65
+ export interface EgressVerificationResult {
66
+ readonly id: string;
67
+ readonly target: string;
68
+ readonly inbound: "in-mixed" | "in-proxifier";
69
+ readonly expectedOutboundGroup: string;
70
+ readonly passed: boolean;
71
+ readonly ip?: string;
72
+ readonly country?: string;
73
+ readonly asn?: string;
74
+ readonly details: string;
75
+ }
43
76
  export declare function assertVerificationReportPassed(report: VerificationReport): void;
44
77
  interface PreparedVerificationConfig {
45
78
  readonly config: JsonObject;
46
79
  readonly mixedPort: number;
47
80
  readonly proxifierPort: number;
48
81
  }
82
+ interface RuntimeScenario {
83
+ readonly id: string;
84
+ readonly name: string;
85
+ readonly url: string;
86
+ readonly inboundTag: "in-mixed" | "in-proxifier";
87
+ readonly proxyPort: number;
88
+ readonly expectedOutboundTag: string;
89
+ }
49
90
  export interface ConfiguredVerificationScenario {
50
91
  readonly id: BuilderConfig["verification"]["scenarios"][number]["id"];
51
92
  readonly name: BuilderConfig["verification"]["scenarios"][number]["name"];
@@ -53,7 +94,23 @@ export interface ConfiguredVerificationScenario {
53
94
  readonly inbound: BuilderConfig["verification"]["scenarios"][number]["inbound"];
54
95
  readonly expectedOutbound: BuilderConfig["verification"]["scenarios"][number]["expectedOutbound"];
55
96
  }
97
+ interface RequestRunResult {
98
+ readonly exitCode: number;
99
+ readonly stdout: string;
100
+ readonly stderr: string;
101
+ readonly timedOut: boolean;
102
+ }
56
103
  export declare function verifyConfigRoutes(input: VerifyConfigRoutesInput): Promise<VerificationReport>;
104
+ export declare function verifyDnsPlan(plan: VerificationPlan, dnsPlan: DNSPlan): readonly DnsVerificationResult[];
105
+ export declare function verifyAppPlan(plan: VerificationPlan, config: JsonObject): readonly AppVerificationResult[];
106
+ export declare function verifyProtocolPlan(plan: VerificationPlan, config: JsonObject): readonly ProtocolVerificationResult[];
107
+ export declare function verifyEgressPlan(input: {
108
+ readonly configPath: string;
109
+ readonly checks: VerificationPlan["egressChecks"];
110
+ readonly singBoxBinary?: string;
111
+ readonly requestBinary?: string;
112
+ }): Promise<readonly EgressVerificationResult[]>;
113
+ export declare function isRouteLevelProxySuccess(scenario: Pick<RuntimeScenario, "inboundTag">, requestResult: RequestRunResult): boolean;
57
114
  export declare function resolveChromeBinary(explicitPath?: string): Promise<string>;
58
115
  export declare function openVisibleChromeWindows(input: {
59
116
  readonly scenarios: readonly VisibleVerificationScenario[];