@fougere/cli 0.12.4-alpha.0 → 0.12.6-alpha.0
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/.fougere/scan.generated.d.ts +3 -0
- package/dist/.fougere/scan.generated.d.ts.map +1 -0
- package/dist/.fougere/scan.generated.js +140 -0
- package/dist/.fougere/scan.generated.js.map +1 -0
- package/dist/app/commands/BuildCommand.d.ts +18 -0
- package/dist/app/commands/BuildCommand.d.ts.map +1 -0
- package/dist/app/commands/BuildCommand.js +35 -0
- package/dist/app/commands/BuildCommand.js.map +1 -0
- package/dist/app/commands/CallCommand.d.ts +16 -0
- package/dist/app/commands/CallCommand.d.ts.map +1 -0
- package/dist/app/commands/CallCommand.js +73 -0
- package/dist/app/commands/CallCommand.js.map +1 -0
- package/dist/app/commands/CheckCommand.d.ts +11 -0
- package/dist/app/commands/CheckCommand.d.ts.map +1 -0
- package/dist/app/commands/CheckCommand.js +59 -0
- package/dist/app/commands/CheckCommand.js.map +1 -0
- package/dist/app/commands/CompletionCommand.d.ts +7 -0
- package/dist/app/commands/CompletionCommand.d.ts.map +1 -0
- package/dist/app/commands/CompletionCommand.js +23 -0
- package/dist/app/commands/CompletionCommand.js.map +1 -0
- package/dist/app/commands/DevtoolsCommand.d.ts +20 -0
- package/dist/app/commands/DevtoolsCommand.d.ts.map +1 -0
- package/dist/app/commands/DevtoolsCommand.js +79 -0
- package/dist/app/commands/DevtoolsCommand.js.map +1 -0
- package/dist/app/commands/ExplainCommand.d.ts +18 -0
- package/dist/app/commands/ExplainCommand.d.ts.map +1 -0
- package/dist/app/commands/ExplainCommand.js +111 -0
- package/dist/app/commands/ExplainCommand.js.map +1 -0
- package/dist/app/commands/FreezeCommand.d.ts +21 -0
- package/dist/app/commands/FreezeCommand.d.ts.map +1 -0
- package/dist/app/commands/FreezeCommand.js +102 -0
- package/dist/app/commands/FreezeCommand.js.map +1 -0
- package/dist/app/commands/GrantCommand.d.ts +18 -0
- package/dist/app/commands/GrantCommand.d.ts.map +1 -0
- package/dist/app/commands/GrantCommand.js +39 -0
- package/dist/app/commands/GrantCommand.js.map +1 -0
- package/dist/app/commands/GraphCommand.d.ts +11 -0
- package/dist/app/commands/GraphCommand.d.ts.map +1 -0
- package/dist/app/commands/GraphCommand.js +72 -0
- package/dist/app/commands/GraphCommand.js.map +1 -0
- package/dist/app/commands/KeysCommand.d.ts +22 -0
- package/dist/app/commands/KeysCommand.d.ts.map +1 -0
- package/dist/app/commands/KeysCommand.js +50 -0
- package/dist/app/commands/KeysCommand.js.map +1 -0
- package/dist/app/commands/LoadCommand.d.ts +19 -0
- package/dist/app/commands/LoadCommand.d.ts.map +1 -0
- package/dist/app/commands/LoadCommand.js +37 -0
- package/dist/app/commands/LoadCommand.js.map +1 -0
- package/dist/app/commands/MigrateCommand.d.ts +17 -0
- package/dist/app/commands/MigrateCommand.d.ts.map +1 -0
- package/dist/app/commands/MigrateCommand.js +47 -0
- package/dist/app/commands/MigrateCommand.js.map +1 -0
- package/dist/app/commands/NewCommand.d.ts +24 -0
- package/dist/app/commands/NewCommand.d.ts.map +1 -0
- package/dist/app/commands/NewCommand.js +131 -0
- package/dist/app/commands/NewCommand.js.map +1 -0
- package/dist/app/commands/ServeCommand.d.ts +17 -0
- package/dist/app/commands/ServeCommand.d.ts.map +1 -0
- package/dist/app/commands/ServeCommand.js +93 -0
- package/dist/app/commands/ServeCommand.js.map +1 -0
- package/dist/app/commands/grant-material.d.ts +5 -0
- package/dist/app/commands/grant-material.d.ts.map +1 -0
- package/{app/commands/grant-material.ts → dist/app/commands/grant-material.js} +2 -2
- package/dist/app/commands/grant-material.js.map +1 -0
- package/dist/fronds/analysis/entities/Build.d.ts +10 -0
- package/dist/fronds/analysis/entities/Build.d.ts.map +1 -0
- package/dist/fronds/analysis/entities/Build.js +9 -0
- package/dist/fronds/analysis/entities/Build.js.map +1 -0
- package/dist/fronds/analysis/entities/Check.d.ts +8 -0
- package/dist/fronds/analysis/entities/Check.d.ts.map +1 -0
- package/dist/fronds/analysis/entities/Check.js +7 -0
- package/dist/fronds/analysis/entities/Check.js.map +1 -0
- package/dist/fronds/analysis/entities/Devtools.d.ts +10 -0
- package/dist/fronds/analysis/entities/Devtools.d.ts.map +1 -0
- package/dist/fronds/analysis/entities/Devtools.js +9 -0
- package/dist/fronds/analysis/entities/Devtools.js.map +1 -0
- package/dist/fronds/analysis/entities/Explain.d.ts +11 -0
- package/dist/fronds/analysis/entities/Explain.d.ts.map +1 -0
- package/dist/fronds/analysis/entities/Explain.js +10 -0
- package/dist/fronds/analysis/entities/Explain.js.map +1 -0
- package/dist/fronds/analysis/entities/Freeze.d.ts +10 -0
- package/dist/fronds/analysis/entities/Freeze.d.ts.map +1 -0
- package/dist/fronds/analysis/entities/Freeze.js +9 -0
- package/dist/fronds/analysis/entities/Freeze.js.map +1 -0
- package/dist/fronds/analysis/entities/Graph.d.ts +9 -0
- package/dist/fronds/analysis/entities/Graph.d.ts.map +1 -0
- package/dist/fronds/analysis/entities/Graph.js +8 -0
- package/dist/fronds/analysis/entities/Graph.js.map +1 -0
- package/dist/fronds/analysis/entities/Load.d.ts +10 -0
- package/dist/fronds/analysis/entities/Load.d.ts.map +1 -0
- package/dist/fronds/analysis/entities/Load.js +9 -0
- package/dist/fronds/analysis/entities/Load.js.map +1 -0
- package/dist/fronds/analysis/entities/Migrate.d.ts +10 -0
- package/dist/fronds/analysis/entities/Migrate.d.ts.map +1 -0
- package/dist/fronds/analysis/entities/Migrate.js +9 -0
- package/dist/fronds/analysis/entities/Migrate.js.map +1 -0
- package/dist/fronds/analysis/handlers/BuildHandler.d.ts +50 -0
- package/dist/fronds/analysis/handlers/BuildHandler.d.ts.map +1 -0
- package/dist/fronds/analysis/handlers/BuildHandler.js +63 -0
- package/dist/fronds/analysis/handlers/BuildHandler.js.map +1 -0
- package/dist/fronds/analysis/handlers/CheckHandler.d.ts +30 -0
- package/dist/fronds/analysis/handlers/CheckHandler.d.ts.map +1 -0
- package/dist/fronds/analysis/handlers/CheckHandler.js +196 -0
- package/dist/fronds/analysis/handlers/CheckHandler.js.map +1 -0
- package/dist/fronds/analysis/handlers/DevtoolsHandler.d.ts +45 -0
- package/dist/fronds/analysis/handlers/DevtoolsHandler.d.ts.map +1 -0
- package/dist/fronds/analysis/handlers/DevtoolsHandler.js +61 -0
- package/dist/fronds/analysis/handlers/DevtoolsHandler.js.map +1 -0
- package/dist/fronds/analysis/handlers/ExplainHandler.d.ts +99 -0
- package/dist/fronds/analysis/handlers/ExplainHandler.d.ts.map +1 -0
- package/dist/fronds/analysis/handlers/ExplainHandler.js +157 -0
- package/dist/fronds/analysis/handlers/ExplainHandler.js.map +1 -0
- package/dist/fronds/analysis/handlers/FreezeHandler.d.ts +55 -0
- package/dist/fronds/analysis/handlers/FreezeHandler.d.ts.map +1 -0
- package/dist/fronds/analysis/handlers/FreezeHandler.js +145 -0
- package/dist/fronds/analysis/handlers/FreezeHandler.js.map +1 -0
- package/dist/fronds/analysis/handlers/GraphHandler.d.ts +23 -0
- package/dist/fronds/analysis/handlers/GraphHandler.d.ts.map +1 -0
- package/dist/fronds/analysis/handlers/GraphHandler.js +23 -0
- package/dist/fronds/analysis/handlers/GraphHandler.js.map +1 -0
- package/dist/fronds/analysis/handlers/LoadHandler.d.ts +26 -0
- package/dist/fronds/analysis/handlers/LoadHandler.d.ts.map +1 -0
- package/dist/fronds/analysis/handlers/LoadHandler.js +35 -0
- package/dist/fronds/analysis/handlers/LoadHandler.js.map +1 -0
- package/dist/fronds/analysis/handlers/MigrateHandler.d.ts +34 -0
- package/dist/fronds/analysis/handlers/MigrateHandler.d.ts.map +1 -0
- package/dist/fronds/analysis/handlers/MigrateHandler.js +92 -0
- package/dist/fronds/analysis/handlers/MigrateHandler.js.map +1 -0
- package/dist/fronds/analysis/services/ProjectScan.d.ts +22 -0
- package/dist/fronds/analysis/services/ProjectScan.d.ts.map +1 -0
- package/dist/fronds/analysis/services/ProjectScan.js +48 -0
- package/dist/fronds/analysis/services/ProjectScan.js.map +1 -0
- package/dist/fronds/analysis/versions.d.ts +21 -0
- package/dist/fronds/analysis/versions.d.ts.map +1 -0
- package/dist/fronds/analysis/versions.js +48 -0
- package/dist/fronds/analysis/versions.js.map +1 -0
- package/dist/fronds/scaffold/entities/BuildFrond.d.ts +7 -0
- package/dist/fronds/scaffold/entities/BuildFrond.d.ts.map +1 -0
- package/dist/fronds/scaffold/entities/BuildFrond.js +6 -0
- package/dist/fronds/scaffold/entities/BuildFrond.js.map +1 -0
- package/dist/fronds/scaffold/entities/Call.d.ts +8 -0
- package/dist/fronds/scaffold/entities/Call.d.ts.map +1 -0
- package/{fronds/scaffold/entities/Call.ts → dist/fronds/scaffold/entities/Call.js} +4 -3
- package/dist/fronds/scaffold/entities/Call.js.map +1 -0
- package/dist/fronds/scaffold/entities/Completion.d.ts +7 -0
- package/dist/fronds/scaffold/entities/Completion.d.ts.map +1 -0
- package/dist/fronds/scaffold/entities/Completion.js +6 -0
- package/dist/fronds/scaffold/entities/Completion.js.map +1 -0
- package/dist/fronds/scaffold/entities/Grant.d.ts +8 -0
- package/dist/fronds/scaffold/entities/Grant.d.ts.map +1 -0
- package/{fronds/scaffold/entities/Grant.ts → dist/fronds/scaffold/entities/Grant.js} +4 -3
- package/dist/fronds/scaffold/entities/Grant.js.map +1 -0
- package/dist/fronds/scaffold/entities/Keys.d.ts +6 -0
- package/dist/fronds/scaffold/entities/Keys.d.ts.map +1 -0
- package/{fronds/scaffold/entities/Keys.ts → dist/fronds/scaffold/entities/Keys.js} +3 -2
- package/dist/fronds/scaffold/entities/Keys.js.map +1 -0
- package/dist/fronds/scaffold/entities/New.d.ts +21 -0
- package/dist/fronds/scaffold/entities/New.d.ts.map +1 -0
- package/dist/fronds/scaffold/entities/New.js +20 -0
- package/dist/fronds/scaffold/entities/New.js.map +1 -0
- package/dist/fronds/scaffold/entities/Serve.d.ts +10 -0
- package/dist/fronds/scaffold/entities/Serve.d.ts.map +1 -0
- package/dist/fronds/scaffold/entities/Serve.js +9 -0
- package/dist/fronds/scaffold/entities/Serve.js.map +1 -0
- package/dist/fronds/scaffold/entities/Sync.d.ts +8 -0
- package/dist/fronds/scaffold/entities/Sync.d.ts.map +1 -0
- package/dist/fronds/scaffold/entities/Sync.js +7 -0
- package/dist/fronds/scaffold/entities/Sync.js.map +1 -0
- package/dist/fronds/scaffold/handlers/BuildFrondHandler.d.ts +11 -0
- package/dist/fronds/scaffold/handlers/BuildFrondHandler.d.ts.map +1 -0
- package/dist/fronds/scaffold/handlers/BuildFrondHandler.js +82 -0
- package/dist/fronds/scaffold/handlers/BuildFrondHandler.js.map +1 -0
- package/dist/fronds/scaffold/handlers/CallHandler.d.ts +10 -0
- package/dist/fronds/scaffold/handlers/CallHandler.d.ts.map +1 -0
- package/{fronds/scaffold/handlers/CallHandler.ts → dist/fronds/scaffold/handlers/CallHandler.js} +3 -2
- package/dist/fronds/scaffold/handlers/CallHandler.js.map +1 -0
- package/dist/fronds/scaffold/handlers/CompletionHandler.d.ts +9 -0
- package/dist/fronds/scaffold/handlers/CompletionHandler.d.ts.map +1 -0
- package/{fronds/scaffold/handlers/CompletionHandler.ts → dist/fronds/scaffold/handlers/CompletionHandler.js} +3 -2
- package/dist/fronds/scaffold/handlers/CompletionHandler.js.map +1 -0
- package/dist/fronds/scaffold/handlers/GrantHandler.d.ts +9 -0
- package/dist/fronds/scaffold/handlers/GrantHandler.d.ts.map +1 -0
- package/{fronds/scaffold/handlers/GrantHandler.ts → dist/fronds/scaffold/handlers/GrantHandler.js} +3 -2
- package/dist/fronds/scaffold/handlers/GrantHandler.js.map +1 -0
- package/dist/fronds/scaffold/handlers/KeysHandler.d.ts +9 -0
- package/dist/fronds/scaffold/handlers/KeysHandler.d.ts.map +1 -0
- package/{fronds/scaffold/handlers/KeysHandler.ts → dist/fronds/scaffold/handlers/KeysHandler.js} +3 -2
- package/dist/fronds/scaffold/handlers/KeysHandler.js.map +1 -0
- package/dist/fronds/scaffold/handlers/NewHandler.d.ts +9 -0
- package/dist/fronds/scaffold/handlers/NewHandler.d.ts.map +1 -0
- package/{fronds/scaffold/handlers/NewHandler.ts → dist/fronds/scaffold/handlers/NewHandler.js} +3 -2
- package/dist/fronds/scaffold/handlers/NewHandler.js.map +1 -0
- package/dist/fronds/scaffold/handlers/ServeHandler.d.ts +10 -0
- package/dist/fronds/scaffold/handlers/ServeHandler.d.ts.map +1 -0
- package/{fronds/scaffold/handlers/ServeHandler.ts → dist/fronds/scaffold/handlers/ServeHandler.js} +3 -2
- package/dist/fronds/scaffold/handlers/ServeHandler.js.map +1 -0
- package/dist/fronds/scaffold/handlers/SyncHandler.d.ts +20 -0
- package/dist/fronds/scaffold/handlers/SyncHandler.d.ts.map +1 -0
- package/dist/fronds/scaffold/handlers/SyncHandler.js +349 -0
- package/dist/fronds/scaffold/handlers/SyncHandler.js.map +1 -0
- package/dist/fronds/scaffold/services/ProjectWriter.d.ts +71 -0
- package/dist/fronds/scaffold/services/ProjectWriter.d.ts.map +1 -0
- package/dist/fronds/scaffold/services/ProjectWriter.js +341 -0
- package/dist/fronds/scaffold/services/ProjectWriter.js.map +1 -0
- package/dist/src/bin.d.ts.map +1 -0
- package/dist/src/bin.js +11 -0
- package/dist/src/bin.js.map +1 -0
- package/dist/src/bridge.d.ts.map +1 -0
- package/dist/src/bridge.js.map +1 -0
- package/dist/src/completion.d.ts.map +1 -0
- package/dist/src/completion.js.map +1 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/loader.d.ts +8 -0
- package/dist/src/loader.d.ts.map +1 -0
- package/dist/{loader.js → src/loader.js} +10 -3
- package/dist/src/loader.js.map +1 -0
- package/dist/src/machine.d.ts.map +1 -0
- package/dist/src/machine.js.map +1 -0
- package/dist/src/main.d.ts +2 -0
- package/dist/src/main.d.ts.map +1 -0
- package/dist/src/main.js +19 -0
- package/dist/src/main.js.map +1 -0
- package/dist/src/runner.d.ts.map +1 -0
- package/dist/{runner.js → src/runner.js} +22 -22
- package/dist/src/runner.js.map +1 -0
- package/dist/src/theme.d.ts.map +1 -0
- package/dist/src/theme.js.map +1 -0
- package/dist/src/typescript/EntityTypes.d.ts.map +1 -0
- package/dist/src/typescript/EntityTypes.js.map +1 -0
- package/dist/src/typescript/FacadeTypes.d.ts.map +1 -0
- package/dist/src/typescript/FacadeTypes.js.map +1 -0
- package/dist/src/typescript/syntax.d.ts.map +1 -0
- package/dist/src/typescript/syntax.js.map +1 -0
- package/dist/{ui.d.ts → src/ui.d.ts} +0 -1
- package/dist/src/ui.d.ts.map +1 -0
- package/dist/{ui.js → src/ui.js} +24 -22
- package/dist/src/ui.js.map +1 -0
- package/package.json +23 -27
- package/templates/workspace/fronds/tsconfig.json +4 -1
- package/app/commands/BuildCommand.ts +0 -43
- package/app/commands/CallCommand.ts +0 -70
- package/app/commands/CheckCommand.ts +0 -70
- package/app/commands/CompletionCommand.ts +0 -24
- package/app/commands/DevtoolsCommand.ts +0 -92
- package/app/commands/ExplainCommand.ts +0 -136
- package/app/commands/FreezeCommand.ts +0 -119
- package/app/commands/GrantCommand.ts +0 -46
- package/app/commands/GraphCommand.ts +0 -91
- package/app/commands/KeysCommand.ts +0 -57
- package/app/commands/LoadCommand.ts +0 -46
- package/app/commands/MigrateCommand.ts +0 -61
- package/app/commands/NewCommand.ts +0 -137
- package/app/commands/ServeCommand.ts +0 -108
- package/dist/bin.d.ts.map +0 -1
- package/dist/bin.js +0 -64
- package/dist/bin.js.map +0 -1
- package/dist/bridge.d.ts.map +0 -1
- package/dist/bridge.js.map +0 -1
- package/dist/completion.d.ts.map +0 -1
- package/dist/completion.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/loader.d.ts +0 -4
- package/dist/loader.d.ts.map +0 -1
- package/dist/loader.js.map +0 -1
- package/dist/machine.d.ts.map +0 -1
- package/dist/machine.js.map +0 -1
- package/dist/runner.d.ts.map +0 -1
- package/dist/runner.js.map +0 -1
- package/dist/theme.d.ts.map +0 -1
- package/dist/theme.js.map +0 -1
- package/dist/typescript/EntityTypes.d.ts.map +0 -1
- package/dist/typescript/EntityTypes.js.map +0 -1
- package/dist/typescript/FacadeTypes.d.ts.map +0 -1
- package/dist/typescript/FacadeTypes.js.map +0 -1
- package/dist/typescript/syntax.d.ts.map +0 -1
- package/dist/typescript/syntax.js.map +0 -1
- package/dist/ui.d.ts.map +0 -1
- package/dist/ui.js.map +0 -1
- package/fronds/analysis/entities/Build.ts +0 -8
- package/fronds/analysis/entities/Check.ts +0 -6
- package/fronds/analysis/entities/Devtools.ts +0 -8
- package/fronds/analysis/entities/Explain.ts +0 -9
- package/fronds/analysis/entities/Freeze.ts +0 -8
- package/fronds/analysis/entities/Graph.ts +0 -7
- package/fronds/analysis/entities/Load.ts +0 -8
- package/fronds/analysis/entities/Migrate.ts +0 -8
- package/fronds/analysis/handlers/BuildHandler.ts +0 -87
- package/fronds/analysis/handlers/CheckHandler.ts +0 -217
- package/fronds/analysis/handlers/DevtoolsHandler.ts +0 -97
- package/fronds/analysis/handlers/ExplainHandler.ts +0 -263
- package/fronds/analysis/handlers/FreezeHandler.ts +0 -183
- package/fronds/analysis/handlers/GraphHandler.ts +0 -38
- package/fronds/analysis/handlers/LoadHandler.ts +0 -44
- package/fronds/analysis/handlers/MigrateHandler.ts +0 -110
- package/fronds/analysis/services/ProjectScan.ts +0 -55
- package/fronds/analysis/versions.ts +0 -59
- package/fronds/scaffold/entities/BuildFrond.ts +0 -5
- package/fronds/scaffold/entities/Completion.ts +0 -5
- package/fronds/scaffold/entities/New.ts +0 -19
- package/fronds/scaffold/entities/Serve.ts +0 -8
- package/fronds/scaffold/entities/Sync.ts +0 -6
- package/fronds/scaffold/handlers/BuildFrondHandler.ts +0 -96
- package/fronds/scaffold/handlers/SyncHandler.ts +0 -376
- package/fronds/scaffold/services/ProjectWriter.ts +0 -339
- package/fronds/shims.d.ts +0 -9
- package/src/bin.ts +0 -77
- package/src/bridge.ts +0 -118
- package/src/completion.ts +0 -145
- package/src/index.ts +0 -1
- package/src/loader.ts +0 -21
- package/src/machine.ts +0 -17
- package/src/runner.ts +0 -152
- package/src/theme.ts +0 -19
- package/src/typescript/EntityTypes.ts +0 -92
- package/src/typescript/FacadeTypes.ts +0 -50
- package/src/typescript/syntax.ts +0 -11
- package/src/ui.ts +0 -142
- /package/dist/{bin.d.ts → src/bin.d.ts} +0 -0
- /package/dist/{bridge.d.ts → src/bridge.d.ts} +0 -0
- /package/dist/{bridge.js → src/bridge.js} +0 -0
- /package/dist/{completion.d.ts → src/completion.d.ts} +0 -0
- /package/dist/{completion.js → src/completion.js} +0 -0
- /package/dist/{index.d.ts → src/index.d.ts} +0 -0
- /package/dist/{index.js → src/index.js} +0 -0
- /package/dist/{machine.d.ts → src/machine.d.ts} +0 -0
- /package/dist/{machine.js → src/machine.js} +0 -0
- /package/dist/{runner.d.ts → src/runner.d.ts} +0 -0
- /package/dist/{theme.d.ts → src/theme.d.ts} +0 -0
- /package/dist/{theme.js → src/theme.js} +0 -0
- /package/dist/{typescript → src/typescript}/EntityTypes.d.ts +0 -0
- /package/dist/{typescript → src/typescript}/EntityTypes.js +0 -0
- /package/dist/{typescript → src/typescript}/FacadeTypes.d.ts +0 -0
- /package/dist/{typescript → src/typescript}/FacadeTypes.js +0 -0
- /package/dist/{typescript → src/typescript}/syntax.d.ts +0 -0
- /package/dist/{typescript → src/typescript}/syntax.js +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { App } from '@fougere/core';
|
|
2
|
+
import type { ui as createUi } from '../../src/ui.js';
|
|
3
|
+
import type { ExplainResult, ExplainListing } from '../../fronds/analysis/handlers/ExplainHandler.js';
|
|
4
|
+
type Ui = ReturnType<typeof createUi>;
|
|
5
|
+
export default class ExplainCommand {
|
|
6
|
+
private app;
|
|
7
|
+
private ui;
|
|
8
|
+
constructor(app: App, ui: Ui);
|
|
9
|
+
run(raw: Record<string, unknown>): Promise<void>;
|
|
10
|
+
private listing;
|
|
11
|
+
private ask;
|
|
12
|
+
}
|
|
13
|
+
/** Kept as the name `tests/explain.test.ts` pins the key order through. */
|
|
14
|
+
export declare function renderExplainJson(result: ExplainResult): string;
|
|
15
|
+
export declare function renderExplain(result: ExplainResult): string;
|
|
16
|
+
export declare function renderListing(listing: ExplainListing): string;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=ExplainCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExplainCommand.d.ts","sourceRoot":"","sources":["../../../app/commands/ExplainCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,KAAK,EAAE,EAAE,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EAEf,MAAM,kDAAkD,CAAC;AAI1D,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEtC,MAAM,CAAC,OAAO,OAAO,cAAc;IACrB,OAAO,CAAC,GAAG;IAAO,OAAO,CAAC,EAAE;IAAxC,YAAoB,GAAG,EAAE,GAAG,EAAU,EAAE,EAAE,EAAE,EAAI;IAE1C,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,iBAarC;YAEa,OAAO;IAkBrB,OAAO,CAAC,GAAG;CAMZ;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAE/D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAqC3D;AAaD,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAa7D"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { createAppRunner } from '@fougere/core';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { machineText, printMachine } from '../../src/machine.js';
|
|
4
|
+
export default class ExplainCommand {
|
|
5
|
+
app;
|
|
6
|
+
ui;
|
|
7
|
+
constructor(app, ui) {
|
|
8
|
+
this.app = app;
|
|
9
|
+
this.ui = ui;
|
|
10
|
+
}
|
|
11
|
+
async run(raw) {
|
|
12
|
+
const names = raw.names;
|
|
13
|
+
const operation = raw.operation?.trim();
|
|
14
|
+
// No operation named — the question is what this project serves at all. The same
|
|
15
|
+
// model answers both, so the facade is the one that was asked, never a guess.
|
|
16
|
+
if (names || !operation)
|
|
17
|
+
return this.listing(raw, names);
|
|
18
|
+
const result = await this.ask('execute', raw);
|
|
19
|
+
if (raw.json === true)
|
|
20
|
+
return printMachine(result);
|
|
21
|
+
this.ui.note(renderExplain(result), result.operation);
|
|
22
|
+
}
|
|
23
|
+
async listing(raw, names) {
|
|
24
|
+
const listing = await this.ask('list', raw);
|
|
25
|
+
// A completion script has no JSON parser: one name per line, nothing else on stdout.
|
|
26
|
+
if (names) {
|
|
27
|
+
const values = names === 'fronds'
|
|
28
|
+
? listing.fronds.map((frond) => frond.name)
|
|
29
|
+
: listing.operations;
|
|
30
|
+
if (values.length > 0)
|
|
31
|
+
process.stdout.write(values.join('\n') + '\n');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (raw.json === true)
|
|
35
|
+
return printMachine(listing);
|
|
36
|
+
this.ui.note(renderListing(listing), 'what this project serves');
|
|
37
|
+
}
|
|
38
|
+
ask(op, raw) {
|
|
39
|
+
return createAppRunner(this.app)({ entity: 'explain', op }, { params: {}, query: {}, input: raw, state: {} });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Kept as the name `tests/explain.test.ts` pins the key order through. */
|
|
43
|
+
export function renderExplainJson(result) {
|
|
44
|
+
return machineText(result);
|
|
45
|
+
}
|
|
46
|
+
export function renderExplain(result) {
|
|
47
|
+
const lines = [
|
|
48
|
+
`${pc.dim('Handler:')} ${result.handler.class}.${result.handler.method}`,
|
|
49
|
+
`${pc.dim('Address:')} ${result.handler.address}.${result.operation.split('.').at(-1)}`,
|
|
50
|
+
`${pc.dim('Kind:')} ${result.kind}`,
|
|
51
|
+
`${pc.dim('Input:')} ${result.input ?? '—'}`,
|
|
52
|
+
`${pc.dim('Output:')} ${result.output ? `${result.output.type}${result.output.cardinality ? ` (${result.output.cardinality})` : ''}` : '—'}`,
|
|
53
|
+
];
|
|
54
|
+
if (result.description)
|
|
55
|
+
lines.push(`${pc.dim('Purpose:')} ${result.description}`);
|
|
56
|
+
lines.push('', pc.bold('Parameters'));
|
|
57
|
+
if (result.parameters.length === 0)
|
|
58
|
+
lines.push(' —');
|
|
59
|
+
for (const parameter of result.parameters) {
|
|
60
|
+
const optional = parameter.optional ? '?' : '';
|
|
61
|
+
lines.push(` ${parameter.name}${optional}: ${parameter.type ?? 'unknown'} ${pc.dim('→')} ${bindingName(parameter.binding)}`);
|
|
62
|
+
}
|
|
63
|
+
lines.push('', pc.bold('Collectors'));
|
|
64
|
+
if (result.collectors.length === 0)
|
|
65
|
+
lines.push(' —');
|
|
66
|
+
for (const collector of result.collectors) {
|
|
67
|
+
lines.push(` ${collector.typeName} ${pc.dim('→')} ${collector.class}`);
|
|
68
|
+
}
|
|
69
|
+
lines.push('', `${pc.dim('Surfaces:')} ${result.exposure.surfaces.join(', ') || '—'}`, `${pc.dim('Adapters:')} ${result.exposure.adapters.join(', ') || '—'}`, `${pc.dim('Placement:')} ${result.placement.frond} / ${result.placement.runtime}${result.placement.remote ? ` (${result.placement.remote})` : ''}`,
|
|
70
|
+
// Where the work GOES, under where it answers. The hop count is what a sampling rate, a
|
|
71
|
+
// histogram's bounds and a load threshold are all a function of — each hard-coded today.
|
|
72
|
+
`${pc.dim('Reach:')} ${renderReach(result.reach)}`);
|
|
73
|
+
if (result.handler.file)
|
|
74
|
+
lines.push(`${pc.dim('Source:')} ${result.handler.file}`);
|
|
75
|
+
return lines.join('\n');
|
|
76
|
+
}
|
|
77
|
+
/** What this op reaches, and the part of it that costs a round trip. */
|
|
78
|
+
function renderReach(reach) {
|
|
79
|
+
if (reach.fronds.length === 0)
|
|
80
|
+
return pc.dim('nothing outside its own frond');
|
|
81
|
+
const named = reach.fronds
|
|
82
|
+
.map((one) => (one.runtime === 'remote' ? pc.yellow(one.frond) : pc.cyan(one.frond)))
|
|
83
|
+
.join(', ');
|
|
84
|
+
return `${named} ${pc.dim(`— ${reach.hops} hop(s)`)}`;
|
|
85
|
+
}
|
|
86
|
+
export function renderListing(listing) {
|
|
87
|
+
const lines = [pc.bold('Fronds')];
|
|
88
|
+
if (listing.fronds.length === 0)
|
|
89
|
+
lines.push(' —');
|
|
90
|
+
for (const frond of listing.fronds) {
|
|
91
|
+
const where = frond.remote ? `remote ${pc.dim(frond.remote)}` : 'local';
|
|
92
|
+
lines.push(` ${frond.name} ${pc.dim('→')} ${where}, ${frond.operations} operation(s)`);
|
|
93
|
+
}
|
|
94
|
+
lines.push('', pc.bold('Operations'));
|
|
95
|
+
if (listing.operations.length === 0)
|
|
96
|
+
lines.push(' —');
|
|
97
|
+
for (const operation of listing.operations)
|
|
98
|
+
lines.push(` ${operation}`);
|
|
99
|
+
return lines.join('\n');
|
|
100
|
+
}
|
|
101
|
+
function bindingName(binding) {
|
|
102
|
+
if (!binding)
|
|
103
|
+
return 'unbound';
|
|
104
|
+
switch (binding.kind) {
|
|
105
|
+
case 'collector': return `collector:${binding.typeName}`;
|
|
106
|
+
case 'fact': return `fact:${binding.factName}`;
|
|
107
|
+
case 'param': return `param:${binding.name}${binding.coerce ? ` (${binding.coerce})` : ''}`;
|
|
108
|
+
default: return binding.kind;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=ExplainCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExplainCommand.js","sourceRoot":"","sources":["../../../app/commands/ExplainCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { App } from '@fougere/core';
|
|
2
|
+
import type { ui as createUi } from '../../src/ui.js';
|
|
3
|
+
type Ui = ReturnType<typeof createUi>;
|
|
4
|
+
/**
|
|
5
|
+
* Cutting a version — inspect, ask what only a human knows, then record.
|
|
6
|
+
*
|
|
7
|
+
* The question is asked between the two ops and nowhere else: a field gone plus a field
|
|
8
|
+
* appeared is either a rename or a drop-and-add, the two produce opposite DDL, and the
|
|
9
|
+
* intent left with the person who made the change. Nothing is written until it is settled.
|
|
10
|
+
*/
|
|
11
|
+
export default class FreezeCommand {
|
|
12
|
+
private app;
|
|
13
|
+
private ui;
|
|
14
|
+
constructor(app: App, ui: Ui);
|
|
15
|
+
run(raw: Record<string, unknown>): Promise<void>;
|
|
16
|
+
/** Turn every ambiguity into a declaration, or `undefined` when the answer is a refusal. */
|
|
17
|
+
private settle;
|
|
18
|
+
private report;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=FreezeCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FreezeCommand.d.ts","sourceRoot":"","sources":["../../../app/commands/FreezeCommand.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,EAAE,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAKtD,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEtC;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;IACpB,OAAO,CAAC,GAAG;IAAO,OAAO,CAAC,EAAE;IAAxC,YAAoB,GAAG,EAAE,GAAG,EAAU,EAAE,EAAE,EAAE,EAAI;IAE1C,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,iBAkCrC;IAED,4FAA4F;YAC9E,MAAM;IAmCpB,OAAO,CAAC,MAAM;CAkBf"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { createAppRunner } from '@fougere/core';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { machineWanted, printMachine } from '../../src/machine.js';
|
|
4
|
+
/**
|
|
5
|
+
* Cutting a version — inspect, ask what only a human knows, then record.
|
|
6
|
+
*
|
|
7
|
+
* The question is asked between the two ops and nowhere else: a field gone plus a field
|
|
8
|
+
* appeared is either a rename or a drop-and-add, the two produce opposite DDL, and the
|
|
9
|
+
* intent left with the person who made the change. Nothing is written until it is settled.
|
|
10
|
+
*/
|
|
11
|
+
export default class FreezeCommand {
|
|
12
|
+
app;
|
|
13
|
+
ui;
|
|
14
|
+
constructor(app, ui) {
|
|
15
|
+
this.app = app;
|
|
16
|
+
this.ui = ui;
|
|
17
|
+
}
|
|
18
|
+
async run(raw) {
|
|
19
|
+
if (!raw.version) {
|
|
20
|
+
this.ui.error('Usage: fougere freeze <version>');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const freeze = (input) => createAppRunner(this.app)({ entity: 'freeze', op: 'execute' }, { params: {}, query: {}, input, state: {} });
|
|
24
|
+
// Idempotent while it refuses: this writes when nothing is ambiguous, and reports
|
|
25
|
+
// otherwise — so the first call is both the inspection and the happy path.
|
|
26
|
+
const seen = await freeze(raw);
|
|
27
|
+
// The question below cannot be put to a machine, so the inspection is the answer:
|
|
28
|
+
// `ambiguous` says what a human still has to settle, and nothing was written.
|
|
29
|
+
if (machineWanted(raw))
|
|
30
|
+
return printMachine(seen);
|
|
31
|
+
if (seen.entities.length === 0) {
|
|
32
|
+
this.ui.warn('No entities found. Run this from a Fougere project root.');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (seen.written) {
|
|
36
|
+
this.report(seen);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const renamed = await this.settle(seen);
|
|
40
|
+
if (renamed === undefined)
|
|
41
|
+
return;
|
|
42
|
+
this.report(await freeze({ ...raw, renamed }));
|
|
43
|
+
}
|
|
44
|
+
/** Turn every ambiguity into a declaration, or `undefined` when the answer is a refusal. */
|
|
45
|
+
async settle(seen) {
|
|
46
|
+
const renamed = {};
|
|
47
|
+
const pending = Object.entries(seen.ambiguous);
|
|
48
|
+
if (pending.length === 0)
|
|
49
|
+
return renamed;
|
|
50
|
+
this.ui.warn('A field left and a field of the same shape appeared. Only you know which.');
|
|
51
|
+
for (const [entity, pairs] of pending) {
|
|
52
|
+
// Grouped by what LEFT: one departed field is one question, however many
|
|
53
|
+
// candidates carry its shape.
|
|
54
|
+
const byRemoved = new Map();
|
|
55
|
+
for (const { removed, added } of pairs)
|
|
56
|
+
byRemoved.set(removed, [...(byRemoved.get(removed) ?? []), added]);
|
|
57
|
+
for (const [removed, candidates] of byRemoved) {
|
|
58
|
+
const answer = await this.ui.select({
|
|
59
|
+
message: `${entity}.${pc.bold(removed)} — what happened to it?`,
|
|
60
|
+
options: [
|
|
61
|
+
...candidates.map((added) => ({ value: added, label: `renamed to ${added}`, hint: 'the data moves with it' })),
|
|
62
|
+
{ value: '', label: 'dropped', hint: 'the column goes, and what it held goes with it' },
|
|
63
|
+
],
|
|
64
|
+
});
|
|
65
|
+
// An empty answer is a cancel as much as a "dropped" — writing on either would
|
|
66
|
+
// record a decision nobody made.
|
|
67
|
+
if (!answer) {
|
|
68
|
+
this.ui.warn(`${entity}.${removed} treated as dropped — say so explicitly if that is right.`);
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
renamed[entity] = { ...renamed[entity], [removed]: answer };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return renamed;
|
|
75
|
+
}
|
|
76
|
+
report(written) {
|
|
77
|
+
const { step } = written;
|
|
78
|
+
if (!step) {
|
|
79
|
+
this.ui.success(`${written.version} recorded — ${written.entities.length} entities, and nothing before it`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const moved = Object.entries(step.entities);
|
|
83
|
+
const count = moved.reduce((total, [, answer]) => total + answer.changes.length, 0);
|
|
84
|
+
this.ui.success(`${written.version} recorded — ${count} change(s) since ${written.previous}`);
|
|
85
|
+
for (const [entity, answer] of moved) {
|
|
86
|
+
this.ui.step(`${pc.bold(entity)} — ${answer.changes.map(describeChange).join(', ')}`);
|
|
87
|
+
}
|
|
88
|
+
if (step.entitiesAdded.length > 0)
|
|
89
|
+
this.ui.step(`new: ${step.entitiesAdded.join(', ')}`);
|
|
90
|
+
if (step.entitiesRemoved.length > 0)
|
|
91
|
+
this.ui.step(`gone: ${step.entitiesRemoved.join(', ')}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function describeChange(change) {
|
|
95
|
+
if (change.kind === 'renamed')
|
|
96
|
+
return `${change.from} → ${change.to}`;
|
|
97
|
+
// An axis that moved names WHICH: "restated title" says nothing a reader can act on.
|
|
98
|
+
if (change.kind === 'restated')
|
|
99
|
+
return `${change.field}: ${change.axis} moved`;
|
|
100
|
+
return `${change.kind} ${change.field}`;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=FreezeCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FreezeCommand.js","sourceRoot":"","sources":["../../../app/commands/FreezeCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { App } from '@fougere/core';
|
|
2
|
+
import type { ui as createUi } from '../../src/ui.js';
|
|
3
|
+
type Ui = ReturnType<typeof createUi>;
|
|
4
|
+
/**
|
|
5
|
+
* Vouch for one frond: bind its name to a fresh key, signed by the root.
|
|
6
|
+
*
|
|
7
|
+
* The key is printed and never stored — it belongs to the deployment, not to the
|
|
8
|
+
* repository. Re-running issues a NEW key rather than showing the old one, which is
|
|
9
|
+
* what rotation is: run it again, redeploy that frond, and nobody else's config moves.
|
|
10
|
+
*/
|
|
11
|
+
export default class GrantCommand {
|
|
12
|
+
private app;
|
|
13
|
+
private ui;
|
|
14
|
+
constructor(app: App, ui: Ui);
|
|
15
|
+
run(raw: Record<string, unknown>): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=GrantCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrantCommand.d.ts","sourceRoot":"","sources":["../../../app/commands/GrantCommand.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,EAAE,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGtD,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEtC;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;IACnB,OAAO,CAAC,GAAG;IAAO,OAAO,CAAC,EAAE;IAAxC,YAAoB,GAAG,EAAE,GAAG,EAAU,EAAE,EAAE,EAAE,EAAI;IAE1C,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,iBAyBrC;CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { generateKeyPair, issueGrant } from '@fougere/core/node';
|
|
4
|
+
import { ROOT_KEY, packed } from './grant-material.js';
|
|
5
|
+
/**
|
|
6
|
+
* Vouch for one frond: bind its name to a fresh key, signed by the root.
|
|
7
|
+
*
|
|
8
|
+
* The key is printed and never stored — it belongs to the deployment, not to the
|
|
9
|
+
* repository. Re-running issues a NEW key rather than showing the old one, which is
|
|
10
|
+
* what rotation is: run it again, redeploy that frond, and nobody else's config moves.
|
|
11
|
+
*/
|
|
12
|
+
export default class GrantCommand {
|
|
13
|
+
app;
|
|
14
|
+
ui;
|
|
15
|
+
constructor(app, ui) {
|
|
16
|
+
this.app = app;
|
|
17
|
+
this.ui = ui;
|
|
18
|
+
}
|
|
19
|
+
async run(raw) {
|
|
20
|
+
const frond = raw.frond;
|
|
21
|
+
if (!frond) {
|
|
22
|
+
this.ui.error('Usage: fougere grant <frond>');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
let rootPrivateKey;
|
|
26
|
+
try {
|
|
27
|
+
rootPrivateKey = await readFile(join(process.cwd(), ROOT_KEY), 'utf8');
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
this.ui.error(`No ${ROOT_KEY} — run \`fougere keys\` first.`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const { privateKey, publicKey } = generateKeyPair();
|
|
34
|
+
const grant = issueGrant(rootPrivateKey, frond, publicKey);
|
|
35
|
+
this.ui.success(`granted — '${frond}' will be admitted by any receiver trusting this root`);
|
|
36
|
+
this.ui.note(`FOUGERE_KEY=${packed(privateKey)}\nFOUGERE_GRANT=${grant}`, `Inject into '${frond}' at launch — secret, shown once`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=GrantCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrantCommand.js","sourceRoot":"","sources":["../../../app/commands/GrantCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGjE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIvD;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;IACX,GAAG;IAAe,EAAE;IAAxC,YAAoB,GAAQ,EAAU,EAAM;mBAAxB,GAAG;kBAAe,EAAE;IAAO,CAAC;IAEhD,KAAK,CAAC,GAAG,CAAC,GAA4B;QACpC,MAAM,KAAK,GAAG,GAAG,CAAC,KAA2B,CAAC;QAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAE9C,OAAO;QACT,CAAC;QAED,IAAI,cAAsB,CAAC;QAC3B,IAAI,CAAC;YACH,cAAc,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;QACzE,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,QAAQ,gCAAgC,CAAC,CAAC;YAE9D,OAAO;QACT,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,eAAe,EAAE,CAAC;QACpD,MAAM,KAAK,GAAG,UAAU,CAAC,cAAc,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAE3D,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,cAAc,KAAK,uDAAuD,CAAC,CAAC;QAC5F,IAAI,CAAC,EAAE,CAAC,IAAI,CACV,eAAe,MAAM,CAAC,UAAU,CAAC,mBAAmB,KAAK,EAAE,EAC3D,gBAAgB,KAAK,kCAAkC,CACxD,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { App } from '@fougere/core';
|
|
2
|
+
import type { ui as createUi } from '../../src/ui.js';
|
|
3
|
+
type Ui = ReturnType<typeof createUi>;
|
|
4
|
+
export default class GraphCommand {
|
|
5
|
+
private app;
|
|
6
|
+
private ui;
|
|
7
|
+
constructor(app: App, ui: Ui);
|
|
8
|
+
run(raw: Record<string, unknown>): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=GraphCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphCommand.d.ts","sourceRoot":"","sources":["../../../app/commands/GraphCommand.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA+C,GAAG,EAAE,MAAM,eAAe,CAAC;AAEtF,OAAO,KAAK,EAAE,EAAE,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAItD,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEtC,MAAM,CAAC,OAAO,OAAO,YAAY;IACnB,OAAO,CAAC,GAAG;IAAO,OAAO,CAAC,EAAE;IAAxC,YAAoB,GAAG,EAAE,GAAG,EAAU,EAAE,EAAE,EAAE,EAAI;IAE1C,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,iBA4BrC;CACF"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createAppRunner } from '@fougere/core';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { machineWanted, printMachine } from '../../src/machine.js';
|
|
4
|
+
export default class GraphCommand {
|
|
5
|
+
app;
|
|
6
|
+
ui;
|
|
7
|
+
constructor(app, ui) {
|
|
8
|
+
this.app = app;
|
|
9
|
+
this.ui = ui;
|
|
10
|
+
}
|
|
11
|
+
async run(raw) {
|
|
12
|
+
// Ride the call contract — the same envelope every consumer uses.
|
|
13
|
+
const result = await createAppRunner(this.app)({ entity: 'graph', op: 'execute' }, { params: {}, query: {}, input: raw, state: {} });
|
|
14
|
+
if (machineWanted(raw))
|
|
15
|
+
return printMachine(result);
|
|
16
|
+
if (result.totalFronds === 0) {
|
|
17
|
+
this.ui.warn('No fronds found. Run this from a Fougere project root.');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
this.ui.step(`${pc.bold(String(result.totalEntities))} entities, ${pc.bold(String(result.totalRefs))} refs, ${pc.bold(String(result.totalFronds))} frond(s)`);
|
|
21
|
+
this.ui.note(renderFronds(result.declared), 'Fronds');
|
|
22
|
+
this.ui.note(renderGraph(result.nodes), 'Entity Graph');
|
|
23
|
+
const min = raw.minEntities ?? 6;
|
|
24
|
+
if (result.clusters.length > 1 && result.totalEntities >= min) {
|
|
25
|
+
this.ui.note(renderClusters(result.clusters), 'Suggested Domains');
|
|
26
|
+
}
|
|
27
|
+
if (result.totalFronds === 1 && result.clusters.length > 1 && result.totalEntities >= min) {
|
|
28
|
+
this.ui.info(`${pc.dim('Tip:')} ${result.clusters.length} natural domains detected. Consider splitting into separate fronds.`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Where each frond runs, and which reaches which. Read from `remotes:` and from what handlers
|
|
34
|
+
* ask for — never from a call, so this says the same thing with nothing running.
|
|
35
|
+
*/
|
|
36
|
+
function renderFronds(declared) {
|
|
37
|
+
const reached = new Map();
|
|
38
|
+
for (const edge of declared.edges) {
|
|
39
|
+
reached.set(edge.from, [...(reached.get(edge.from) ?? []), edge.to]);
|
|
40
|
+
}
|
|
41
|
+
const width = Math.max(0, ...declared.fronds.map((one) => one.frond.length));
|
|
42
|
+
return declared.fronds.map((one) => {
|
|
43
|
+
const name = pc.bold(one.frond.padEnd(width));
|
|
44
|
+
const where = one.placement === 'local' ? pc.dim('local ') : pc.yellow('remote');
|
|
45
|
+
const at = one.at ? ` ${pc.dim(one.at)}` : '';
|
|
46
|
+
const calls = reached.get(one.frond);
|
|
47
|
+
const out = calls ? ` ${pc.dim('→')} ${calls.map((to) => pc.cyan(to)).join(', ')}` : '';
|
|
48
|
+
return ` ${name} ${where}${at}${out}`;
|
|
49
|
+
}).join('\n');
|
|
50
|
+
}
|
|
51
|
+
function renderGraph(nodes) {
|
|
52
|
+
return Object.entries(nodes).map(([name, node]) => {
|
|
53
|
+
const refs = node.refs.length > 0
|
|
54
|
+
? ` ${pc.dim('→')} ${node.refs.map((r) => pc.cyan(r)).join(', ')}`
|
|
55
|
+
: '';
|
|
56
|
+
const badge = node.referencedBy.length > 0
|
|
57
|
+
? pc.dim(` (${node.referencedBy.length} incoming)`)
|
|
58
|
+
: '';
|
|
59
|
+
return ` ${pc.bold(name)}${refs}${badge}`;
|
|
60
|
+
}).join('\n');
|
|
61
|
+
}
|
|
62
|
+
function renderClusters(clusters) {
|
|
63
|
+
return clusters.map((cluster) => {
|
|
64
|
+
const header = ` ${pc.green(pc.bold(cluster.name + '/'))} ${pc.dim(`(${cluster.entities.length} entities)`)}`;
|
|
65
|
+
const entities = cluster.entities.map((e) => ` ${e}`);
|
|
66
|
+
const crossRefs = cluster.crossRefs.length > 0
|
|
67
|
+
? [` ${pc.dim('cross-refs:')}`, ...cluster.crossRefs.map((r) => ` ${r.from} ${pc.dim('→')} ${pc.yellow(r.to)} ${pc.dim(`(${r.targetCluster})`)}`)]
|
|
68
|
+
: [];
|
|
69
|
+
return [header, ...entities, ...crossRefs, ''].join('\n');
|
|
70
|
+
}).join('\n');
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=GraphCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphCommand.js","sourceRoot":"","sources":["../../../app/commands/GraphCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { App } from '@fougere/core';
|
|
2
|
+
import type { ui as createUi } from '../../src/ui.js';
|
|
3
|
+
type Ui = ReturnType<typeof createUi>;
|
|
4
|
+
/**
|
|
5
|
+
* Create the authority — a command, not a service.
|
|
6
|
+
*
|
|
7
|
+
* This is the whole of it: it runs at deployment time and exits. Nothing stays alive,
|
|
8
|
+
* nothing is joined at boot, and no frond reaches anything to prove who it is. What a
|
|
9
|
+
* receiver ends up holding is ONE public key, so a frond granted tomorrow is admitted
|
|
10
|
+
* by a receiver deployed today without its config being touched.
|
|
11
|
+
*
|
|
12
|
+
* The private key is written and never printed: it signs grants, and a grant is the
|
|
13
|
+
* only thing that has to travel.
|
|
14
|
+
*/
|
|
15
|
+
export default class KeysCommand {
|
|
16
|
+
private app;
|
|
17
|
+
private ui;
|
|
18
|
+
constructor(app: App, ui: Ui);
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=KeysCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeysCommand.d.ts","sourceRoot":"","sources":["../../../app/commands/KeysCommand.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,EAAE,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGtD,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEtC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAClB,OAAO,CAAC,GAAG;IAAO,OAAO,CAAC,EAAE;IAAxC,YAAoB,GAAG,EAAE,GAAG,EAAU,EAAE,EAAE,EAAE,EAAI;IAE1C,GAAG,kBAoBR;CACF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile, appendFile, access } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { generateKeyPair } from '@fougere/core/node';
|
|
4
|
+
import { ROOT_KEY, packed } from './grant-material.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create the authority — a command, not a service.
|
|
7
|
+
*
|
|
8
|
+
* This is the whole of it: it runs at deployment time and exits. Nothing stays alive,
|
|
9
|
+
* nothing is joined at boot, and no frond reaches anything to prove who it is. What a
|
|
10
|
+
* receiver ends up holding is ONE public key, so a frond granted tomorrow is admitted
|
|
11
|
+
* by a receiver deployed today without its config being touched.
|
|
12
|
+
*
|
|
13
|
+
* The private key is written and never printed: it signs grants, and a grant is the
|
|
14
|
+
* only thing that has to travel.
|
|
15
|
+
*/
|
|
16
|
+
export default class KeysCommand {
|
|
17
|
+
app;
|
|
18
|
+
ui;
|
|
19
|
+
constructor(app, ui) {
|
|
20
|
+
this.app = app;
|
|
21
|
+
this.ui = ui;
|
|
22
|
+
}
|
|
23
|
+
async run() {
|
|
24
|
+
const path = join(process.cwd(), ROOT_KEY);
|
|
25
|
+
if (await exists(path)) {
|
|
26
|
+
this.ui.error(`${ROOT_KEY} already exists — a second root would split the system in two.`);
|
|
27
|
+
this.ui.info('Delete it deliberately to start over; every grant issued so far stops being recognized.');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const { privateKey, publicKey } = generateKeyPair();
|
|
31
|
+
await mkdir(join(process.cwd(), '.fougere'), { recursive: true });
|
|
32
|
+
await writeFile(path, privateKey, { mode: 0o600 });
|
|
33
|
+
await ignore(ROOT_KEY);
|
|
34
|
+
this.ui.success(`root created — ${ROOT_KEY} (never commit it; added to .gitignore)`);
|
|
35
|
+
this.ui.note(`FOUGERE_ROOT_KEY=${packed(publicKey)}`, 'Every frond that ANSWERS — public, safe in an image or a manifest');
|
|
36
|
+
this.ui.info('Then `fougere grant <frond>` for each frond that CALLS.');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function exists(path) {
|
|
40
|
+
return access(path).then(() => true, () => false);
|
|
41
|
+
}
|
|
42
|
+
/** Keep the root out of a commit — the one mistake that cannot be walked back. */
|
|
43
|
+
async function ignore(entry) {
|
|
44
|
+
const path = join(process.cwd(), '.gitignore');
|
|
45
|
+
const current = await readFile(path, 'utf8').catch(() => '');
|
|
46
|
+
if (current.split('\n').some((line) => line.trim() === entry))
|
|
47
|
+
return;
|
|
48
|
+
await appendFile(path, `${current.endsWith('\n') || current === '' ? '' : '\n'}${entry}\n`);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=KeysCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeysCommand.js","sourceRoot":"","sources":["../../../app/commands/KeysCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIvD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IACV,GAAG;IAAe,EAAE;IAAxC,YAAoB,GAAQ,EAAU,EAAM;mBAAxB,GAAG;kBAAe,EAAE;IAAO,CAAC;IAEhD,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC3C,IAAI,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,QAAQ,gEAAgE,CAAC,CAAC;YAC3F,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,yFAAyF,CAAC,CAAC;YAExG,OAAO;QACT,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,eAAe,EAAE,CAAC;QACpD,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,MAAM,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACnD,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QAEvB,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,kBAAkB,QAAQ,yCAAyC,CAAC,CAAC;QACrF,IAAI,CAAC,EAAE,CAAC,IAAI,CACV,oBAAoB,MAAM,CAAC,SAAS,CAAC,EAAE,EACvC,mEAAmE,CACpE,CAAC;QACF,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;IAC1E,CAAC;CACF;AAED,KAAK,UAAU,MAAM,CAAC,IAAY;IAChC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;AACpD,CAAC;AAED,kFAAkF;AAClF,KAAK,UAAU,MAAM,CAAC,KAAa;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7D,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,CAAC;QAAE,OAAO;IACtE,MAAM,UAAU,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,IAAI,CAAC,CAAC;AAC9F,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { App } from '@fougere/core';
|
|
2
|
+
import type { ui as createUi } from '../../src/ui.js';
|
|
3
|
+
type Ui = ReturnType<typeof createUi>;
|
|
4
|
+
/**
|
|
5
|
+
* The command the generated header has been naming all along.
|
|
6
|
+
*
|
|
7
|
+
* What it writes is derived — the operations from what the project serves, a body for each from
|
|
8
|
+
* the entity's own fields, the envelope from the one function that states it. What it cannot
|
|
9
|
+
* derive is what the load IS: the weights, the stages and the thresholds are facts about your
|
|
10
|
+
* users, and the file says so where they sit.
|
|
11
|
+
*/
|
|
12
|
+
export default class LoadCommand {
|
|
13
|
+
private app;
|
|
14
|
+
private ui;
|
|
15
|
+
constructor(app: App, ui: Ui);
|
|
16
|
+
run(raw: Record<string, unknown>): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=LoadCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoadCommand.d.ts","sourceRoot":"","sources":["../../../app/commands/LoadCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,KAAK,EAAE,EAAE,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAItD,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAClB,OAAO,CAAC,GAAG;IAAO,OAAO,CAAC,EAAE;IAAxC,YAAoB,GAAG,EAAE,GAAG,EAAU,EAAE,EAAE,EAAE,EAAI;IAE1C,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,iBAwBrC;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createAppRunner } from '@fougere/core';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { machineWanted, printMachine } from '../../src/machine.js';
|
|
4
|
+
/**
|
|
5
|
+
* The command the generated header has been naming all along.
|
|
6
|
+
*
|
|
7
|
+
* What it writes is derived — the operations from what the project serves, a body for each from
|
|
8
|
+
* the entity's own fields, the envelope from the one function that states it. What it cannot
|
|
9
|
+
* derive is what the load IS: the weights, the stages and the thresholds are facts about your
|
|
10
|
+
* users, and the file says so where they sit.
|
|
11
|
+
*/
|
|
12
|
+
export default class LoadCommand {
|
|
13
|
+
app;
|
|
14
|
+
ui;
|
|
15
|
+
constructor(app, ui) {
|
|
16
|
+
this.app = app;
|
|
17
|
+
this.ui = ui;
|
|
18
|
+
}
|
|
19
|
+
async run(raw) {
|
|
20
|
+
const result = await createAppRunner(this.app)({ entity: 'load', op: 'execute' }, { params: {}, query: {}, input: raw, state: {} });
|
|
21
|
+
if (machineWanted(raw))
|
|
22
|
+
return printMachine(result);
|
|
23
|
+
if (result.operations.length === 0) {
|
|
24
|
+
this.ui.warn('No operation answers the default facade — nothing to put under load.');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (!result.file) {
|
|
28
|
+
process.stdout.write(result.script);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
this.ui.step(`${pc.bold(String(result.operations.length))} operation(s) against ${pc.dim(result.facade)}`);
|
|
32
|
+
this.ui.note(result.operations.map((one) => ` ${one}`).join('\n'), 'Under load');
|
|
33
|
+
this.ui.info(`${pc.dim('Written to')} ${result.file} ${pc.dim('— edit the weights, the stages and the thresholds.')}`);
|
|
34
|
+
this.ui.info(`${pc.dim('Then:')} k6 run ${result.file}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=LoadCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoadCommand.js","sourceRoot":"","sources":["../../../app/commands/LoadCommand.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAInE;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IACV,GAAG;IAAe,EAAE;IAAxC,YAAoB,GAAQ,EAAU,EAAM;mBAAxB,GAAG;kBAAe,EAAE;IAAO,CAAC;IAEhD,KAAK,CAAC,GAAG,CAAC,GAA4B;QACpC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAC5C,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,EACjC,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CACjC,CAAC;QAElB,IAAI,aAAa,CAAC,GAAG,CAAC;YAAE,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAEpD,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;YAErF,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEpC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,yBAAyB,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3G,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;QAClF,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC,GAAG,CAAC,oDAAoD,CAAC,EAAE,CAAC,CAAC;QACxH,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { App } from '@fougere/core';
|
|
2
|
+
import type { ui as createUi } from '../../src/ui.js';
|
|
3
|
+
type Ui = ReturnType<typeof createUi>;
|
|
4
|
+
/**
|
|
5
|
+
* Catching a database up with the frozen chain.
|
|
6
|
+
*
|
|
7
|
+
* Prints by default and moves nothing: what this runs drops and renames columns, so the
|
|
8
|
+
* plan is read before it is agreed to. `--apply` is that agreement.
|
|
9
|
+
*/
|
|
10
|
+
export default class MigrateCommand {
|
|
11
|
+
private app;
|
|
12
|
+
private ui;
|
|
13
|
+
constructor(app: App, ui: Ui);
|
|
14
|
+
run(raw: Record<string, unknown>): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=MigrateCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MigrateCommand.d.ts","sourceRoot":"","sources":["../../../app/commands/MigrateCommand.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,EAAE,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAKtD,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IACrB,OAAO,CAAC,GAAG;IAAO,OAAO,CAAC,EAAE;IAAxC,YAAoB,GAAG,EAAE,GAAG,EAAU,EAAE,EAAE,EAAE,EAAI;IAE1C,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,iBAyCrC;CACF"}
|