pyric-admin 0.1.0-alpha.8 → 0.1.0-alpha.9

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.
@@ -1,158 +1,47 @@
1
1
  /**
2
- * `pyric-admin/app` — Phase 3 initializeApp surface (ADR-001 D6) plus the
3
- * default-app registry and AMBIENT INIT (adoption experience, layer 3).
2
+ * `pyric-admin/app` — sandbox-only admin app registry.
4
3
  *
5
- * Mirror shape: at cutover this becomes `pyric-admin/app` and is the
6
- * single entry point where the sandbox-vs-prod choice is made for the
7
- * admin surface. Every `pyric-admin/*` subpath inspects the handle's
8
- * brand for backend dispatch.
9
- *
10
- * Current shadow scope:
11
- * - `initializeApp({ credential, ... })` — prod-backed (live;
12
- * delegates to `firebase-admin/app.initializeApp`).
13
- * - `initializeApp({ sandbox })` — sandbox-backed (live).
14
- * - `initializeApp()` — BARE, zero pyric identifiers in app code. The
15
- * environment decides the backend (see "Ambient init" below).
16
- * - Per-subpath adapter dispatch via the brand: implemented in
17
- * `pyric-admin/{auth,database,storage}` via structural
18
- * checks on the `app` argument. Phase 4 commits use property
19
- * probing today; cutover swaps to brand-symbol reads.
20
- *
21
- * ── Default-app registry ──────────────────────────────────────────────
22
- *
23
- * Mirrors `firebase-admin/app`'s lifecycle exactly (oracle:
24
- * `firebase-admin/lib/app/lifecycle.js`):
25
- *
26
- * - `initializeApp(config?, name?)` registers under `'[DEFAULT]'` when
27
- * unnamed; `getApp(name?)` / `getApps()` / `deleteApp(app)` read it.
28
- * - Duplicate-name errors carry firebase-admin's codes and message
29
- * text: `app/duplicate-app` for a config'd re-init with a different
30
- * configuration, `app/invalid-app-options` for a bare-vs-config'd
31
- * mismatch (firebase-admin's autoInit mismatch), `app/no-app` from
32
- * `getApp` on a missing name, `app/invalid-app-name` for a
33
- * non-string/empty name. Errors reuse firebase-admin's own
34
- * `FirebaseAppError` class, so `instanceof`, `constructor.name`,
35
- * `.code`, and message text match production byte-for-byte
36
- * (oracle: `admin-app-*` observations).
37
- * - Idempotency mirror: a bare `initializeApp()` repeated for the same
38
- * name returns the existing auto-initialized app (firebase-admin's
39
- * autoInit path); `initializeApp({ sandbox })` repeated with the
40
- * SAME `Sandbox` reference returns the existing app (the reference
41
- * is our deep-equal analog — sandboxes have identity, not value
42
- * equality); prod re-inits delegate the equality decision to
43
- * firebase-admin itself (deep-equal options → same app; credential /
44
- * httpAgent present → `app/invalid-app-options`, exactly upstream).
45
- *
46
- * ── Ambient init (bare `initializeApp()`) ─────────────────────────────
47
- *
48
- * The user's server code contains ZERO pyric identifiers — bare
49
- * `initializeApp()` + no-arg `getDatabase()` / `getAuth()`. The
50
- * environment picks the backend:
51
- *
52
- * - `PYRIC_SANDBOX` unset → exactly firebase-admin's behavior:
53
- * delegate to `firebase-admin/app.initializeApp()` (FIREBASE_CONFIG
54
- * env + application-default credentials), register the prod arm.
55
- * - `PYRIC_SANDBOX=remote` or `remote:<url>` → obtain a remote sandbox
56
- * handle from the factory installed by `pyric-tools/register` at
57
- * `globalThis[REMOTE_SANDBOX_FACTORY]`
58
- * (`Symbol.for('pyric.remote.sandboxFactory')`) and register the
59
- * sandbox arm. One activation line is logged to stderr. If the env
60
- * is set but no factory is installed, throw with remediation (run
61
- * under `pyric dev`, or add `--import pyric-tools/register` to
62
- * NODE_OPTIONS).
63
- * - Production guard: refuses to route to a sandbox when
64
- * `NODE_ENV === 'production'`, unless `PYRIC_SANDBOX_FORCE=1`.
65
- *
66
- * Ambient resolution happens ONLY on the bare call — any explicit
67
- * config (`{ sandbox }` or prod `AppOptions`, even `{}`) bypasses the
68
- * env entirely, so pyric-aware code keeps full control.
4
+ * Production selection happens before this module loads: activated Node
5
+ * processes resolve `firebase-admin/app` here, while inactive applications
6
+ * continue resolving their own `firebase-admin/app` package unchanged.
69
7
  */
