@dereekb/dbx-cli 14.3.0 → 14.5.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 +5 -7
- package/firebase-api-manifest/package.json +5 -7
- 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 +1356 -1147
- package/lint-cache/package.json +2 -2
- package/manifest-extract/package.json +12 -8
- package/model-test/package.json +2 -2
- package/package.json +10 -7
- package/route/package.json +8 -7
- package/src/lib/api/firestore-session.client.d.ts +21 -27
- package/src/lib/auth/auth.command.factory.d.ts +28 -2
- package/src/lib/auth/cli-handoff.client.d.ts +62 -0
- package/src/lib/auth/index.d.ts +1 -0
- package/src/lib/config/cli.config.d.ts +8 -0
- package/src/lib/config/env.d.ts +13 -60
- package/src/lib/config/firestore-session.cache.d.ts +20 -49
- package/src/lib/firestore/firestore.sdk-identity.d.ts +24 -104
- package/src/lib/firestore/firestore.session.d.ts +19 -64
- package/src/lib/mcp-scan/scan/index.d.ts +1 -0
- package/src/lib/mcp-scan/scan/model-snapshot-fields-build-manifest.d.ts +6 -0
- package/src/lib/mcp-scan/scan/sanitize-type-text.d.ts +44 -0
- package/src/lib/mcp-scan/scan/utils-build-manifest.d.ts +6 -0
- package/test/package.json +10 -9
- package/validate/package.json +3 -3
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { type FirestoreModelKey, type FirestoreModelType } from '@dereekb/firebase';
|
|
2
2
|
import { type Maybe } from '@dereekb/util';
|
|
3
|
+
import { type FirebaseClientFirestoreIdentityContext, type FirebaseClientFirestoreIdentityProblem, type FirebaseClientFirestoreIdentityReport, type FirebaseClientFirestoreSdkModuleIdentity } from '@dereekb/oauth-resource/firebase';
|
|
3
4
|
/**
|
|
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.
|
|
5
|
+
* The `drivers.firestoreDriverIdentifier` a client-SDK `FirestoreContext` reports. See
|
|
6
|
+
* {@link CLIENT_FIRESTORE_DRIVER_IDENTIFIER}.
|
|
10
7
|
*/
|
|
11
8
|
export declare const CLI_CLIENT_FIRESTORE_DRIVER_IDENTIFIER = "@firebase/firestore";
|
|
12
9
|
/**
|
|
@@ -22,94 +19,31 @@ export declare const FIRESTORE_SDK_IDENTITY_STAGE = "firestore-sdk-identity";
|
|
|
22
19
|
*/
|
|
23
20
|
export declare const FIRESTORE_SDK_INSTANCE_MISMATCH_CODE = "FIRESTORE_SDK_INSTANCE_MISMATCH";
|
|
24
21
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
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.
|
|
22
|
+
* `CliError` code for a collection/document reference the SDK refused to build for a reason the
|
|
23
|
+
* wiring identity check cannot explain — a bad `--parent`, or an app collection whose own
|
|
24
|
+
* construction is broken.
|
|
44
25
|
*/
|
|
45
|
-
|
|
26
|
+
export declare const FIRESTORE_COLLECTION_UNRESOLVABLE_CODE = "FIRESTORE_COLLECTION_UNRESOLVABLE";
|
|
46
27
|
/**
|
|
47
|
-
* The
|
|
48
|
-
*
|
|
28
|
+
* The distinct ways a session's Firestore handle can be unusable. See
|
|
29
|
+
* {@link FirebaseClientFirestoreIdentityProblem}.
|
|
49
30
|
*/
|
|
50
|
-
|
|
31
|
+
export type CliFirestoreSdkIdentityProblem = FirebaseClientFirestoreIdentityProblem;
|
|
51
32
|
/**
|
|
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.
|
|
33
|
+
* Where one consumer resolved `@firebase/firestore` to, and at which version. See
|
|
34
|
+
* {@link FirebaseClientFirestoreSdkModuleIdentity}.
|
|
56
35
|
*/
|
|
57
|
-
export
|
|
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
|
-
}
|
|
36
|
+
export type CliFirestoreSdkModuleIdentity = FirebaseClientFirestoreSdkModuleIdentity;
|
|
68
37
|
/**
|
|
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.
|
|
38
|
+
* The provenance + brand-check report {@link inspectCliFirestoreSdkIdentity} produces. See
|
|
39
|
+
* {@link FirebaseClientFirestoreIdentityReport}.
|
|
73
40
|
*/
|
|
74
|
-
export
|
|
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
|
-
}
|
|
41
|
+
export type CliFirestoreSdkIdentityReport = FirebaseClientFirestoreIdentityReport;
|
|
100
42
|
/**
|
|
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.
|
|
43
|
+
* The slice of a session context {@link inspectCliFirestoreSdkIdentity} reads. See
|
|
44
|
+
* {@link FirebaseClientFirestoreIdentityContext}.
|
|
106
45
|
*/
|
|
107
|
-
export
|
|
108
|
-
readonly firestore?: unknown;
|
|
109
|
-
readonly drivers?: {
|
|
110
|
-
readonly firestoreDriverIdentifier?: unknown;
|
|
111
|
-
};
|
|
112
|
-
}
|
|
46
|
+
export type CliFirestoreSdkIdentityContext = FirebaseClientFirestoreIdentityContext;
|
|
113
47
|
/**
|
|
114
48
|
* Input for {@link inspectCliFirestoreSdkIdentity}.
|
|
115
49
|
*/
|
|
@@ -117,20 +51,12 @@ export interface InspectCliFirestoreSdkIdentityInput {
|
|
|
117
51
|
readonly firestoreContext?: Maybe<CliFirestoreSdkIdentityContext>;
|
|
118
52
|
}
|
|
119
53
|
/**
|
|
120
|
-
* Checks that a session's Firestore handle is one
|
|
121
|
-
*
|
|
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.
|
|
54
|
+
* Checks that a session's Firestore handle is one the loaded client SDK will accept, and reports
|
|
55
|
+
* where every consumer resolved the SDK from.
|
|
128
56
|
*
|
|
129
|
-
* The
|
|
130
|
-
*
|
|
131
|
-
*
|
|
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.)
|
|
57
|
+
* The CLI wrapper over {@link inspectFirebaseClientFirestoreIdentity}: it supplies this package's own
|
|
58
|
+
* `require` as the resolution root and names the CLI in the report, so `doctor`'s output is unchanged
|
|
59
|
+
* by the move of the inspection core into `@dereekb/oauth-resource/firebase`.
|
|
134
60
|
*
|
|
135
61
|
* @param input - The session's `firestoreContext`, when one was built.
|
|
136
62
|
* @returns The provenance + brand-check report.
|
|
@@ -149,12 +75,6 @@ export declare function inspectCliFirestoreSdkIdentity(input: InspectCliFirestor
|
|
|
149
75
|
* @__NO_SIDE_EFFECTS__
|
|
150
76
|
*/
|
|
151
77
|
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
78
|
/**
|
|
159
79
|
* Input for {@link cliFirestoreWiringError}.
|
|
160
80
|
*/
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type Auth } from 'firebase/auth';
|
|
3
|
-
import { type Firestore } from 'firebase/firestore';
|
|
4
|
-
import { type FirestoreContext } from '@dereekb/firebase';
|
|
1
|
+
import { type FirebaseUserSession } from '@dereekb/oauth-resource/firebase';
|
|
5
2
|
import { type CliFirestoreSession } from '../api/firestore-session.client';
|
|
6
3
|
import { type CliEnvConfig } from '../config/env';
|
|
7
4
|
import { type CliFirestoreSessionCacheStore } from '../config/firestore-session.cache';
|
|
@@ -9,25 +6,23 @@ import { type CliFirestoreSessionCacheStore } from '../config/firestore-session.
|
|
|
9
6
|
* A live direct-Firestore session: the Firebase client objects the CLI signed in with, plus the
|
|
10
7
|
* `FirestoreContext` an app's collections factory consumes.
|
|
11
8
|
*
|
|
9
|
+
* The CLI's view of {@link FirebaseUserSession}, whose implementation lives in
|
|
10
|
+
* `@dereekb/oauth-resource/firebase` so any resource server that verified a bearer token carrying the
|
|
11
|
+
* `session.firestore` scope gets the same bridge.
|
|
12
|
+
*
|
|
12
13
|
* The `firestoreContext` is built by `clientFirebaseFirestoreContextFactory`, the exact analogue of
|
|
13
14
|
* the server's `googleCloudFirestoreContextFactory` — both satisfy `FirestoreContextFactory` — so an
|
|
14
15
|
* app's `make<App>FirestoreCollections(context)` accepts it unchanged, and the CLI runs the SAME
|
|
15
16
|
* queries the Angular app runs, through the SAME security rules.
|
|
16
17
|
*/
|
|
17
|
-
export interface CliFirestoreSessionContext {
|
|
18
|
+
export interface CliFirestoreSessionContext extends FirebaseUserSession {
|
|
18
19
|
/**
|
|
19
20
|
* The credential bundle the API minted for this session.
|
|
21
|
+
*
|
|
22
|
+
* The CLI's long-standing name for {@link FirebaseUserSession.credentials}; both name the same
|
|
23
|
+
* object.
|
|
20
24
|
*/
|
|
21
25
|
readonly session: CliFirestoreSession;
|
|
22
|
-
/**
|
|
23
|
-
* True when {@link session} came from the on-disk session cache rather than a fresh
|
|
24
|
-
* `GET /session/firestore`. Surfaced for `doctor` and `--verbose`, not for control flow.
|
|
25
|
-
*/
|
|
26
|
-
readonly fromCache: boolean;
|
|
27
|
-
readonly app: FirebaseApp;
|
|
28
|
-
readonly auth: Auth;
|
|
29
|
-
readonly firestore: Firestore;
|
|
30
|
-
readonly firestoreContext: FirestoreContext;
|
|
31
26
|
}
|
|
32
27
|
export interface CreateCliFirestoreSessionContextInput {
|
|
33
28
|
readonly cliName: string;
|
|
@@ -49,39 +44,15 @@ export interface CreateCliFirestoreSessionContextInput {
|
|
|
49
44
|
*/
|
|
50
45
|
readonly refreshSession?: boolean;
|
|
51
46
|
}
|
|
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;
|
|
66
47
|
/**
|
|
67
48
|
* Opens a direct Firestore connection as the authenticated CLI user.
|
|
68
49
|
*
|
|
69
|
-
*
|
|
50
|
+
* A thin wrapper over `openFirebaseUserSession`: it validates the env's Firebase client config with
|
|
51
|
+
* the CLI's own env-var-naming remediation, then delegates. The strict step ORDER (mint → fresh app →
|
|
52
|
+
* App Check FIRST → emulator wiring → sign-in) and its reasoning live with the implementation.
|
|
70
53
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* the ceiling the Firebase credentials themselves sit under. A hit skips step 1 only — the
|
|
74
|
-
* Firebase app is per-process, so the sign-in in step 5 always runs.
|
|
75
|
-
* 1. `GET <apiBaseUrl>/session/firestore` for a custom token + App Check attestation.
|
|
76
|
-
* 2. `initializeApp` with the env's Firebase client config.
|
|
77
|
-
* 3. `initializeAppCheck` with a `CustomProvider` handing back the server-minted token. **This must
|
|
78
|
-
* happen before any other Firebase call** — `dbx-firebase`'s provider documents the same
|
|
79
|
-
* constraint: "App Check must be initialized before any Firebase request goes out, otherwise
|
|
80
|
-
* requests are sent without an App Check token and are rejected in production." Skipped when the
|
|
81
|
-
* env targets emulators (which do not verify attestations) or when the API minted no token.
|
|
82
|
-
* 4. `getAuth` / `getFirestore`, connecting each to its emulator when configured.
|
|
83
|
-
* 5. `signInWithCustomToken`. The user's stored custom claims land at the top level of the exchanged
|
|
84
|
-
* ID token, so `request.auth.token.<claim>` reads in security rules behave exactly as in the app.
|
|
54
|
+
* The session's Firebase app is named `<cliName>::<envName>::<uid>`, so
|
|
55
|
+
* {@link closeAllCliFirebaseApps} finds every app this CLI opened from the name alone.
|
|
85
56
|
*
|
|
86
57
|
* There is deliberately NO fallback to the HTTP model API — a failure here throws so the operator
|
|
87
58
|
* sees it. `createFirestoreSessionDoctorCheck` is the diagnostic surface for why.
|
|
@@ -96,15 +67,7 @@ export declare function createCliFirestoreSessionContext(input: CreateCliFiresto
|
|
|
96
67
|
*
|
|
97
68
|
* Required for the CLI to EXIT. A signed-in `Auth` and a live `Firestore` both hold open handles
|
|
98
69
|
* that keep the Node event loop alive indefinitely, so without this a command prints its result and
|
|
99
|
-
* then hangs forever — the process never returns to the shell.
|
|
100
|
-
* enough to want that: a session is opened for one invocation and is dead weight afterwards.
|
|
101
|
-
*
|
|
102
|
-
* `deleteApp` is the single call that covers it — it disposes every registered component, which for
|
|
103
|
-
* Firestore runs the same shutdown `terminate()` does, and for Auth stops the token-refresh timer.
|
|
104
|
-
*
|
|
105
|
-
* Deliberately tolerant: teardown runs in a `finally` after the command has already produced its
|
|
106
|
-
* output, so a failure here must not change the exit code or mask the real result. A session that
|
|
107
|
-
* was never opened is a no-op.
|
|
70
|
+
* then hangs forever — the process never returns to the shell.
|
|
108
71
|
*
|
|
109
72
|
* @param session - The session context to close.
|
|
110
73
|
*/
|
|
@@ -112,23 +75,15 @@ export declare function closeCliFirestoreSessionContext(session: CliFirestoreSes
|
|
|
112
75
|
/**
|
|
113
76
|
* Deletes every still-live Firebase app this CLI opened, whether or not a session was handed back.
|
|
114
77
|
*
|
|
115
|
-
* The CLI's last line of defence against a hang.
|
|
116
|
-
* path, but it needs a session to be handed to it, and three cases never produce one:
|
|
78
|
+
* The CLI's last line of defence against a hang. {@link closeCliFirestoreSessionContext} covers the
|
|
79
|
+
* normal path, but it needs a session to be handed to it, and three cases never produce one:
|
|
117
80
|
*
|
|
118
|
-
* - a handshake that fails AFTER `initializeApp` — a
|
|
119
|
-
*
|
|
81
|
+
* - a handshake that fails AFTER `initializeApp` — a failed App Check registration, a broken emulator
|
|
82
|
+
* connection — throws, so the caller that catches it has an initialized app and no session;
|
|
120
83
|
* - a caller that opens its own session outside the context memo (the doctor probe) owns its own
|
|
121
84
|
* teardown, and forgetting it hangs the process;
|
|
122
85
|
* - a {@link CliContext} orphaned mid-invocation carries the only reference to its session memo.
|
|
123
86
|
*
|
|
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
87
|
* @param input - The function inputs.
|
|
133
88
|
* @param input.cliName - The CLI whose apps should be closed. Apps belonging to other Firebase
|
|
134
89
|
* consumers in the same process are left alone.
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
export * from './scan-config-schema.js';
|
|
10
10
|
export * from './extract.js';
|
|
11
11
|
export * from './build-manifest.js';
|
|
12
|
+
export * from './sanitize-type-text.js';
|
|
12
13
|
export * from './cli.js';
|
|
13
14
|
export * from './filters-cli.js';
|
|
14
15
|
export * from './filters-extract.js';
|
|
@@ -26,6 +26,12 @@ export type BuildModelSnapshotFieldsGlobber = ScanGlobber;
|
|
|
26
26
|
export interface BuildModelSnapshotFieldsManifestInput {
|
|
27
27
|
readonly projectRoot: string;
|
|
28
28
|
readonly generator: string;
|
|
29
|
+
/**
|
|
30
|
+
* Absolute workspace root that absolute paths baked into type text are made
|
|
31
|
+
* relative to. Defaults to `process.cwd()`, which is the workspace root because
|
|
32
|
+
* the generate-* targets all run with `cwd: {workspaceRoot}`.
|
|
33
|
+
*/
|
|
34
|
+
readonly workspaceRoot?: string;
|
|
29
35
|
readonly now?: () => Date;
|
|
30
36
|
readonly readFile?: BuildModelSnapshotFieldsReadFile;
|
|
31
37
|
readonly globber?: BuildModelSnapshotFieldsGlobber;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Makes ts-morph type text reproducible across checkouts.
|
|
3
|
+
*
|
|
4
|
+
* TypeScript emits `import("<absolute path>").Type` for any type it cannot name
|
|
5
|
+
* from the enclosing scope, and ts-morph surfaces that text verbatim. The path is
|
|
6
|
+
* machine-specific: it is the host checkout on a developer's machine and `/code`
|
|
7
|
+
* inside the build container's bind mount.
|
|
8
|
+
*
|
|
9
|
+
* That difference is not cosmetic. The generated manifests are tracked files under
|
|
10
|
+
* `packages/dbx-cli/generated`, which is inside `dbx-cli`'s project root, and the
|
|
11
|
+
* workspace's `default` named input is `{projectRoot}/**\/*`. So an absolute path
|
|
12
|
+
* baked into a manifest invalidates the Nx cache for `dbx-cli` — and everything
|
|
13
|
+
* downstream of it — on every alternation between a host build and a container
|
|
14
|
+
* build, and leaves the git tree permanently dirty.
|
|
15
|
+
*
|
|
16
|
+
* Rewriting the path to be workspace-relative makes the emitted bytes identical
|
|
17
|
+
* everywhere the workspace is checked out.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Input to {@link sanitizeTypeText}.
|
|
21
|
+
*/
|
|
22
|
+
export interface SanitizeTypeTextInput {
|
|
23
|
+
/**
|
|
24
|
+
* Type text as reported by the type checker, possibly containing one or more
|
|
25
|
+
* `import("<absolute path>")` segments.
|
|
26
|
+
*/
|
|
27
|
+
readonly typeText: string;
|
|
28
|
+
/**
|
|
29
|
+
* Absolute path to the workspace root that emitted paths are made relative to.
|
|
30
|
+
*/
|
|
31
|
+
readonly workspaceRoot: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Rewrites every absolute `import("…")` path in `typeText` to a workspace-relative,
|
|
35
|
+
* forward-slashed path.
|
|
36
|
+
*
|
|
37
|
+
* Paths that are already relative, or that resolve outside `workspaceRoot`, are left
|
|
38
|
+
* untouched — there is no stable shorter form for them, and rewriting to a `../`
|
|
39
|
+
* chain would reintroduce the machine dependence this exists to remove.
|
|
40
|
+
*
|
|
41
|
+
* @param input - The type text and the workspace root to relativize against.
|
|
42
|
+
* @returns The type text with workspace-internal absolute paths relativized.
|
|
43
|
+
*/
|
|
44
|
+
export declare function sanitizeTypeText(input: SanitizeTypeTextInput): string;
|
|
@@ -25,6 +25,12 @@ export type BuildUtilsGlobber = ScanGlobber;
|
|
|
25
25
|
export interface BuildUtilsManifestInput {
|
|
26
26
|
readonly projectRoot: string;
|
|
27
27
|
readonly generator: string;
|
|
28
|
+
/**
|
|
29
|
+
* Absolute workspace root that absolute paths baked into type text are made
|
|
30
|
+
* relative to. Defaults to `process.cwd()`, which is the workspace root because
|
|
31
|
+
* the generate-* targets all run with `cwd: {workspaceRoot}`.
|
|
32
|
+
*/
|
|
33
|
+
readonly workspaceRoot?: string;
|
|
28
34
|
readonly now?: () => Date;
|
|
29
35
|
readonly readFile?: BuildUtilsReadFile;
|
|
30
36
|
readonly globber?: BuildUtilsGlobber;
|
package/test/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli/test",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.5.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"peerDependencies": {
|
|
7
|
-
"@dereekb/date": "14.
|
|
8
|
-
"@dereekb/dbx-cli": "14.
|
|
9
|
-
"@dereekb/firebase": "14.
|
|
10
|
-
"@dereekb/firebase-server/test": "14.
|
|
11
|
-
"@dereekb/model": "14.
|
|
12
|
-
"@dereekb/nestjs": "14.
|
|
13
|
-
"@dereekb/
|
|
14
|
-
"@dereekb/
|
|
7
|
+
"@dereekb/date": "14.5.0",
|
|
8
|
+
"@dereekb/dbx-cli": "14.5.0",
|
|
9
|
+
"@dereekb/firebase": "14.5.0",
|
|
10
|
+
"@dereekb/firebase-server/test": "14.4.0",
|
|
11
|
+
"@dereekb/model": "14.5.0",
|
|
12
|
+
"@dereekb/nestjs": "14.5.0",
|
|
13
|
+
"@dereekb/oauth-resource": "14.5.0",
|
|
14
|
+
"@dereekb/rxjs": "14.5.0",
|
|
15
|
+
"@dereekb/util": "14.5.0",
|
|
15
16
|
"@nestjs/common": "^12.0.1",
|
|
16
17
|
"arktype": "^2.2.0",
|
|
17
18
|
"vitest": "4.1.11",
|
package/validate/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-cli/validate",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|
|
7
|
-
"@dereekb/dbx-cli": "14.
|
|
8
|
-
"@dereekb/util": "14.
|
|
7
|
+
"@dereekb/dbx-cli": "14.5.0",
|
|
8
|
+
"@dereekb/util": "14.5.0",
|
|
9
9
|
"ts-morph": "^28.0.0"
|
|
10
10
|
}
|
|
11
11
|
}
|