@dereekb/dbx-cli 13.42.0 → 13.43.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 +3 -3
- package/firebase-api-manifest/main.js +21 -3
- package/firebase-api-manifest/package.json +3 -3
- package/firestore-query-manifest/main.js +8 -6
- 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 +1625 -441
- package/lint-cache/package.json +2 -2
- package/manifest-extract/package.json +2 -2
- package/model-test/package.json +2 -2
- package/package.json +6 -6
- package/route/package.json +7 -7
- package/src/lib/doctor/build-drift.check.d.ts +21 -0
- package/src/lib/doctor/doctor.command.factory.d.ts +21 -2
- package/src/lib/doctor/firestore-session.check.d.ts +7 -1
- package/src/lib/doctor/index.d.ts +1 -0
- package/src/lib/firestore/firestore.sdk-identity.d.ts +193 -0
- package/src/lib/firestore/index.d.ts +1 -0
- package/src/lib/manifest/types.d.ts +21 -0
- package/src/lib/mcp-scan/manifest/css-utilities-schema.d.ts +2 -2
- package/src/lib/runner/build-stamp.d.ts +138 -0
- package/src/lib/runner/index.d.ts +1 -0
- package/src/lib/runner/run.d.ts +13 -0
- package/test/package.json +9 -9
- package/validate/index.js +5 -0
- package/validate/package.json +3 -3
package/lint-cache/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli-lint-cache",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.43.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"devDependencies": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"eslint": "10.4.0"
|
|
9
9
|
},
|
|
10
10
|
"peerDependencies": {
|
|
11
|
-
"@dereekb/util": "13.
|
|
11
|
+
"@dereekb/util": "13.43.0",
|
|
12
12
|
"yargs": "^18.0.0"
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli/manifest-extract",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.43.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|
|
7
7
|
"@dereekb/date": "13.15.0",
|
|
8
|
-
"@dereekb/dbx-cli": "13.
|
|
8
|
+
"@dereekb/dbx-cli": "13.43.0",
|
|
9
9
|
"@dereekb/firebase": "13.15.0",
|
|
10
10
|
"@dereekb/model": "13.15.0",
|
|
11
11
|
"@dereekb/nestjs": "13.15.0",
|
package/model-test/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli/model-test",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.43.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|
|
7
|
-
"@dereekb/util": "13.
|
|
7
|
+
"@dereekb/util": "13.43.0",
|
|
8
8
|
"ts-morph": "^21.0.0"
|
|
9
9
|
},
|
|
10
10
|
"exports": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.43.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"bin": {
|
|
@@ -66,11 +66,11 @@
|
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@dereekb/date": "13.
|
|
70
|
-
"@dereekb/firebase": "13.
|
|
71
|
-
"@dereekb/model": "13.
|
|
72
|
-
"@dereekb/nestjs": "13.
|
|
73
|
-
"@dereekb/util": "13.
|
|
69
|
+
"@dereekb/date": "13.43.0",
|
|
70
|
+
"@dereekb/firebase": "13.43.0",
|
|
71
|
+
"@dereekb/model": "13.43.0",
|
|
72
|
+
"@dereekb/nestjs": "13.43.0",
|
|
73
|
+
"@dereekb/util": "13.43.0",
|
|
74
74
|
"@nestjs/common": "^11.1.19",
|
|
75
75
|
"arktype": "^2.2.0",
|
|
76
76
|
"firebase": "^12.12.1",
|
package/route/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli/route",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.43.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|
|
7
|
-
"@dereekb/date": "13.
|
|
8
|
-
"@dereekb/dbx-cli": "13.
|
|
9
|
-
"@dereekb/firebase": "13.
|
|
10
|
-
"@dereekb/model": "13.
|
|
11
|
-
"@dereekb/nestjs": "13.
|
|
12
|
-
"@dereekb/util": "13.
|
|
7
|
+
"@dereekb/date": "13.43.0",
|
|
8
|
+
"@dereekb/dbx-cli": "13.43.0",
|
|
9
|
+
"@dereekb/firebase": "13.43.0",
|
|
10
|
+
"@dereekb/model": "13.43.0",
|
|
11
|
+
"@dereekb/nestjs": "13.43.0",
|
|
12
|
+
"@dereekb/util": "13.43.0"
|
|
13
13
|
},
|
|
14
14
|
"exports": {
|
|
15
15
|
"./package.json": "./package.json",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type InspectCliBuildDriftInput } from '../runner/build-stamp';
|
|
2
|
+
import { type DoctorCheck } from './doctor.command.factory';
|
|
3
|
+
/**
|
|
4
|
+
* Name reported by the check {@link createCliBuildDriftDoctorCheck} builds.
|
|
5
|
+
*/
|
|
6
|
+
export declare const BUILD_DRIFT_DOCTOR_CHECK_NAME = "cli-build-not-stale";
|
|
7
|
+
/**
|
|
8
|
+
* Builds the doctor check that compares the running artifact against the `@dereekb/*` tree resolved
|
|
9
|
+
* at run time.
|
|
10
|
+
*
|
|
11
|
+
* Runs FIRST in the default check list, ahead of every network hop, because a stale artifact
|
|
12
|
+
* invalidates the answers those hops give: they exercise the framework that is loaded now, not the
|
|
13
|
+
* one the bundle was compiled against, so a green `token-refresh-round-trip` next to a red read is
|
|
14
|
+
* exactly the misleading report this check exists to pre-empt.
|
|
15
|
+
*
|
|
16
|
+
* @param input - Optional overrides forwarded to {@link inspectCliBuildDrift}; apps normally pass only
|
|
17
|
+
* `manifestGeneratorVersion`.
|
|
18
|
+
* @returns The {@link DoctorCheck}.
|
|
19
|
+
* @__NO_SIDE_EFFECTS__
|
|
20
|
+
*/
|
|
21
|
+
export declare function createCliBuildDriftDoctorCheck(input?: InspectCliBuildDriftInput): DoctorCheck;
|
|
@@ -16,11 +16,24 @@ export interface DoctorCheckResult {
|
|
|
16
16
|
}
|
|
17
17
|
export type DoctorCheck = (input: DoctorCheckInput) => Promise<DoctorCheckResult>;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* Input for {@link defaultDoctorChecks}.
|
|
20
|
+
*/
|
|
21
|
+
export interface DefaultDoctorChecksInput {
|
|
22
|
+
/**
|
|
23
|
+
* The `@dereekb/dbx-cli` version that emitted the app's generated manifests
|
|
24
|
+
* (`<NAMESPACE>_STAMP.generatorVersion`). Forwarded to the build-drift check so a manifest produced
|
|
25
|
+
* by a different generator than the one running it is flagged.
|
|
26
|
+
*/
|
|
27
|
+
readonly manifestGeneratorVersion?: Maybe<string>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Built-in checks: build not stale, config file present, active env resolved, OIDC discovery, token
|
|
31
|
+
* refresh, API reachability.
|
|
20
32
|
*
|
|
33
|
+
* @param input - Optional configuration for the built-in checks.
|
|
21
34
|
* @returns The default {@link DoctorCheck} list, in execution order.
|
|
22
35
|
*/
|
|
23
|
-
export declare function defaultDoctorChecks(): DoctorCheck[];
|
|
36
|
+
export declare function defaultDoctorChecks(input?: DefaultDoctorChecksInput): DoctorCheck[];
|
|
24
37
|
export interface CreateDoctorCommandInput {
|
|
25
38
|
readonly cliName: string;
|
|
26
39
|
/**
|
|
@@ -32,6 +45,11 @@ export interface CreateDoctorCommandInput {
|
|
|
32
45
|
* doctor can run against an env that only stores overrides on top of a registered default.
|
|
33
46
|
*/
|
|
34
47
|
readonly defaultEnvs?: readonly CliEnvDefault[];
|
|
48
|
+
/**
|
|
49
|
+
* The generator version stamped into the app's generated manifests, forwarded to the built-in
|
|
50
|
+
* build-drift check.
|
|
51
|
+
*/
|
|
52
|
+
readonly manifestGeneratorVersion?: Maybe<string>;
|
|
35
53
|
}
|
|
36
54
|
/**
|
|
37
55
|
* Composable doctor command.
|
|
@@ -43,6 +61,7 @@ export interface CreateDoctorCommandInput {
|
|
|
43
61
|
* @param input.cliName - The CLI's binary name.
|
|
44
62
|
* @param input.checks - Additional checks to append after the default check list.
|
|
45
63
|
* @param input.defaultEnvs - Built-in env presets merged underneath the user's stored env when names match.
|
|
64
|
+
* @param input.manifestGeneratorVersion - The generator version stamped into the app's generated manifests.
|
|
46
65
|
* @returns A yargs `CommandModule` exposing the `doctor` command.
|
|
47
66
|
* @__NO_SIDE_EFFECTS__
|
|
48
67
|
*/
|
|
@@ -120,7 +120,13 @@ export declare function buildFirestoreSessionDoctorReadRouting(input: {
|
|
|
120
120
|
* 3. `GET /session/firestore` is reachable and mints a custom token (+ an App Check token when the
|
|
121
121
|
* API is configured with a web `appId`);
|
|
122
122
|
* 4. `signInWithCustomToken` succeeds against the configured project;
|
|
123
|
-
* 5. the
|
|
123
|
+
* 5. the session's Firestore handle is one the loaded client SDK accepts (`inspectCliFirestoreSdkIdentity`),
|
|
124
|
+
* reported as `stage: 'firestore-sdk-identity'`. Sits between the sign-in and the read because it
|
|
125
|
+
* is the hop whose failure otherwise MASQUERADES as the read's: the handshake returns a uid, and
|
|
126
|
+
* the read then dies on the SDK's `Expected first argument to collection() to be …` — a message
|
|
127
|
+
* that names neither the model nor the handle, and sends the operator to rules and App Check
|
|
128
|
+
* instead of to a duplicated SDK or a stale artifact;
|
|
129
|
+
* 6. the app-supplied {@link FirestoreSessionDoctorProbe} performs one rules-protected read.
|
|
124
130
|
*
|
|
125
131
|
* Doctor checks run PRE-AUTH — `DoctorCheckInput` is only `{ cliName, envName, env, config }`, with no
|
|
126
132
|
* token and no `CliContext` — so this loads credentials itself via `buildCliPaths` +
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { type FirestoreModelKey, type FirestoreModelType } from '@dereekb/firebase';
|
|
2
|
+
import { type Maybe } from '@dereekb/util';
|
|
3
|
+
/**
|
|
4
|
+
* The `drivers.firestoreDriverIdentifier` a client-SDK `FirestoreContext` reports.
|
|
5
|
+
*
|
|
6
|
+
* `clientFirebaseFirestoreContextFactory` stamps this; the server's
|
|
7
|
+
* `googleCloudFirestoreContextFactory` stamps `@google-cloud/firestore` instead. Comparing against
|
|
8
|
+
* it is how {@link inspectCliFirestoreSdkIdentity} tells an admin-SDK context handed to the CLI apart
|
|
9
|
+
* from a genuinely broken client one.
|
|
10
|
+
*/
|
|
11
|
+
export declare const CLI_CLIENT_FIRESTORE_DRIVER_IDENTIFIER = "@firebase/firestore";
|
|
12
|
+
/**
|
|
13
|
+
* The doctor `detail.stage` reported when the session's Firestore handle is not a usable client-SDK
|
|
14
|
+
* `Firestore`.
|
|
15
|
+
*
|
|
16
|
+
* A distinct stage from `rules-protected-read` on purpose: the read never ran, so reporting it under
|
|
17
|
+
* the read's stage is what made this failure look like a rules/App Check problem.
|
|
18
|
+
*/
|
|
19
|
+
export declare const FIRESTORE_SDK_IDENTITY_STAGE = "firestore-sdk-identity";
|
|
20
|
+
/**
|
|
21
|
+
* `CliError` code for a Firestore handle the client SDK does not recognize as its own.
|
|
22
|
+
*/
|
|
23
|
+
export declare const FIRESTORE_SDK_INSTANCE_MISMATCH_CODE = "FIRESTORE_SDK_INSTANCE_MISMATCH";
|
|
24
|
+
/**
|
|
25
|
+
* The distinct ways a session's Firestore handle can be unusable, in the order
|
|
26
|
+
* {@link inspectCliFirestoreSdkIdentity} tests them — most specific diagnosis first.
|
|
27
|
+
*/
|
|
28
|
+
export type CliFirestoreSdkIdentityProblem =
|
|
29
|
+
/**
|
|
30
|
+
* `firestoreContext` is absent, or its `firestore` is null/undefined. Every `collection()` call
|
|
31
|
+
* built off it throws `Expected first argument to collection() to be a CollectionReference, a
|
|
32
|
+
* DocumentReference or FirebaseFirestore` — the SDK's message for ANY non-Firestore first
|
|
33
|
+
* argument, which is why it never named this.
|
|
34
|
+
*/
|
|
35
|
+
'no-firestore-handle'
|
|
36
|
+
/**
|
|
37
|
+
* The context reports a driver other than {@link CLI_CLIENT_FIRESTORE_DRIVER_IDENTIFIER} — an
|
|
38
|
+
* admin/`@google-cloud/firestore` context reached the client-SDK read path.
|
|
39
|
+
*/
|
|
40
|
+
| 'unexpected-driver'
|
|
41
|
+
/**
|
|
42
|
+
* Two copies of `@firebase/firestore` are loaded, so the handle minted by one fails the other's
|
|
43
|
+
* brand check.
|
|
44
|
+
*/
|
|
45
|
+
| 'duplicated-firestore-sdk'
|
|
46
|
+
/**
|
|
47
|
+
* The handle is present and the driver looks right, but it is not an instance of THIS copy of the
|
|
48
|
+
* SDK's `Firestore` class and no duplicate install explains it.
|
|
49
|
+
*/
|
|
50
|
+
| 'foreign-firestore-instance';
|
|
51
|
+
/**
|
|
52
|
+
* Where one consumer resolved `@firebase/firestore` to, and at which version.
|
|
53
|
+
*
|
|
54
|
+
* Reported for both `@dereekb/dbx-cli` and `@dereekb/firebase` because the whole point of the
|
|
55
|
+
* duplicated-SDK hypothesis is that those two answers can differ.
|
|
56
|
+
*/
|
|
57
|
+
export interface CliFirestoreSdkModuleIdentity {
|
|
58
|
+
/**
|
|
59
|
+
* The resolved package directory, or `undefined` when resolution failed.
|
|
60
|
+
*/
|
|
61
|
+
readonly packageDir?: Maybe<string>;
|
|
62
|
+
readonly version?: Maybe<string>;
|
|
63
|
+
/**
|
|
64
|
+
* Why resolution failed, when it did.
|
|
65
|
+
*/
|
|
66
|
+
readonly error?: Maybe<string>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The provenance + brand-check report {@link inspectCliFirestoreSdkIdentity} produces.
|
|
70
|
+
*
|
|
71
|
+
* Everything here is reported whether or not the check passed: a `sdkDuplicated: true` alongside
|
|
72
|
+
* `ok: true` is a latent hazard worth seeing before it becomes an outage.
|
|
73
|
+
*/
|
|
74
|
+
export interface CliFirestoreSdkIdentityReport {
|
|
75
|
+
readonly ok: boolean;
|
|
76
|
+
readonly problem?: CliFirestoreSdkIdentityProblem;
|
|
77
|
+
readonly firestorePresent: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Whether the handle passes `instanceof Firestore` against the copy of `@firebase/firestore` THIS
|
|
80
|
+
* package loaded.
|
|
81
|
+
*/
|
|
82
|
+
readonly firestoreIsSdkInstance: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* The handle's constructor name, which distinguishes a duplicate `Firestore` (same name, different
|
|
85
|
+
* class) from a genuinely foreign object.
|
|
86
|
+
*/
|
|
87
|
+
readonly firestoreConstructor?: Maybe<string>;
|
|
88
|
+
readonly firestoreDriverIdentifier?: Maybe<string>;
|
|
89
|
+
/**
|
|
90
|
+
* The version of the `firebase` umbrella package resolved at runtime.
|
|
91
|
+
*/
|
|
92
|
+
readonly firebaseVersion?: Maybe<string>;
|
|
93
|
+
readonly sdkFromDbxCli: CliFirestoreSdkModuleIdentity;
|
|
94
|
+
readonly sdkFromDbxFirebase: CliFirestoreSdkModuleIdentity;
|
|
95
|
+
/**
|
|
96
|
+
* True when the two resolutions above name DIFFERENT package directories.
|
|
97
|
+
*/
|
|
98
|
+
readonly sdkDuplicated: boolean;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The slice of a session context {@link inspectCliFirestoreSdkIdentity} reads.
|
|
102
|
+
*
|
|
103
|
+
* Deliberately looser than `FirestoreContext`: this check exists precisely for the case where the
|
|
104
|
+
* object is not the shape its declared type claims, so narrowing it here would assume away the
|
|
105
|
+
* failure. A real `CliFirestoreSessionContext['firestoreContext']` is structurally assignable.
|
|
106
|
+
*/
|
|
107
|
+
export interface CliFirestoreSdkIdentityContext {
|
|
108
|
+
readonly firestore?: unknown;
|
|
109
|
+
readonly drivers?: {
|
|
110
|
+
readonly firestoreDriverIdentifier?: unknown;
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Input for {@link inspectCliFirestoreSdkIdentity}.
|
|
115
|
+
*/
|
|
116
|
+
export interface InspectCliFirestoreSdkIdentityInput {
|
|
117
|
+
readonly firestoreContext?: Maybe<CliFirestoreSdkIdentityContext>;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Checks that a session's Firestore handle is one THIS copy of the client SDK will accept, and
|
|
121
|
+
* reports where every consumer resolved the SDK from.
|
|
122
|
+
*
|
|
123
|
+
* Exists because `collection()` refuses any non-`Firestore` first argument with one message —
|
|
124
|
+
* `Expected first argument to collection() to be a CollectionReference, a DocumentReference or
|
|
125
|
+
* FirebaseFirestore` — that names neither the model, nor the collection, nor which of the three
|
|
126
|
+
* distinct causes ({@link CliFirestoreSdkIdentityProblem}) produced it. Every downstream CLI built on
|
|
127
|
+
* `@dereekb/dbx-cli` shares that hazard, so the diagnosis belongs here rather than in an app.
|
|
128
|
+
*
|
|
129
|
+
* The `instanceof` test is the load-bearing one and it is deliberately NOT structural: an identity
|
|
130
|
+
* check across the package boundary is the only thing that can detect a duplicated
|
|
131
|
+
* `@firebase/firestore`, which is exactly what a structural check would hide. (Contrast
|
|
132
|
+
* `firestore.error.ts`, which narrows a thrown `FirebaseError` structurally — there the goal is to
|
|
133
|
+
* classify an error even when copies differ, so the tradeoff runs the other way.)
|
|
134
|
+
*
|
|
135
|
+
* @param input - The session's `firestoreContext`, when one was built.
|
|
136
|
+
* @returns The provenance + brand-check report.
|
|
137
|
+
*/
|
|
138
|
+
export declare function inspectCliFirestoreSdkIdentity(input: InspectCliFirestoreSdkIdentityInput): CliFirestoreSdkIdentityReport;
|
|
139
|
+
/**
|
|
140
|
+
* The actionable next step for a failed {@link inspectCliFirestoreSdkIdentity}, keyed on which
|
|
141
|
+
* problem was found.
|
|
142
|
+
*
|
|
143
|
+
* Each branch names the fix rather than the symptom — a raw SDK sentence sends an operator looking at
|
|
144
|
+
* security rules and App Check, neither of which is ever the cause here.
|
|
145
|
+
*
|
|
146
|
+
* @param report - The report to describe.
|
|
147
|
+
* @returns The suggestion, or `undefined` when the report passed.
|
|
148
|
+
*
|
|
149
|
+
* @__NO_SIDE_EFFECTS__
|
|
150
|
+
*/
|
|
151
|
+
export declare function cliFirestoreSdkIdentitySuggestion(report: CliFirestoreSdkIdentityReport): Maybe<string>;
|
|
152
|
+
/**
|
|
153
|
+
* `CliError` code for a collection/document reference the SDK refused to build for a reason the
|
|
154
|
+
* wiring identity check cannot explain — a bad `--parent`, or an app collection whose own
|
|
155
|
+
* construction is broken.
|
|
156
|
+
*/
|
|
157
|
+
export declare const FIRESTORE_COLLECTION_UNRESOLVABLE_CODE = "FIRESTORE_COLLECTION_UNRESOLVABLE";
|
|
158
|
+
/**
|
|
159
|
+
* Input for {@link cliFirestoreWiringError}.
|
|
160
|
+
*/
|
|
161
|
+
export interface CliFirestoreWiringErrorInput {
|
|
162
|
+
/**
|
|
163
|
+
* The value the SDK threw.
|
|
164
|
+
*/
|
|
165
|
+
readonly error: unknown;
|
|
166
|
+
/**
|
|
167
|
+
* What the CLI was doing, phrased to complete `Could not <operation>` — e.g.
|
|
168
|
+
* `build the app's Firestore collections`.
|
|
169
|
+
*/
|
|
170
|
+
readonly operation: string;
|
|
171
|
+
readonly modelType?: FirestoreModelType;
|
|
172
|
+
readonly collectionName?: string;
|
|
173
|
+
/**
|
|
174
|
+
* The `--parent` in play, when one was supplied. Reported either way: "no `--parent`" rules out the
|
|
175
|
+
* subcollection route, which is otherwise the first thing an operator has to go and check.
|
|
176
|
+
*/
|
|
177
|
+
readonly parentKey?: FirestoreModelKey;
|
|
178
|
+
readonly firestoreContext?: Maybe<CliFirestoreSdkIdentityContext>;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Re-raises a reference-construction failure as a `CliError` that names WHAT was being built and, when
|
|
182
|
+
* the SDK handle is at fault, WHY.
|
|
183
|
+
*
|
|
184
|
+
* The failure this replaces is the least readable in the direct-Firestore path: `collection()` and
|
|
185
|
+
* `doc()` reject a bad first argument with a message that names neither the model, the collection, the
|
|
186
|
+
* `--parent`, nor the handle — and every one of those is known at the call site. A `CliError` already
|
|
187
|
+
* raised upstream (an unknown model type, a malformed `--parent`) is passed through untouched, so this
|
|
188
|
+
* can be applied unconditionally in a `catch`.
|
|
189
|
+
*
|
|
190
|
+
* @param input - The thrown value plus everything the call site knows about the reference it was building.
|
|
191
|
+
* @returns The `CliError` to throw, or the original `CliError` when the failure was already named.
|
|
192
|
+
*/
|
|
193
|
+
export declare function cliFirestoreWiringError(input: CliFirestoreWiringErrorInput): Error;
|
|
@@ -8,6 +8,7 @@ export * from './firestore.models';
|
|
|
8
8
|
export * from './firestore.query';
|
|
9
9
|
export * from './firestore.query-params';
|
|
10
10
|
export * from './firestore.read';
|
|
11
|
+
export * from './firestore.sdk-identity';
|
|
11
12
|
export * from './firestore.session';
|
|
12
13
|
export * from './query-info-utils';
|
|
13
14
|
export * from './query-mode';
|
|
@@ -788,3 +788,24 @@ export interface CliFirestoreQueryManifestEntry {
|
|
|
788
788
|
* The generated per-model Firestore query catalog.
|
|
789
789
|
*/
|
|
790
790
|
export type CliFirestoreQueryManifest = readonly CliFirestoreQueryManifestEntry[];
|
|
791
|
+
/**
|
|
792
|
+
* The generator provenance a generated manifest module carries alongside its catalog.
|
|
793
|
+
*
|
|
794
|
+
* Emitted as `<NAMESPACE>_STAMP` by the manifest generators and wired into `runCli` as
|
|
795
|
+
* `manifestGeneratorVersion`. Exists because a generated manifest is the one build output that can go
|
|
796
|
+
* stale WITHOUT breaking the build: it is committed TypeScript, so a manifest emitted by an older
|
|
797
|
+
* generator still compiles and still type-checks against a newer runtime — it just quietly lacks the
|
|
798
|
+
* fields that runtime reads. `queryMode` / `rules` were exactly that, and the resulting
|
|
799
|
+
* `queryModesScanned: false` sat in `doctor` output unread while the direct-Firestore path was being
|
|
800
|
+
* debugged from the wrong end.
|
|
801
|
+
*
|
|
802
|
+
* Version only, deliberately no timestamp: the generators skip a write when the bytes are unchanged
|
|
803
|
+
* so incremental builds preserve mtimes, and a timestamp would rewrite the file — and its git
|
|
804
|
+
* history — on every build.
|
|
805
|
+
*/
|
|
806
|
+
export interface CliGeneratedManifestStamp {
|
|
807
|
+
/**
|
|
808
|
+
* The `@dereekb/dbx-cli` version of the generator that emitted the module.
|
|
809
|
+
*/
|
|
810
|
+
readonly generatorVersion: string;
|
|
811
|
+
}
|
|
@@ -106,7 +106,7 @@ export declare const CssUtilityEntry: import("arktype/internal/variants/object.t
|
|
|
106
106
|
property: string;
|
|
107
107
|
value: string;
|
|
108
108
|
}[];
|
|
109
|
-
role?: "color" | "
|
|
109
|
+
role?: "color" | "state" | "text" | "size" | "layout" | "misc" | "flex" | "spacing" | "interaction" | "text-color" | "surface" | "radius" | undefined;
|
|
110
110
|
intent?: string | undefined;
|
|
111
111
|
seeAlso?: string[] | undefined;
|
|
112
112
|
antiUse?: string | undefined;
|
|
@@ -149,7 +149,7 @@ export declare const CssUtilityManifest: import("arktype/internal/variants/objec
|
|
|
149
149
|
property: string;
|
|
150
150
|
value: string;
|
|
151
151
|
}[];
|
|
152
|
-
role?: "color" | "
|
|
152
|
+
role?: "color" | "state" | "text" | "size" | "layout" | "misc" | "flex" | "spacing" | "interaction" | "text-color" | "surface" | "radius" | undefined;
|
|
153
153
|
intent?: string | undefined;
|
|
154
154
|
seeAlso?: string[] | undefined;
|
|
155
155
|
antiUse?: string | undefined;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { type Maybe } from '@dereekb/util';
|
|
2
|
+
/**
|
|
3
|
+
* The `@dereekb/*` package prefix the drift check compares. Only framework packages are checked —
|
|
4
|
+
* a third-party range like `firebase: ^12.12.1` is deliberately out of scope.
|
|
5
|
+
*/
|
|
6
|
+
export declare const CLI_FRAMEWORK_PACKAGE_PREFIX = "@dereekb/";
|
|
7
|
+
/**
|
|
8
|
+
* The artifact `package.json` a built CLI ships beside its entry file.
|
|
9
|
+
*
|
|
10
|
+
* `@nx/esbuild` copies the project's `package.json` verbatim into the output directory, so its
|
|
11
|
+
* exact-pinned `@dereekb/*` peer versions ARE the build stamp — the dependency tree the bundle was
|
|
12
|
+
* compiled against — with no extra build-time codegen to keep in sync.
|
|
13
|
+
*/
|
|
14
|
+
export interface CliArtifactPackage {
|
|
15
|
+
/**
|
|
16
|
+
* Absolute path the stamp was read from, reported so an operator can see WHICH artifact is running.
|
|
17
|
+
*/
|
|
18
|
+
readonly path: string;
|
|
19
|
+
readonly name?: Maybe<string>;
|
|
20
|
+
readonly version?: Maybe<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Every exact-pinned `@dereekb/*` version the artifact declares, from `peerDependencies` and
|
|
23
|
+
* `dependencies` combined.
|
|
24
|
+
*/
|
|
25
|
+
readonly frameworkVersions: Readonly<Record<string, string>>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* One framework package whose built-against version differs from the version resolved at run time.
|
|
29
|
+
*/
|
|
30
|
+
export interface CliFrameworkVersionDrift {
|
|
31
|
+
readonly packageName: string;
|
|
32
|
+
readonly builtAgainst: string;
|
|
33
|
+
/**
|
|
34
|
+
* The version resolved from `node_modules` now, or `undefined` when the package is not installed.
|
|
35
|
+
*/
|
|
36
|
+
readonly resolved?: Maybe<string>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Why {@link inspectCliBuildDrift} could not compare anything. A report with a `reason` is `ok`: an
|
|
40
|
+
* undetectable stamp is not evidence of drift.
|
|
41
|
+
*/
|
|
42
|
+
export type CliBuildDriftUndeterminedReason = 'no-entry-path' | 'no-artifact-package' | 'no-framework-versions-declared'
|
|
43
|
+
/**
|
|
44
|
+
* The artifact declares framework versions but NOT ONE of them resolves from `node_modules` — the
|
|
45
|
+
* signature of running from SOURCE through a workspace's tsconfig paths (a monorepo dev run), where
|
|
46
|
+
* there is no installed framework to drift from. Reporting every package as "not installed" here
|
|
47
|
+
* would make the check red on every dev run, and a check that is red by default gets ignored.
|
|
48
|
+
*/
|
|
49
|
+
| 'framework-not-resolvable';
|
|
50
|
+
/**
|
|
51
|
+
* The verdict on whether the running artifact matches the dependency tree it was built against.
|
|
52
|
+
*/
|
|
53
|
+
export interface CliBuildDriftReport {
|
|
54
|
+
readonly ok: boolean;
|
|
55
|
+
readonly reason?: Maybe<CliBuildDriftUndeterminedReason>;
|
|
56
|
+
readonly artifactPackagePath?: Maybe<string>;
|
|
57
|
+
readonly artifactVersion?: Maybe<string>;
|
|
58
|
+
/**
|
|
59
|
+
* How many framework packages were actually comparable.
|
|
60
|
+
*/
|
|
61
|
+
readonly checked: number;
|
|
62
|
+
readonly drift: readonly CliFrameworkVersionDrift[];
|
|
63
|
+
/**
|
|
64
|
+
* The `@dereekb/dbx-cli` version that emitted the CLI's generated manifests, when the app passed
|
|
65
|
+
* one through.
|
|
66
|
+
*/
|
|
67
|
+
readonly manifestGeneratorVersion?: Maybe<string>;
|
|
68
|
+
/**
|
|
69
|
+
* The `@dereekb/dbx-cli` version resolved at run time.
|
|
70
|
+
*/
|
|
71
|
+
readonly resolvedDbxCliVersion?: Maybe<string>;
|
|
72
|
+
/**
|
|
73
|
+
* True when the manifests were generated by a DIFFERENT `@dereekb/dbx-cli` than the one now
|
|
74
|
+
* running them. This is the half the peer-version comparison cannot see: bumping the app's declared
|
|
75
|
+
* peers without re-running the generators leaves the committed manifests behind, which is how a
|
|
76
|
+
* manifest silently lost fields the runtime reads (`queryModesScanned: false` was this, unread).
|
|
77
|
+
*/
|
|
78
|
+
readonly manifestGeneratorDrift: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Input for {@link inspectCliBuildDrift}.
|
|
82
|
+
*/
|
|
83
|
+
export interface InspectCliBuildDriftInput {
|
|
84
|
+
/**
|
|
85
|
+
* The executed entry file. Defaults to `process.argv[1]`.
|
|
86
|
+
*/
|
|
87
|
+
readonly entryPath?: Maybe<string>;
|
|
88
|
+
/**
|
|
89
|
+
* The generator version stamped into the app's generated manifests
|
|
90
|
+
* (`<NAMESPACE>_STAMP.generatorVersion`), when the app wires one.
|
|
91
|
+
*/
|
|
92
|
+
readonly manifestGeneratorVersion?: Maybe<string>;
|
|
93
|
+
/**
|
|
94
|
+
* Test seam: use this artifact stamp instead of discovering one from {@link entryPath}.
|
|
95
|
+
*/
|
|
96
|
+
readonly artifactPackage?: Maybe<CliArtifactPackage>;
|
|
97
|
+
/**
|
|
98
|
+
* Test seam: resolves a package's installed version. Defaults to resolving each package's
|
|
99
|
+
* `package.json` through `createRequire`.
|
|
100
|
+
*/
|
|
101
|
+
readonly resolveVersion?: (packageName: string) => Maybe<string>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Compares the `@dereekb/*` versions the running artifact was BUILT against with the versions
|
|
105
|
+
* resolved from `node_modules` now.
|
|
106
|
+
*
|
|
107
|
+
* This is the check whose absence turns a routine `@dereekb/*` bump into an unreadable runtime
|
|
108
|
+
* failure. A CLI built with `thirdParty: false` inlines its app code and resolves the framework at
|
|
109
|
+
* RUN time, so the artifact is only valid against the tree it was compiled against — and nothing
|
|
110
|
+
* else in the toolchain notices when that stops being true. The symptom is arbitrary: an SDK
|
|
111
|
+
* assertion, a missing manifest field, a silently-empty result.
|
|
112
|
+
*
|
|
113
|
+
* Deliberately conservative. Only exact-pinned `@dereekb/*` versions are compared, and every way the
|
|
114
|
+
* comparison can fail to apply produces `ok: true` with a {@link CliBuildDriftUndeterminedReason} —
|
|
115
|
+
* a check that cried wolf on every source-run CLI would be turned off, and then it would be useless
|
|
116
|
+
* on the day it mattered.
|
|
117
|
+
*
|
|
118
|
+
* @param input - The entry path, the manifest generator stamp, and the test seams.
|
|
119
|
+
* @returns The drift verdict.
|
|
120
|
+
*/
|
|
121
|
+
export declare function inspectCliBuildDrift(input?: InspectCliBuildDriftInput): CliBuildDriftReport;
|
|
122
|
+
/**
|
|
123
|
+
* Renders a {@link CliBuildDriftReport} as one operator-facing line, for `--version` and for a
|
|
124
|
+
* doctor suggestion.
|
|
125
|
+
*
|
|
126
|
+
* @param report - The report to describe.
|
|
127
|
+
* @returns The description, or `undefined` when there is nothing to say.
|
|
128
|
+
*
|
|
129
|
+
* @__NO_SIDE_EFFECTS__
|
|
130
|
+
*/
|
|
131
|
+
export declare function cliBuildDriftDescription(report: CliBuildDriftReport): Maybe<string>;
|
|
132
|
+
/**
|
|
133
|
+
* Finds and parses the artifact `package.json` nearest the executed entry file.
|
|
134
|
+
*
|
|
135
|
+
* @param entryPath - The executed entry file (`process.argv[1]`).
|
|
136
|
+
* @returns The parsed stamp, or `undefined` when none could be read.
|
|
137
|
+
*/
|
|
138
|
+
export declare function readCliArtifactPackage(entryPath: string): Maybe<CliArtifactPackage>;
|
package/src/lib/runner/run.d.ts
CHANGED
|
@@ -146,6 +146,17 @@ export interface CreateCliInput extends CliLifecycleHooks {
|
|
|
146
146
|
* bundler `define` or a generated module).
|
|
147
147
|
*/
|
|
148
148
|
readonly version?: string;
|
|
149
|
+
/**
|
|
150
|
+
* The `@dereekb/dbx-cli` version that emitted this CLI's generated manifests — pass
|
|
151
|
+
* `<NAMESPACE>_STAMP.generatorVersion` from a generated manifest module.
|
|
152
|
+
*
|
|
153
|
+
* Wiring it turns the built-in `cli-build-not-stale` doctor check from "the artifact's declared
|
|
154
|
+
* peers match `node_modules`" into "…and the committed manifests were generated by that same
|
|
155
|
+
* version", which is the half the peer comparison cannot see: bumping `@dereekb/*` and rebuilding
|
|
156
|
+
* without re-running the generators leaves the manifests behind, and a manifest missing a field the
|
|
157
|
+
* runtime reads degrades silently rather than failing.
|
|
158
|
+
*/
|
|
159
|
+
readonly manifestGeneratorVersion?: string;
|
|
149
160
|
/**
|
|
150
161
|
* The lifecycle runner guarding this invocation's {@link CliLifecycleHooks}.
|
|
151
162
|
*
|
|
@@ -188,6 +199,8 @@ export interface CreateCliInput extends CliLifecycleHooks {
|
|
|
188
199
|
* if {@link CreateCliInput.modelManifest} is provided.
|
|
189
200
|
* @param input.firestore - The app-supplied direct-Firestore binding; enables `firestore-get` / `firestore-query`.
|
|
190
201
|
* @param input.firestoreQueryManifest - The generated Firestore query catalog; enables `firestore-queries`.
|
|
202
|
+
* @param input.manifestGeneratorVersion - The `@dereekb/dbx-cli` version that emitted the app's generated
|
|
203
|
+
* manifests, for the built-in `cli-build-not-stale` doctor check.
|
|
191
204
|
* @param input.setup - App hook run once before the command's handler; a throw aborts the command.
|
|
192
205
|
* @param input.teardown - App hook run once after the parser settles, before the Firestore session closes.
|
|
193
206
|
* Only {@link runCli} runs it — a caller that drives `createCli().parse()` itself owns its own teardown.
|
package/test/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli/test",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.43.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"peerDependencies": {
|
|
6
|
-
"@dereekb/date": "13.
|
|
7
|
-
"@dereekb/dbx-cli": "13.
|
|
8
|
-
"@dereekb/firebase": "13.
|
|
9
|
-
"@dereekb/firebase-server/test": "13.
|
|
10
|
-
"@dereekb/model": "13.
|
|
11
|
-
"@dereekb/nestjs": "13.
|
|
12
|
-
"@dereekb/rxjs": "13.
|
|
13
|
-
"@dereekb/util": "13.
|
|
6
|
+
"@dereekb/date": "13.43.0",
|
|
7
|
+
"@dereekb/dbx-cli": "13.43.0",
|
|
8
|
+
"@dereekb/firebase": "13.43.0",
|
|
9
|
+
"@dereekb/firebase-server/test": "13.43.0",
|
|
10
|
+
"@dereekb/model": "13.43.0",
|
|
11
|
+
"@dereekb/nestjs": "13.43.0",
|
|
12
|
+
"@dereekb/rxjs": "13.43.0",
|
|
13
|
+
"@dereekb/util": "13.43.0",
|
|
14
14
|
"@nestjs/common": "^11.1.19",
|
|
15
15
|
"arktype": "^2.2.0",
|
|
16
16
|
"vitest": "4.1.5",
|
package/validate/index.js
CHANGED
|
@@ -6335,6 +6335,11 @@ var RESERVED_MODEL_FOLDERS = [
|
|
|
6335
6335
|
reason: "StorageFile is a canonical group from `@dereekb/firebase` with a richer layout than the base 5 files (group, upload, file, etc.); downstream projects extend rather than redeclare it.",
|
|
6336
6336
|
recommendedTool: "dbx_storagefile_m_validate_folder"
|
|
6337
6337
|
},
|
|
6338
|
+
{
|
|
6339
|
+
name: "formspace",
|
|
6340
|
+
reason: "FormSpace is a canonical group from `@dereekb/firebase` with a richer layout than the base 5 files (type, upload, task, util, etc.); a downstream project only registers its own types and does not redeclare the model.",
|
|
6341
|
+
recommendedTool: "dbx_model_validate_folder"
|
|
6342
|
+
},
|
|
6338
6343
|
{
|
|
6339
6344
|
name: "calendar",
|
|
6340
6345
|
reason: "Calendar is a canonical group from `@dereekb/firebase` with a richer layout than the base 5 files (type, expand, ics, processing, etc.); downstream projects extend rather than redeclare it.",
|