70
8
  import { type Sandbox } from 'pyric/sandbox';
71
- import { type App as AdminApp, type AppOptions } from 'firebase-admin/app';
72
- /**
73
- * Brand on every PyricAdminApp. Matches the symbol used in
74
- * `pyric/app` so a future shared `pyric/runtime` package can
75
- * unify dispatch helpers across both packages.
76
- */
9
+ /** Brand carried by every sandbox admin app. */
77
10
  export declare const ADMIN_APP_TARGET: unique symbol;
78
- export type PyricAdminAppTarget = 'sandbox' | 'prod';
79
- /** firebase-admin's default app name — `'[DEFAULT]'`. */
11
+ export type PyricAdminAppTarget = 'sandbox';
12
+ /** firebase-admin's default app name. */
80
13
  export declare const DEFAULT_APP_NAME = "[DEFAULT]";
81
14
  export interface SandboxAdminApp {
82
15
  readonly [ADMIN_APP_TARGET]: 'sandbox';
83
16
  readonly sandbox: Sandbox;
84
- /** Registry name (mirrors firebase-admin `App.name`). */
85
- readonly name: string;
86
- }
87
- export interface ProdAdminApp {
88
- readonly [ADMIN_APP_TARGET]: 'prod';
89
- readonly adminApp: AdminApp;
90
- /** Registry name (mirrors firebase-admin `App.name`). */
91
17
  readonly name: string;
92
18
  }
93
- export type PyricAdminApp = SandboxAdminApp | ProdAdminApp;
19
+ export type PyricAdminApp = SandboxAdminApp;
94
20
  export type InitializeAdminAppConfig = {
95
21
  sandbox: Sandbox;
96
- } | AppOptions;
22
+ };
97
23
  /**
98
- * App-lifecycle errors reuse `firebase-admin`'s own exported
99
- * `FirebaseAppError` so the thrown error's class, `constructor.name`,
100
- * `.code` (`app/no-app`, `app/duplicate-app`, `app/invalid-app-options`,
101
- * `app/invalid-app-name`, `app/invalid-argument`), and message text match
102
- * production byte-for-byte (oracle: `admin-app-*` observations assert
103
- * `errorName: "FirebaseAppError"`). The published typings declare only the
104
- * base `Error` constructor, but the real runtime class is
105
- * `new FirebaseAppError(code, message)` where `code` becomes `app/<code>` —
106
- * the typed cast recovers it.
24
+ * Firebase Functions' ESM runtime statically imports this credential factory
25
+ * while linking its database provider. Pyric initializes the sandbox app
26
+ * before that provider executes, so the factory is not used by supported
27
+ * Functions flows. Keep the named export link-compatible, but fail clearly if
28
+ * application code asks the development sandbox for production credentials.
107
29
  */
108
- declare const AdminAppError: new (code: string, message: string) => Error & {
109
- readonly code: string;
110
- };
111
- /** @deprecated Alias kept for pre-merge call sites; errors ARE `FirebaseAppError`. */
112
- export declare const PyricAdminAppError: new (code: string, message: string) => Error & {
113
- readonly code: string;
114
- };
115
- export type PyricAdminAppError = InstanceType<typeof AdminAppError>;
30
+ export declare function applicationDefault(): never;
116
31
  /**
117
- * Initialize a Pyric admin app and register it under `name`
118
- * (default `'[DEFAULT]'`), mirroring `firebase-admin/app.initializeApp`.
32
+ * Initialize a sandbox admin app.
119
33
  *
120
- * @example
121
- * ```ts
122
- * // Ambient (zero pyric identifiers — environment decides)
123
- * import { initializeApp } from 'pyric-admin/app';
124
- * const app = initializeApp();
125
- *
126
- * // Prod-backed
127
- * import { applicationDefault } from 'firebase-admin/app';
128
- * const app = initializeApp({ credential: applicationDefault() });
129
- *
130
- * // Sandbox-backed
131
- * import { initializeSandbox } from 'pyric/sandbox';
132
- * const app = initializeApp({ sandbox: initializeSandbox() });
133
- * ```
34
+ * An explicit `{ sandbox }` config binds an in-process or remote sandbox.
35
+ * A bare call resolves the remote sandbox factory installed by
36
+ * `@pyric/cli/register`. Production callers must import `firebase-admin/app`
37
+ * without Pyric activation instead of passing production options here.
134
38
  */
