@dereekb/dbx-cli 13.38.0 → 13.40.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/eslint/package.json +8 -8
- package/firebase-api-manifest/package.json +3 -3
- package/firestore-query-manifest/main.js +3 -3
- package/firestore-query-manifest/package.json +3 -3
- package/generate-firestore-indexes/main.js +2 -2
- package/generate-firestore-indexes/package.json +2 -2
- package/generate-mcp-manifest/package.json +3 -3
- package/generate-route-manifest/package.json +2 -2
- package/index.esm.js +1011 -521
- package/lint-cache/package.json +2 -2
- package/manifest-extract/package.json +7 -7
- package/model-test/LICENSE +21 -0
- package/model-test/index.d.ts +1 -0
- package/model-test/index.esm.js +5984 -0
- package/model-test/package.json +21 -0
- package/model-test/src/index.d.ts +41 -0
- package/model-test/src/lib/fixture/archetype.d.ts +33 -0
- package/model-test/src/lib/fixture/extract.d.ts +37 -0
- package/model-test/src/lib/fixture/format.json.d.ts +24 -0
- package/model-test/src/lib/fixture/format.markdown.d.ts +23 -0
- package/model-test/src/lib/fixture/forward.d.ts +48 -0
- package/model-test/src/lib/fixture/framework-fixtures.d.ts +70 -0
- package/model-test/src/lib/fixture/inspect.d.ts +22 -0
- package/model-test/src/lib/fixture/scaffold.d.ts +74 -0
- package/model-test/src/lib/fixture/types.d.ts +175 -0
- package/model-test/src/lib/test/discover.d.ts +81 -0
- package/model-test/src/lib/test/extract.d.ts +49 -0
- package/model-test/src/lib/test/format.hotspots.d.ts +23 -0
- package/model-test/src/lib/test/format.json.d.ts +25 -0
- package/model-test/src/lib/test/format.list-app.d.ts +30 -0
- package/model-test/src/lib/test/format.markdown.d.ts +25 -0
- package/model-test/src/lib/test/hotspots.d.ts +98 -0
- package/model-test/src/lib/test/inspect.d.ts +32 -0
- package/model-test/src/lib/test/search.d.ts +34 -0
- package/model-test/src/lib/test/types.d.ts +179 -0
- package/package.json +18 -22
- package/route/package.json +12 -12
- package/src/lib/firestore/firestore.session.d.ts +40 -0
- package/src/lib/runner/index.d.ts +1 -0
- package/src/lib/runner/lifecycle.d.ts +85 -0
- package/src/lib/runner/run.d.ts +15 -1
- package/test/package.json +14 -14
- package/validate/LICENSE +21 -0
- package/validate/index.js +16641 -0
- package/validate/package.json +11 -0
- package/eslint/index.cjs.default.js +0 -1
- package/eslint/index.cjs.js +0 -1112
- package/eslint/index.cjs.mjs +0 -2
- package/index.cjs.js +0 -65624
- package/manifest-extract/index.cjs.default.js +0 -1
- package/manifest-extract/index.cjs.js +0 -1595
- package/manifest-extract/index.cjs.mjs +0 -2
- package/route/index.cjs.default.js +0 -1
- package/route/index.cjs.js +0 -18
- package/route/index.cjs.mjs +0 -2
- package/test/index.cjs.default.js +0 -1
- package/test/index.cjs.js +0 -383
- package/test/index.cjs.mjs +0 -2
|
@@ -49,6 +49,20 @@ export interface CreateCliFirestoreSessionContextInput {
|
|
|
49
49
|
*/
|
|
50
50
|
readonly refreshSession?: boolean;
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* The Firebase app name a direct-Firestore session registers for a CLI + env pair.
|
|
54
|
+
*
|
|
55
|
+
* Deriving the name rather than tracking apps in a side registry is what makes ONE app per CLI + env
|
|
56
|
+
* per process a property of the code instead of a convention: {@link createCliFirestoreSessionContext}
|
|
57
|
+
* looks this name up in `getApps()` before initializing, so repeated session opens in one process —
|
|
58
|
+
* a doctor probe alongside a command's own session, an action that re-resolves the accessor — all
|
|
59
|
+
* share a single app, and {@link closeAllCliFirebaseApps} finds it again from the name alone.
|
|
60
|
+
*
|
|
61
|
+
* @param input - The CLI name and env name the session targets.
|
|
62
|
+
* @returns The Firebase app name for that pair.
|
|
63
|
+
* @__NO_SIDE_EFFECTS__
|
|
64
|
+
*/
|
|
65
|
+
export declare function cliFirebaseAppName(input: Pick<CreateCliFirestoreSessionContextInput, 'cliName' | 'envName'>): string;
|
|
52
66
|
/**
|
|
53
67
|
* Opens a direct Firestore connection as the authenticated CLI user.
|
|
54
68
|
*
|
|
@@ -95,3 +109,29 @@ export declare function createCliFirestoreSessionContext(input: CreateCliFiresto
|
|
|
95
109
|
* @param session - The session context to close.
|
|
96
110
|
*/
|
|
97
111
|
export declare function closeCliFirestoreSessionContext(session: CliFirestoreSessionContext): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Deletes every still-live Firebase app this CLI opened, whether or not a session was handed back.
|
|
114
|
+
*
|
|
115
|
+
* The CLI's last line of defence against a hang. `closeCliFirestoreSessionContext` covers the normal
|
|
116
|
+
* path, but it needs a session to be handed to it, and three cases never produce one:
|
|
117
|
+
*
|
|
118
|
+
* - a handshake that fails AFTER `initializeApp` — a rejected custom token, a failed App Check
|
|
119
|
+
* registration — throws, so the caller that catches it has an initialized app and no session;
|
|
120
|
+
* - a caller that opens its own session outside the context memo (the doctor probe) owns its own
|
|
121
|
+
* teardown, and forgetting it hangs the process;
|
|
122
|
+
* - a {@link CliContext} orphaned mid-invocation carries the only reference to its session memo.
|
|
123
|
+
*
|
|
124
|
+
* Each leaves an app whose `Firestore` and signed-in `Auth` hold the Node event loop open forever.
|
|
125
|
+
* `getApps()` already tracks every live app and `deleteApp` removes it from that list, so the app
|
|
126
|
+
* names {@link cliFirebaseAppName} derives are enough to find them again — no side registry to keep
|
|
127
|
+
* in sync, and idempotent by construction.
|
|
128
|
+
*
|
|
129
|
+
* Tolerant of failures for the same reason {@link closeCliFirestoreSessionContext} is: it runs after
|
|
130
|
+
* the result is already on stdout.
|
|
131
|
+
*
|
|
132
|
+
* @param input - The function inputs.
|
|
133
|
+
* @param input.cliName - The CLI whose apps should be closed. Apps belonging to other Firebase
|
|
134
|
+
* consumers in the same process are left alone.
|
|
135
|
+
* @returns Resolves once every matching app has been deleted.
|
|
136
|
+
*/
|
|
137
|
+
export declare function closeAllCliFirebaseApps(input: Pick<CreateCliFirestoreSessionContextInput, 'cliName'>): Promise<void>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { type Maybe, type PromiseOrValue } from '@dereekb/util';
|
|
2
|
+
import { type CliContext } from '../context/cli.context';
|
|
3
|
+
/**
|
|
4
|
+
* Input handed to a {@link CliSetupFunction} / {@link CliTeardownFunction}.
|
|
5
|
+
*/
|
|
6
|
+
export interface CliLifecycleHookInput {
|
|
7
|
+
readonly cliName: string;
|
|
8
|
+
/**
|
|
9
|
+
* The invocation's {@link CliContext}, when one was built.
|
|
10
|
+
*
|
|
11
|
+
* Absent for an auth-bypassed command (`auth login`, `env list`, `firestore-queries`), and for a
|
|
12
|
+
* teardown that runs after authentication itself failed. A hook that needs the context should say
|
|
13
|
+
* so by throwing from `setup`, which aborts the command with an error envelope — a `teardown` must
|
|
14
|
+
* tolerate its absence, since it runs on paths `setup` never reached.
|
|
15
|
+
*/
|
|
16
|
+
readonly context: Maybe<CliContext>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* App-supplied hook run once per invocation, after the command's arguments validate and the auth
|
|
20
|
+
* middleware has attached the {@link CliContext}, and before the command's handler.
|
|
21
|
+
*
|
|
22
|
+
* Runs inside the parser, so throwing aborts the command: the error is emitted as the standard error
|
|
23
|
+
* envelope and the process exits non-zero, with {@link CliTeardownFunction} still run. That makes it
|
|
24
|
+
* the right place for a precondition an app's commands all depend on.
|
|
25
|
+
*/
|
|
26
|
+
export type CliSetupFunction = (input: CliLifecycleHookInput) => PromiseOrValue<void>;
|
|
27
|
+
/**
|
|
28
|
+
* App-supplied hook run once per invocation after the parser has fully settled, on both the success
|
|
29
|
+
* and the failure path, and BEFORE the CLI closes its direct-Firestore session — so the hook can
|
|
30
|
+
* still read Firestore through `input.context`.
|
|
31
|
+
*
|
|
32
|
+
* Best-effort, exactly like the built-in session teardown it precedes: it runs after the command's
|
|
33
|
+
* result is already on stdout, so a throw is swallowed (surfaced under `--verbose`) rather than
|
|
34
|
+
* changing what the caller sees or the exit code they get.
|
|
35
|
+
*
|
|
36
|
+
* A teardown may run when {@link CliSetupFunction} did NOT — an invocation that failed validation or
|
|
37
|
+
* authentication never reaches setup — so it must not assume setup's side effects are in place.
|
|
38
|
+
*/
|
|
39
|
+
export type CliTeardownFunction = (input: CliLifecycleHookInput) => PromiseOrValue<void>;
|
|
40
|
+
/**
|
|
41
|
+
* The app-supplied lifecycle hooks accepted by `createCli` / `runCli`.
|
|
42
|
+
*/
|
|
43
|
+
export interface CliLifecycleHooks {
|
|
44
|
+
/**
|
|
45
|
+
* Run once before the command's handler. See {@link CliSetupFunction}.
|
|
46
|
+
*/
|
|
47
|
+
readonly setup?: Maybe<CliSetupFunction>;
|
|
48
|
+
/**
|
|
49
|
+
* Run once after the parser settles, before the direct-Firestore session is closed. See
|
|
50
|
+
* {@link CliTeardownFunction}.
|
|
51
|
+
*/
|
|
52
|
+
readonly teardown?: Maybe<CliTeardownFunction>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Input for {@link cliLifecycleRunner}.
|
|
56
|
+
*/
|
|
57
|
+
export interface CliLifecycleRunnerInput extends CliLifecycleHooks {
|
|
58
|
+
readonly cliName: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The once-per-invocation view of an app's {@link CliLifecycleHooks}.
|
|
62
|
+
*/
|
|
63
|
+
export interface CliLifecycleRunner {
|
|
64
|
+
/**
|
|
65
|
+
* Runs the app's `setup` hook, at most once, rethrowing whatever it throws.
|
|
66
|
+
*/
|
|
67
|
+
readonly runSetup: (context: Maybe<CliContext>) => Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Runs the app's `teardown` hook, at most once, swallowing whatever it throws.
|
|
70
|
+
*/
|
|
71
|
+
readonly runTeardown: (context: Maybe<CliContext>) => Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Wraps an app's lifecycle hooks so each runs at most once per process.
|
|
75
|
+
*
|
|
76
|
+
* The once-only guard is not a convenience: yargs re-runs a global middleware for every COMMAND
|
|
77
|
+
* LEVEL it parses, so a nested command (`action worker export`) enters the setup middleware three
|
|
78
|
+
* times. An app's `setup` is written as "prepare this invocation", not "prepare this command level",
|
|
79
|
+
* and a hook that opened a connection or wrote a file would do it three times over.
|
|
80
|
+
*
|
|
81
|
+
* @param input - The CLI name and the app's hooks.
|
|
82
|
+
* @returns The guarded runner.
|
|
83
|
+
* @__NO_SIDE_EFFECTS__
|
|
84
|
+
*/
|
|
85
|
+
export declare function cliLifecycleRunner(input: CliLifecycleRunnerInput): CliLifecycleRunner;
|
package/src/lib/runner/run.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { type CliContext } from '../context/cli.context';
|
|
|
5
5
|
import { type DoctorCheck } from '../doctor/doctor.command.factory';
|
|
6
6
|
import { type CliFirestoreQueryManifest, type CliModelManifest } from '../manifest/types';
|
|
7
7
|
import { type CliFirestoreBinding } from '../firestore/firestore.models';
|
|
8
|
+
import { type CliLifecycleHooks, type CliLifecycleRunner } from './lifecycle';
|
|
8
9
|
/**
|
|
9
10
|
* Names of the global options registered by {@link createCli} that are not
|
|
10
11
|
* specific to a single manifest command's payload. Manifest commands hide
|
|
@@ -12,7 +13,7 @@ import { type CliFirestoreBinding } from '../firestore/firestore.models';
|
|
|
12
13
|
* focuses on the schema sections.
|
|
13
14
|
*/
|
|
14
15
|
export declare const STANDARD_GLOBAL_OPTION_NAMES: readonly string[];
|
|
15
|
-
export interface CreateCliInput {
|
|
16
|
+
export interface CreateCliInput extends CliLifecycleHooks {
|
|
16
17
|
readonly cliName: string;
|
|
17
18
|
/**
|
|
18
19
|
* App-specific config/utility commands appended after the built-in `auth`, `env`, and `doctor` commands.
|
|
@@ -145,6 +146,16 @@ export interface CreateCliInput {
|
|
|
145
146
|
* bundler `define` or a generated module).
|
|
146
147
|
*/
|
|
147
148
|
readonly version?: string;
|
|
149
|
+
/**
|
|
150
|
+
* The lifecycle runner guarding this invocation's {@link CliLifecycleHooks}.
|
|
151
|
+
*
|
|
152
|
+
* Passed by {@link runCli} so the setup hook the parser runs and the teardown hook the exit path
|
|
153
|
+
* runs share ONE guard — two runners built from the same hooks would each track their own
|
|
154
|
+
* "already ran" flag, and the pairing between them is the whole contract.
|
|
155
|
+
*
|
|
156
|
+
* @internal Apps pass `setup` / `teardown`, not this.
|
|
157
|
+
*/
|
|
158
|
+
readonly lifecycle?: CliLifecycleRunner;
|
|
148
159
|
/**
|
|
149
160
|
* Optional shell-completion command name. When set, yargs registers
|
|
150
161
|
* `<cli> <completionCommandName>` (defaults to `completion`) that emits a bash/zsh script.
|
|
@@ -177,6 +188,9 @@ export interface CreateCliInput {
|
|
|
177
188
|
* if {@link CreateCliInput.modelManifest} is provided.
|
|
178
189
|
* @param input.firestore - The app-supplied direct-Firestore binding; enables `firestore-get` / `firestore-query`.
|
|
179
190
|
* @param input.firestoreQueryManifest - The generated Firestore query catalog; enables `firestore-queries`.
|
|
191
|
+
* @param input.setup - App hook run once before the command's handler; a throw aborts the command.
|
|
192
|
+
* @param input.teardown - App hook run once after the parser settles, before the Firestore session closes.
|
|
193
|
+
* Only {@link runCli} runs it — a caller that drives `createCli().parse()` itself owns its own teardown.
|
|
180
194
|
* @returns The configured yargs `Argv` ready to be `.parse()`-d.
|
|
181
195
|
* @__NO_SIDE_EFFECTS__
|
|
182
196
|
*/
|
package/test/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli/test",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.40.0",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/date": "13.
|
|
6
|
-
"@dereekb/dbx-cli": "13.
|
|
7
|
-
"@dereekb/firebase": "13.
|
|
8
|
-
"@dereekb/firebase-server/test": "13.
|
|
9
|
-
"@dereekb/model": "13.
|
|
10
|
-
"@dereekb/nestjs": "13.
|
|
11
|
-
"@dereekb/rxjs": "13.
|
|
12
|
-
"@dereekb/util": "13.
|
|
6
|
+
"@dereekb/date": "13.40.0",
|
|
7
|
+
"@dereekb/dbx-cli": "13.40.0",
|
|
8
|
+
"@dereekb/firebase": "13.40.0",
|
|
9
|
+
"@dereekb/firebase-server/test": "13.40.0",
|
|
10
|
+
"@dereekb/model": "13.40.0",
|
|
11
|
+
"@dereekb/nestjs": "13.40.0",
|
|
12
|
+
"@dereekb/rxjs": "13.40.0",
|
|
13
|
+
"@dereekb/util": "13.40.0",
|
|
13
14
|
"@nestjs/common": "^11.1.19",
|
|
14
15
|
"arktype": "^2.2.0",
|
|
15
16
|
"vitest": "4.1.5",
|
|
@@ -18,13 +19,12 @@
|
|
|
18
19
|
"exports": {
|
|
19
20
|
"./package.json": "./package.json",
|
|
20
21
|
".": {
|
|
21
|
-
"module": "./index.esm.js",
|
|
22
22
|
"types": "./index.d.ts",
|
|
23
|
-
"import": "./index.
|
|
24
|
-
"default": "./index.
|
|
23
|
+
"import": "./index.esm.js",
|
|
24
|
+
"default": "./index.esm.js"
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
"module": "./index.esm.js",
|
|
28
|
-
"main": "./index.
|
|
28
|
+
"main": "./index.esm.js",
|
|
29
29
|
"types": "./index.d.ts"
|
|
30
|
-
}
|
|
30
|
+
}
|
package/validate/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Hapier Creative LLC.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|