135
39
  export declare function initializeApp(config?: InitializeAdminAppConfig, name?: string): PyricAdminApp;
136
- /**
137
- * Return the registered app for `name` (default `'[DEFAULT]'`).
138
- * Mirrors `firebase-admin/app.getApp` — including the exact `app/no-app`
139
- * error text on a miss.
140
- */
40
+ /** Return the registered app for `name`. */
141
41
  export declare function getApp(name?: string): PyricAdminApp;
142
- /**
143
- * A copy of the list of all registered apps.
144
- * Mirrors `firebase-admin/app.getApps`.
145
- */
42
+ /** Return a copy of the app registry. */
146
43
  export declare function getApps(): PyricAdminApp[];
147
- /**
148
- * Remove `app` from the registry, mirroring `firebase-admin/app.deleteApp`.
149
- * Prod-backed apps also delete the underlying firebase-admin app (freeing
150
- * its resources and its slot in firebase-admin's own registry, so the
151
- * name can be re-initialized). Sandbox-backed apps only deregister — the
152
- * `Sandbox` handle's lifetime belongs to its creator.
153
- */
44
+ /** Remove a sandbox app from the registry. */
154
45
  export declare function deleteApp(app: PyricAdminApp): Promise<void>;
155
46
  export declare function isSandboxAdminApp(app: PyricAdminApp): app is SandboxAdminApp;
156
- export declare function isProdAdminApp(app: PyricAdminApp): app is ProdAdminApp;
157
- export {};
158
47
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/app/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AAEH,OAAO,EAIL,KAAK,OAAO,EACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAIL,KAAK,GAAG,IAAI,QAAQ,EACpB,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAE5B;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,eAAuC,CAAC;AAErE,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,MAAM,CAAC;AAErD,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,cAAc,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,CAAC,gBAAgB,CAAC,EAAE,SAAS,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,YAAY,CAAC;AAE3D,MAAM,MAAM,wBAAwB,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,UAAU,CAAC;AAEzE;;;;;;;;;;GAUG;AACH,QAAA,MAAM,aAAa,EAAkC,KACnD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,KACZ,KAAK,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,sFAAsF;AACtF,eAAO,MAAM,kBAAkB,aALvB,MAAM,WACH,MAAM,KACZ,KAAK,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAGW,CAAC;AAChD,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AA8BpE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAC3B,MAAM,CAAC,EAAE,wBAAwB,EACjC,IAAI,GAAE,MAAyB,GAC9B,aAAa,CA8Df;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,GAAE,MAAyB,GAAG,aAAa,CAcrE;AAED;;;GAGG;AACH,wBAAgB,OAAO,IAAI,aAAa,EAAE,CAEzC;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAW3D;AA0FD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,GAAG,IAAI,eAAe,CAE5E;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,GAAG,IAAI,YAAY,CAEtE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/app/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAIL,KAAK,OAAO,EACb,MAAM,eAAe,CAAC;AAGvB,gDAAgD;AAChD,eAAO,MAAM,gBAAgB,eAAuC,CAAC;AACrE,MAAM,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAE5C,yCAAyC;AACzC,eAAO,MAAM,gBAAgB,cAAc,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,CAAC,gBAAgB,CAAC,EAAE,SAAS,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,eAAe,CAAC;AAC5C,MAAM,MAAM,wBAAwB,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5D;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,KAAK,CAK1C;AA4CD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,CAAC,EAAE,wBAAwB,EACjC,IAAI,GAAE,MAAyB,GAC9B,aAAa,CAqCf;AAED,4CAA4C;AAC5C,wBAAgB,MAAM,CAAC,IAAI,GAAE,MAAyB,GAAG,aAAa,CAarE;AAED,yCAAyC;AACzC,wBAAgB,OAAO,IAAI,aAAa,EAAE,CAEzC;AAED,8CAA8C;AAC9C,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAS3D;AAgED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,GAAG,IAAI,eAAe,CAE5E"}
package/dist/app/index.js CHANGED
@@ -1,192 +1,94 @@
1
1
  /**
2
- * `pyric-admin/app` — Phase 3 initializeApp surface (ADR-001 D6) plus the
3
- * default-app registry and AMBIENT INIT (adoption experience, layer 3).
2
+ * `pyric-admin/app` — sandbox-only admin app registry.
4
3
  *
5
- * Mirror shape: at cutover this becomes `pyric-admin/app` and is the
6
- * single entry point where the sandbox-vs-prod choice is made for the
7
- * admin surface. Every `pyric-admin/*` subpath inspects the handle's
8
- * brand for backend dispatch.
9
- *
10
- * Current shadow scope:
11
- * - `initializeApp({ credential, ... })` — prod-backed (live;
12
- * delegates to `firebase-admin/app.initializeApp`).
13
- * - `initializeApp({ sandbox })` — sandbox-backed (live).
14
- * - `initializeApp()` — BARE, zero pyric identifiers in app code. The
15
- * environment decides the backend (see "Ambient init" below).
16
- * - Per-subpath adapter dispatch via the brand: implemented in
17
- * `pyric-admin/{auth,database,storage}` via structural
18
- * checks on the `app` argument. Phase 4 commits use property
19
- * probing today; cutover swaps to brand-symbol reads.
20
- *
21
- * ── Default-app registry ──────────────────────────────────────────────
22
- *
23
- * Mirrors `firebase-admin/app`'s lifecycle exactly (oracle:
24
- * `firebase-admin/lib/app/lifecycle.js`):
25
- *
26
- * - `initializeApp(config?, name?)` registers under `'[DEFAULT]'` when
27
- * unnamed; `getApp(name?)` / `getApps()` / `deleteApp(app)` read it.
28
- * - Duplicate-name errors carry firebase-admin's codes and message
29
- * text: `app/duplicate-app` for a config'd re-init with a different
30
- * configuration, `app/invalid-app-options` for a bare-vs-config'd
31
- * mismatch (firebase-admin's autoInit mismatch), `app/no-app` from
32
- * `getApp` on a missing name, `app/invalid-app-name` for a
33
- * non-string/empty name. Errors reuse firebase-admin's own
34
- * `FirebaseAppError` class, so `instanceof`, `constructor.name`,
35
- * `.code`, and message text match production byte-for-byte
36
- * (oracle: `admin-app-*` observations).
37
- * - Idempotency mirror: a bare `initializeApp()` repeated for the same
38
- * name returns the existing auto-initialized app (firebase-admin's
39
- * autoInit path); `initializeApp({ sandbox })` repeated with the
40
- * SAME `Sandbox` reference returns the existing app (the reference
41
- * is our deep-equal analog — sandboxes have identity, not value
42
- * equality); prod re-inits delegate the equality decision to
43
- * firebase-admin itself (deep-equal options → same app; credential /
44
- * httpAgent present → `app/invalid-app-options`, exactly upstream).
45
- *
46
- * ── Ambient init (bare `initializeApp()`) ─────────────────────────────
47
- *
48
- * The user's server code contains ZERO pyric identifiers — bare
49
- * `initializeApp()` + no-arg `getDatabase()` / `getAuth()`. The
50
- * environment picks the backend:
51
- *
52
- * - `PYRIC_SANDBOX` unset → exactly firebase-admin's behavior:
53
- * delegate to `firebase-admin/app.initializeApp()` (FIREBASE_CONFIG
54
- * env + application-default credentials), register the prod arm.
55
- * - `PYRIC_SANDBOX=remote` or `remote:<url>` → obtain a remote sandbox
56
- * handle from the factory installed by `pyric-tools/register` at
57
- * `globalThis[REMOTE_SANDBOX_FACTORY]`
58
- * (`Symbol.for('pyric.remote.sandboxFactory')`) and register the
59
- * sandbox arm. One activation line is logged to stderr. If the env
60
- * is set but no factory is installed, throw with remediation (run
61
- * under `pyric dev`, or add `--import pyric-tools/register` to
62
- * NODE_OPTIONS).
63
- * - Production guard: refuses to route to a sandbox when
64
- * `NODE_ENV === 'production'`, unless `PYRIC_SANDBOX_FORCE=1`.
65
- *
66
- * Ambient resolution happens ONLY on the bare call — any explicit
67
- * config (`{ sandbox }` or prod `AppOptions`, even `{}`) bypasses the
68
- * env entirely, so pyric-aware code keeps full control.
4
+ * Production selection happens before this module loads: activated Node
5
+ * processes resolve `firebase-admin/app` here, while inactive applications
6
+ * continue resolving their own `firebase-admin/app` package unchanged.
69
7
  */
70
8
  import { REMOTE_SANDBOX_FACTORY, } from 'pyric/sandbox';
71
- import { initializeApp as initializeFirebaseAdminApp, deleteApp as deleteFirebaseAdminApp, FirebaseAppError, } from 'firebase-admin/app';
72
- /**
73
- * Brand on every PyricAdminApp. Matches the symbol used in
74
- * `pyric/app` so a future shared `pyric/runtime` package can
75
- * unify dispatch helpers across both packages.
76
- */
9
+ import { assertAdminAppActive, markAdminAppDeleted } from './lifecycle.js';
10
+ /** Brand carried by every sandbox admin app. */
77
11
  export const ADMIN_APP_TARGET = Symbol.for('pyric.admin.app.target');
78
- /** firebase-admin's default app name — `'[DEFAULT]'`. */
12
+ /** firebase-admin's default app name. */
79
13
  export const DEFAULT_APP_NAME = '[DEFAULT]';
80
14
  /**
81
- * App-lifecycle errors reuse `firebase-admin`'s own exported
82
- * `FirebaseAppError` so the thrown error's class, `constructor.name`,
83
- * `.code` (`app/no-app`, `app/duplicate-app`, `app/invalid-app-options`,
84
- * `app/invalid-app-name`, `app/invalid-argument`), and message text match
85
- * production byte-for-byte (oracle: `admin-app-*` observations assert
86
- * `errorName: "FirebaseAppError"`). The published typings declare only the
87
- * base `Error` constructor, but the real runtime class is
88
- * `new FirebaseAppError(code, message)` where `code` becomes `app/<code>` —
89
- * the typed cast recovers it.
15
+ * Firebase Functions' ESM runtime statically imports this credential factory
16
+ * while linking its database provider. Pyric initializes the sandbox app
17
+ * before that provider executes, so the factory is not used by supported
18
+ * Functions flows. Keep the named export link-compatible, but fail clearly if
19
+ * application code asks the development sandbox for production credentials.
90
20
  */
91
- const AdminAppError = FirebaseAppError;
92
- /** @deprecated Alias kept for pre-merge call sites; errors ARE `FirebaseAppError`. */
93
- export const PyricAdminAppError = AdminAppError;
94
- // ─── Registry ───────────────────────────────────────────────────────────
95
- //
96
- // Module-level, matching firebase-admin's `defaultAppStore` (one store per
97
- // module instance). `autoInitApps` tracks which registered apps came from a
98
- // BARE `initializeApp()` — firebase-admin's `autoInit` flag — so the
99
- // bare-vs-config'd mismatch throws exactly like upstream.
100
- const appRegistry = new Map();
101
- const autoInitApps = new WeakSet();
102
- /** firebase-admin's app-name validation, verbatim message. */
21
+ export function applicationDefault() {
22
+ throw new Error('pyric-admin/app: applicationDefault() is unavailable in the sandbox. ' +
23
+ 'Pyric development does not use production credentials.');
24
+ }
25
+ /** Local error with the observable firebase-admin app-error shape. */
26
+ class FirebaseAppError extends Error {
27
+ code;
28
+ constructor(code, message) {
29
+ super(message);
30
+ this.name = 'FirebaseAppError';
31
+ this.code = `app/${code}`;
32
+ }
33
+ }
34
+ // Node may evaluate this ESM-only mirror through distinct require(esm) and
35
+ // import module records when the register hook rewrites both CJS and ESM
36
+ // Firebase consumers. Firebase Admin's app registry is process-wide, so keep
37
+ // the mirror registry behind Symbol.for as well: both module records must see
38
+ // the same default app and sandbox handle.
39
+ const APP_REGISTRY = Symbol.for('pyric.admin.app.registry');
40
+ const AMBIENT_APPS = Symbol.for('pyric.admin.app.ambientApps');
41
+ const globalRegistry = globalThis;
42
+ const appRegistry = globalRegistry[APP_REGISTRY] ??= new Map();
43
+ const ambientApps = globalRegistry[AMBIENT_APPS] ??= new WeakSet();
103
44
  function validateAppName(name) {
104
45
  if (typeof name !== 'string' || name === '') {
105
- throw new AdminAppError('invalid-app-name', `Invalid Firebase app name "${String(name)}" provided. App name must be a non-empty string.`);
46
+ throw new FirebaseAppError('invalid-app-name', `Invalid Firebase app name "${String(name)}" provided. App name must be a non-empty string.`);
106
47
  }
107
48
  }
108
- /** firebase-admin's message for every same-name/different-config case. */
109
49
  function alreadyExists(name, code) {
110
- return new AdminAppError(code, `A Firebase app named "${name}" already exists with a different configuration.`);
50
+ return new FirebaseAppError(code, `A Firebase app named "${name}" already exists with a different configuration.`);
111
51
  }
112
52
  /**
113
- * Initialize a Pyric admin app and register it under `name`
114
- * (default `'[DEFAULT]'`), mirroring `firebase-admin/app.initializeApp`.
115
- *
116
- * @example
117
- * ```ts
118
- * // Ambient (zero pyric identifiers — environment decides)
119
- * import { initializeApp } from 'pyric-admin/app';
120
- * const app = initializeApp();
53
+ * Initialize a sandbox admin app.
121
54
  *
122
- * // Prod-backed
123
- * import { applicationDefault } from 'firebase-admin/app';
124
- * const app = initializeApp({ credential: applicationDefault() });
125
- *
126
- * // Sandbox-backed
127
- * import { initializeSandbox } from 'pyric/sandbox';
128
- * const app = initializeApp({ sandbox: initializeSandbox() });
129
- * ```
55
+ * An explicit `{ sandbox }` config binds an in-process or remote sandbox.
56
+ * A bare call resolves the remote sandbox factory installed by
57
+ * `@pyric/cli/register`. Production callers must import `firebase-admin/app`
58
+ * without Pyric activation instead of passing production options here.
130
59
  */
131
60
  export function initializeApp(config, name = DEFAULT_APP_NAME) {
132
61
  validateAppName(name);
133
62
  const existing = appRegistry.get(name);
134
- // ── Bare call: ambient resolution ────────────────────────────────────
135
63
  if (config === undefined) {
136
64
  if (existing !== undefined) {
137
- // firebase-admin: two autoInit calls return the same app; an
138
- // autoInit call against a config'd app is an options mismatch.
139
- if (autoInitApps.has(existing))
65
+ if (ambientApps.has(existing))
140
66
  return existing;
141
67
  throw alreadyExists(name, 'invalid-app-options');
142
68
  }
143
69
  const app = initializeAmbientApp(name);
144
70
  appRegistry.set(name, app);
145
- autoInitApps.add(app);
71
+ ambientApps.add(app);
146
72
  return app;
147
73
  }
148
- // ── Explicit sandbox config ──────────────────────────────────────────
149
- if (isSandboxConfig(config)) {
150
- if (existing !== undefined) {
151
- // Reference identity is the deep-equal analog for sandboxes.
152
- if (!autoInitApps.has(existing) &&
153
- existing[ADMIN_APP_TARGET] === 'sandbox' &&
154
- existing.sandbox === config.sandbox) {
155
- return existing;
156
- }
157
- throw alreadyExists(name, autoInitApps.has(existing) ? 'invalid-app-options' : 'duplicate-app');
158
- }
159
- const app = {
160
- [ADMIN_APP_TARGET]: 'sandbox',
161
- sandbox: config.sandbox,
162
- name,
163
- };
164
- appRegistry.set(name, app);
165
- return app;
74
+ if (!isSandboxConfig(config)) {
75
+ throw new TypeError('pyric-admin/app is a sandbox-only mirror. Production applications must ' +
76
+ 'load firebase-admin/app without Pyric activation.');
166
77
  }
167
- // ── Explicit prod options ────────────────────────────────────────────
168
78
  if (existing !== undefined) {
169
- if (existing[ADMIN_APP_TARGET] === 'prod' && !autoInitApps.has(existing)) {
170
- // Delegate the equality decision to firebase-admin itself: deep-
171
- // equal options return the same AdminApp; credential / httpAgent
172
- // re-inits throw app/invalid-app-options; different options throw
173
- // app/duplicate-app — all with upstream's exact messages.
174
- const adminApp = initializeFirebaseAdminApp(config, name);
175
- if (adminApp === existing.adminApp)
176
- return existing;
177
- }
178
- throw alreadyExists(name, autoInitApps.has(existing) ? 'invalid-app-options' : 'duplicate-app');
79
+ if (!ambientApps.has(existing) && existing.sandbox === config.sandbox)
80
+ return existing;
81
+ throw alreadyExists(name, ambientApps.has(existing) ? 'invalid-app-options' : 'duplicate-app');
179
82
  }
180
- const adminApp = initializeFirebaseAdminApp(config, name);
181
- const app = { [ADMIN_APP_TARGET]: 'prod', adminApp, name };
83
+ const app = {
84
+ [ADMIN_APP_TARGET]: 'sandbox',
85
+ sandbox: config.sandbox,
86
+ name,
87
+ };
182
88
  appRegistry.set(name, app);
183
89
  return app;
184
90
  }
185
- /**
186
- * Return the registered app for `name` (default `'[DEFAULT]'`).
187
- * Mirrors `firebase-admin/app.getApp` — including the exact `app/no-app`
188
- * error text on a miss.
189
- */
91
+ /** Return the registered app for `name`. */
190
92
  export function getApp(name = DEFAULT_APP_NAME) {
191
93
  validateAppName(name);
192
94
  const app = appRegistry.get(name);
@@ -194,52 +96,34 @@ export function getApp(name = DEFAULT_APP_NAME) {
194
96
  const lead = name === DEFAULT_APP_NAME
195
97
  ? 'The default Firebase app does not exist. '
196
98
  : `Firebase app named "${name}" does not exist. `;
197
- throw new AdminAppError('no-app', lead + 'Make sure you call initializeApp() before using any of the Firebase services.');
99
+ throw new FirebaseAppError('no-app', lead + 'Make sure you call initializeApp() before using any of the Firebase services.');
198
100
  }
199
101
  return app;
200
102
  }
201
- /**
202
- * A copy of the list of all registered apps.
203
- * Mirrors `firebase-admin/app.getApps`.
204
- */
103
+ /** Return a copy of the app registry. */
205
104
  export function getApps() {
206
105
  return Array.from(appRegistry.values());
207
106
  }
208
- /**
209
- * Remove `app` from the registry, mirroring `firebase-admin/app.deleteApp`.
210
- * Prod-backed apps also delete the underlying firebase-admin app (freeing
211
- * its resources and its slot in firebase-admin's own registry, so the
212
- * name can be re-initialized). Sandbox-backed apps only deregister — the
213
- * `Sandbox` handle's lifetime belongs to its creator.
214
- */
107
+ /** Remove a sandbox app from the registry. */
215
108
  export function deleteApp(app) {
216
109
  if (typeof app !== 'object' || app === null || !(ADMIN_APP_TARGET in app)) {
217
- throw new AdminAppError('invalid-argument', 'Invalid app argument.');
110
+ throw new FirebaseAppError('invalid-argument', 'Invalid app argument.');
218
111
  }
219
- // Make sure the given app is actually registered (throws app/no-app).
112
+ assertAdminAppActive(app);
220
113
  const existing = getApp(app.name);
221
114
  appRegistry.delete(existing.name);
222
- if (existing[ADMIN_APP_TARGET] === 'prod') {
223
- return deleteFirebaseAdminApp(existing.adminApp);
224
- }
115
+ markAdminAppDeleted(existing);
225
116
  return Promise.resolve();
226
117
  }
227
- // ─── Ambient init ───────────────────────────────────────────────────────
228
- /**
229
- * Resolve a bare `initializeApp()` from the environment. See the
230
- * module-level "Ambient init" docs for the full contract.
231
- */
232
118
  function initializeAmbientApp(name) {
233
119
  const env = process.env.PYRIC_SANDBOX;
234
120
  if (env === undefined || env.trim() === '') {
235
- // Unset → exactly today's prod behavior: firebase-admin's autoInit
236
- // (FIREBASE_CONFIG env options + application-default credentials).
237
- const adminApp = initializeFirebaseAdminApp(undefined, name);
238
- return { [ADMIN_APP_TARGET]: 'prod', adminApp, name };
121
+ throw new Error('pyric-admin/app is a sandbox-only mirror and no sandbox is active. ' +
122
+ 'Run under `pyric dev`, set PYRIC_SANDBOX with @pyric/cli/register, ' +
123
+ 'or load firebase-admin/app without Pyric activation for production.');
239
124
  }
240
125
  const opts = parsePyricSandboxEnv(env);
241
- if (process.env.NODE_ENV === 'production' &&
242
- process.env.PYRIC_SANDBOX_FORCE !== '1') {
126
+ if (process.env.NODE_ENV === 'production' && process.env.PYRIC_SANDBOX_FORCE !== '1') {
243
127
  throw new Error('pyric-admin: PYRIC_SANDBOX is set but NODE_ENV is "production" — ' +
244
128
  'refusing to route firebase-admin to a development sandbox. ' +
245
129
  'Unset PYRIC_SANDBOX in production, or set PYRIC_SANDBOX_FORCE=1 ' +
@@ -248,25 +132,13 @@ function initializeAmbientApp(name) {
248
132
  const factory = globalThis[REMOTE_SANDBOX_FACTORY];
249
133
  if (typeof factory !== 'function') {
250
134
  throw new Error(`pyric-admin: PYRIC_SANDBOX=${env} is set but no remote sandbox ` +
251
- 'factory is installed (globalThis[Symbol.for(' +
252
- "'pyric.remote.sandboxFactory')] is absent). Run your server " +
253
- 'under `pyric dev`, or add `--import pyric-tools/register` to ' +
254
- 'NODE_OPTIONS.');
135
+ "factory is installed (globalThis[Symbol.for('pyric.remote.sandboxFactory')] is absent). " +
136
+ 'Run your server under `pyric dev`, or add `--import @pyric/cli/register` to NODE_OPTIONS.');
255
137
  }
256
138
  const sandbox = factory(opts);
257
139
  process.stderr.write(`pyric: firebase-admin routed to sandbox${opts.url !== undefined ? ` at ${opts.url}` : ''}\n`);
258
140
  return { [ADMIN_APP_TARGET]: 'sandbox', sandbox, name };
259
141
  }
260
- /**
261
- * Parse the `PYRIC_SANDBOX` activator value.
262
- *
263
- * - `remote` → `{}` (factory discovers the running `pyric dev`)
264
- * - `remote:<url>` → `{ url }` (everything after the FIRST colon —
265
- * URLs contain colons, so only the mode prefix is split off)
266
- *
267
- * Anything else throws: an unrecognized activator must never silently
268
- * fall through to prod (mode-by-side-effect in the failure direction).
269
- */
270
142
  function parsePyricSandboxEnv(env) {
271
143
  const value = env.trim();
272
144
  if (value === 'remote')
@@ -281,17 +153,12 @@ function parsePyricSandboxEnv(env) {
281
153
  return { url };
282
154
  }
283
155
  throw new Error(`pyric-admin: unrecognized PYRIC_SANDBOX value "${env}". Supported ` +
284
- 'values: "remote" (auto-discover the running `pyric dev`) or ' +
285
- '"remote:<url>".');
156
+ 'values: "remote" (auto-discover the running `pyric dev`) or "remote:<url>".');
286
157
  }
287
- // ─── Guards ─────────────────────────────────────────────────────────────
288
158
  function isSandboxConfig(config) {
289
159
  return typeof config === 'object' && config !== null && 'sandbox' in config;
290
160
  }
291
161
  export function isSandboxAdminApp(app) {
292
162
  return app[ADMIN_APP_TARGET] === 'sandbox';
293
163
  }
294
- export function isProdAdminApp(app) {
295
- return app[ADMIN_APP_TARGET] === 'prod';
296
- }
297
164
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/app/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/app/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /** Internal lifecycle guard shared by every pyric-admin service factory. */
2
+ export declare function assertAdminAppActive(app: object & {
3
+ readonly name: string;
4
+ }): void;
5
+ /** Tombstone a wrapper while leaving the caller-owned Sandbox alive. */
6
+ export declare function markAdminAppDeleted(app: object): void;
7
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/app/lifecycle.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQlF;AAED,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAErD"}
@@ -0,0 +1,15 @@
1
+ const deletedApps = new WeakSet();
2
+ /** Internal lifecycle guard shared by every pyric-admin service factory. */
3
+ export function assertAdminAppActive(app) {
4
+ if (!deletedApps.has(app))
5
+ return;
6
+ const error = new Error(`Firebase app named "${app.name}" has already been deleted.`);
7
+ error.name = 'FirebaseAppError';
8
+ error.code = 'app/app-deleted';
9
+ throw error;
10
+ }
11
+ /** Tombstone a wrapper while leaving the caller-owned Sandbox alive. */
12
+ export function markAdminAppDeleted(app) {
13
+ deletedApps.add(app);
14
+ }
15
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/app/lifecycle.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,IAAI,OAAO,EAAU,CAAC;AAE1C,4EAA4E;AAC5E,MAAM,UAAU,oBAAoB,CAAC,GAAuC;IAC1E,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO;IAClC,MAAM,KAAK,GAAG,IAAI,KAAK,CACrB,uBAAuB,GAAG,CAAC,IAAI,6BAA6B,CACjC,CAAC;IAC9B,KAAK,CAAC,IAAI,GAAG,kBAAkB,CAAC;IAChC,KAAK,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAC/B,MAAM,KAAK,CAAC;AACd,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC"}