pyric 0.1.0-alpha.21 → 0.1.0-alpha.24
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/README.md +12 -4
- package/dist/ai/activity.d.ts +9 -0
- package/dist/ai/activity.d.ts.map +1 -0
- package/dist/ai/activity.js +45 -0
- package/dist/ai/activity.js.map +1 -0
- package/dist/ai/broker/broker.d.ts +25 -0
- package/dist/ai/broker/broker.d.ts.map +1 -1
- package/dist/ai/broker/broker.js +46 -42
- package/dist/ai/broker/broker.js.map +1 -1
- package/dist/ai/broker/gemini-engine.d.ts +7 -0
- package/dist/ai/broker/gemini-engine.d.ts.map +1 -1
- package/dist/ai/broker/gemini-engine.js +15 -0
- package/dist/ai/broker/gemini-engine.js.map +1 -1
- package/dist/ai/broker/index.d.ts +1 -1
- package/dist/ai/broker/index.d.ts.map +1 -1
- package/dist/ai/broker/index.js.map +1 -1
- package/dist/ai/broker/openai-engine.d.ts.map +1 -1
- package/dist/ai/broker/openai-engine.js +7 -3
- package/dist/ai/broker/openai-engine.js.map +1 -1
- package/dist/ai/broker/scripted-engine.d.ts +9 -1
- package/dist/ai/broker/scripted-engine.d.ts.map +1 -1
- package/dist/ai/broker/scripted-engine.js +14 -5
- package/dist/ai/broker/scripted-engine.js.map +1 -1
- package/dist/ai/broker/types.d.ts +6 -2
- package/dist/ai/broker/types.d.ts.map +1 -1
- package/dist/ai/events.d.ts +12 -0
- package/dist/ai/events.d.ts.map +1 -0
- package/dist/ai/events.js +17 -0
- package/dist/ai/events.js.map +1 -0
- package/dist/ai/generation-enums.d.ts +43 -0
- package/dist/ai/generation-enums.d.ts.map +1 -0
- package/dist/ai/generation-enums.js +37 -0
- package/dist/ai/generation-enums.js.map +1 -0
- package/dist/ai/index.d.ts +1 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +1 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/instances.d.ts +6 -0
- package/dist/ai/instances.d.ts.map +1 -1
- package/dist/ai/instances.js +20 -2
- package/dist/ai/instances.js.map +1 -1
- package/dist/ai/internal.d.ts +3 -0
- package/dist/ai/internal.d.ts.map +1 -1
- package/dist/ai/internal.js +3 -0
- package/dist/ai/internal.js.map +1 -1
- package/dist/ai/sandbox-plane.d.ts.map +1 -1
- package/dist/ai/sandbox-plane.js +23 -8
- package/dist/ai/sandbox-plane.js.map +1 -1
- package/dist/ai/scripting.d.ts +20 -2
- package/dist/ai/scripting.d.ts.map +1 -1
- package/dist/ai/scripting.js +30 -3
- package/dist/ai/scripting.js.map +1 -1
- package/dist/app/internal.d.ts +1 -0
- package/dist/app/internal.d.ts.map +1 -1
- package/dist/app/internal.js +1 -0
- package/dist/app/internal.js.map +1 -1
- package/dist/auth/email-link.d.ts +8 -1
- package/dist/auth/email-link.d.ts.map +1 -1
- package/dist/auth/email-link.js +29 -20
- package/dist/auth/email-link.js.map +1 -1
- package/dist/auth/events.d.ts +12 -0
- package/dist/auth/events.d.ts.map +1 -0
- package/dist/auth/events.js +18 -0
- package/dist/auth/events.js.map +1 -0
- package/dist/auth/factor-id.d.ts +7 -0
- package/dist/auth/factor-id.d.ts.map +1 -0
- package/dist/auth/factor-id.js +6 -0
- package/dist/auth/factor-id.js.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/instances.d.ts.map +1 -1
- package/dist/auth/instances.js +13 -1
- package/dist/auth/instances.js.map +1 -1
- package/dist/auth/internal.d.ts +20 -0
- package/dist/auth/internal.d.ts.map +1 -0
- package/dist/auth/internal.js +19 -0
- package/dist/auth/internal.js.map +1 -0
- package/dist/auth/modular.d.ts +9 -0
- package/dist/auth/modular.d.ts.map +1 -1
- package/dist/auth/modular.js +20 -0
- package/dist/auth/modular.js.map +1 -1
- package/dist/auth/reauth.js +3 -2
- package/dist/auth/reauth.js.map +1 -1
- package/dist/auth/sandbox/default-avatar.d.ts +64 -0
- package/dist/auth/sandbox/default-avatar.d.ts.map +1 -0
- package/dist/auth/sandbox/default-avatar.js +118 -0
- package/dist/auth/sandbox/default-avatar.js.map +1 -0
- package/dist/auth/sandbox/driver.d.ts +36 -0
- package/dist/auth/sandbox/driver.d.ts.map +1 -1
- package/dist/auth/sandbox/driver.js +47 -0
- package/dist/auth/sandbox/driver.js.map +1 -1
- package/dist/auth/sandbox/project-store.d.ts +0 -1
- package/dist/auth/sandbox/project-store.d.ts.map +1 -1
- package/dist/auth/sandbox/project-store.js +0 -1
- package/dist/auth/sandbox/project-store.js.map +1 -1
- package/dist/auth/sandbox-backend-types.d.ts +34 -20
- package/dist/auth/sandbox-backend-types.d.ts.map +1 -1
- package/dist/auth/sandbox-backend-types.js +2 -3
- package/dist/auth/sandbox-backend-types.js.map +1 -1
- package/dist/auth/sandbox-backend.d.ts +98 -20
- package/dist/auth/sandbox-backend.d.ts.map +1 -1
- package/dist/auth/sandbox-backend.js +403 -96
- package/dist/auth/sandbox-backend.js.map +1 -1
- package/dist/auth/seed-user.d.ts +38 -0
- package/dist/auth/seed-user.d.ts.map +1 -0
- package/dist/auth/seed-user.js +2 -0
- package/dist/auth/seed-user.js.map +1 -0
- package/dist/auth/tokens.d.ts +6 -1
- package/dist/auth/tokens.d.ts.map +1 -1
- package/dist/auth/tokens.js +19 -17
- package/dist/auth/tokens.js.map +1 -1
- package/dist/auth/types.d.ts +13 -1
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/types.js.map +1 -1
- package/dist/database/activity-coverage.d.ts +9 -0
- package/dist/database/activity-coverage.d.ts.map +1 -0
- package/dist/database/activity-coverage.js +11 -0
- package/dist/database/activity-coverage.js.map +1 -0
- package/dist/database/connection-lifecycle.d.ts +3 -0
- package/dist/database/connection-lifecycle.d.ts.map +1 -1
- package/dist/database/connection-lifecycle.js +54 -23
- package/dist/database/connection-lifecycle.js.map +1 -1
- package/dist/database/events.d.ts +12 -0
- package/dist/database/events.d.ts.map +1 -0
- package/dist/database/events.js +10 -0
- package/dist/database/events.js.map +1 -0
- package/dist/database/instances.d.ts +7 -7
- package/dist/database/instances.d.ts.map +1 -1
- package/dist/database/instances.js +35 -13
- package/dist/database/instances.js.map +1 -1
- package/dist/database/internal/query-projection.d.ts +102 -0
- package/dist/database/internal/query-projection.d.ts.map +1 -0
- package/dist/database/internal/query-projection.js +293 -0
- package/dist/database/internal/query-projection.js.map +1 -0
- package/dist/database/internal.d.ts +2 -0
- package/dist/database/internal.d.ts.map +1 -1
- package/dist/database/internal.js +2 -0
- package/dist/database/internal.js.map +1 -1
- package/dist/database/listeners.d.ts.map +1 -1
- package/dist/database/listeners.js +165 -37
- package/dist/database/listeners.js.map +1 -1
- package/dist/database/operations.d.ts.map +1 -1
- package/dist/database/operations.js +77 -50
- package/dist/database/operations.js.map +1 -1
- package/dist/database/replay.d.ts.map +1 -1
- package/dist/database/replay.js +6 -2
- package/dist/database/replay.js.map +1 -1
- package/dist/database/routing.d.ts +4 -0
- package/dist/database/routing.d.ts.map +1 -1
- package/dist/database/routing.js.map +1 -1
- package/dist/database/sandbox/backend-for.d.ts +4 -3
- package/dist/database/sandbox/backend-for.d.ts.map +1 -1
- package/dist/database/sandbox/backend-for.js +130 -24
- package/dist/database/sandbox/backend-for.js.map +1 -1
- package/dist/database/sandbox/backend-state.d.ts +7 -0
- package/dist/database/sandbox/backend-state.d.ts.map +1 -1
- package/dist/database/sandbox/backend-state.js +15 -1
- package/dist/database/sandbox/backend-state.js.map +1 -1
- package/dist/database/sandbox/backend.d.ts +2 -1
- package/dist/database/sandbox/backend.d.ts.map +1 -1
- package/dist/database/sandbox/backend.js +3 -3
- package/dist/database/sandbox/backend.js.map +1 -1
- package/dist/database/sandbox/child-listeners.d.ts +5 -0
- package/dist/database/sandbox/child-listeners.d.ts.map +1 -1
- package/dist/database/sandbox/child-listeners.js +34 -14
- package/dist/database/sandbox/child-listeners.js.map +1 -1
- package/dist/database/sandbox/listener-types.d.ts +5 -0
- package/dist/database/sandbox/listener-types.d.ts.map +1 -1
- package/dist/database/sandbox/operation-events.d.ts +5 -0
- package/dist/database/sandbox/operation-events.d.ts.map +1 -1
- package/dist/database/sandbox/operation-events.js +18 -3
- package/dist/database/sandbox/operation-events.js.map +1 -1
- package/dist/database/sandbox/persistence-state.d.ts.map +1 -1
- package/dist/database/sandbox/persistence-state.js +1 -8
- package/dist/database/sandbox/persistence-state.js.map +1 -1
- package/dist/database/sandbox/priority-writes.js +2 -2
- package/dist/database/sandbox/priority-writes.js.map +1 -1
- package/dist/database/sandbox/query.d.ts +2 -101
- package/dist/database/sandbox/query.d.ts.map +1 -1
- package/dist/database/sandbox/query.js +1 -225
- package/dist/database/sandbox/query.js.map +1 -1
- package/dist/database/sandbox/rules-eval.d.ts +28 -0
- package/dist/database/sandbox/rules-eval.d.ts.map +1 -1
- package/dist/database/sandbox/rules-eval.js +136 -9
- package/dist/database/sandbox/rules-eval.js.map +1 -1
- package/dist/database/sandbox/transactions.d.ts.map +1 -1
- package/dist/database/sandbox/transactions.js +17 -38
- package/dist/database/sandbox/transactions.js.map +1 -1
- package/dist/database/sandbox/value-listeners.d.ts +11 -1
- package/dist/database/sandbox/value-listeners.d.ts.map +1 -1
- package/dist/database/sandbox/value-listeners.js +65 -27
- package/dist/database/sandbox/value-listeners.js.map +1 -1
- package/dist/database/sandbox/write-plane.d.ts.map +1 -1
- package/dist/database/sandbox/write-plane.js +30 -22
- package/dist/database/sandbox/write-plane.js.map +1 -1
- package/dist/database/sdk-activity.d.ts +5 -0
- package/dist/database/sdk-activity.d.ts.map +1 -0
- package/dist/database/sdk-activity.js +20 -0
- package/dist/database/sdk-activity.js.map +1 -0
- package/dist/database/transactions.d.ts.map +1 -1
- package/dist/database/transactions.js +7 -3
- package/dist/database/transactions.js.map +1 -1
- package/dist/database/types.d.ts +9 -1
- package/dist/database/types.d.ts.map +1 -1
- package/dist/database/types.js.map +1 -1
- package/dist/deferred/entry.d.ts +6 -3
- package/dist/deferred/entry.d.ts.map +1 -1
- package/dist/deferred/entry.js +13 -10
- package/dist/deferred/entry.js.map +1 -1
- package/dist/firestore/activity-coverage.d.ts +9 -0
- package/dist/firestore/activity-coverage.d.ts.map +1 -0
- package/dist/firestore/activity-coverage.js +9 -0
- package/dist/firestore/activity-coverage.js.map +1 -0
- package/dist/firestore/aggregates.d.ts.map +1 -1
- package/dist/firestore/aggregates.js +32 -10
- package/dist/firestore/aggregates.js.map +1 -1
- package/dist/firestore/bytes.d.ts +13 -0
- package/dist/firestore/bytes.d.ts.map +1 -0
- package/dist/firestore/bytes.js +51 -0
- package/dist/firestore/bytes.js.map +1 -0
- package/dist/firestore/converter-method.d.ts +11 -0
- package/dist/firestore/converter-method.d.ts.map +1 -0
- package/dist/firestore/converter-method.js +39 -0
- package/dist/firestore/converter-method.js.map +1 -0
- package/dist/firestore/errors.d.ts.map +1 -1
- package/dist/firestore/errors.js +4 -0
- package/dist/firestore/errors.js.map +1 -1
- package/dist/firestore/field-values.d.ts +3 -36
- package/dist/firestore/field-values.d.ts.map +1 -1
- package/dist/firestore/field-values.js +3 -136
- package/dist/firestore/field-values.js.map +1 -1
- package/dist/firestore/geo-point.d.ts +15 -0
- package/dist/firestore/geo-point.d.ts.map +1 -0
- package/dist/firestore/geo-point.js +50 -0
- package/dist/firestore/geo-point.js.map +1 -0
- package/dist/firestore/index.d.ts +1 -1
- package/dist/firestore/index.d.ts.map +1 -1
- package/dist/firestore/index.js +1 -1
- package/dist/firestore/index.js.map +1 -1
- package/dist/firestore/instances.d.ts.map +1 -1
- package/dist/firestore/instances.js +23 -2
- package/dist/firestore/instances.js.map +1 -1
- package/dist/firestore/internal/document-data.d.ts +3 -0
- package/dist/firestore/internal/document-data.d.ts.map +1 -0
- package/dist/firestore/internal/document-data.js +10 -0
- package/dist/firestore/internal/document-data.js.map +1 -0
- package/dist/firestore/internal/index.d.ts +3 -0
- package/dist/firestore/internal/index.d.ts.map +1 -1
- package/dist/firestore/internal/index.js +5 -0
- package/dist/firestore/internal/index.js.map +1 -1
- package/dist/firestore/internal/value-codec.d.ts +16 -61
- package/dist/firestore/internal/value-codec.d.ts.map +1 -1
- package/dist/firestore/internal/value-codec.js +137 -82
- package/dist/firestore/internal/value-codec.js.map +1 -1
- package/dist/firestore/internal/value-depth.d.ts +3 -0
- package/dist/firestore/internal/value-depth.d.ts.map +1 -0
- package/dist/firestore/internal/value-depth.js +19 -0
- package/dist/firestore/internal/value-depth.js.map +1 -0
- package/dist/firestore/listeners.d.ts +18 -1
- package/dist/firestore/listeners.d.ts.map +1 -1
- package/dist/firestore/listeners.js +60 -21
- package/dist/firestore/listeners.js.map +1 -1
- package/dist/firestore/persistence.d.ts +0 -9
- package/dist/firestore/persistence.d.ts.map +1 -1
- package/dist/firestore/persistence.js +23 -9
- package/dist/firestore/persistence.js.map +1 -1
- package/dist/firestore/plain-object.d.ts +3 -0
- package/dist/firestore/plain-object.d.ts.map +1 -0
- package/dist/firestore/plain-object.js +9 -0
- package/dist/firestore/plain-object.js.map +1 -0
- package/dist/firestore/query-constraints.d.ts.map +1 -1
- package/dist/firestore/query-constraints.js +4 -3
- package/dist/firestore/query-constraints.js.map +1 -1
- package/dist/firestore/reads.d.ts +9 -7
- package/dist/firestore/reads.d.ts.map +1 -1
- package/dist/firestore/reads.js +74 -36
- package/dist/firestore/reads.js.map +1 -1
- package/dist/firestore/refs.d.ts +2 -1
- package/dist/firestore/refs.d.ts.map +1 -1
- package/dist/firestore/refs.js +37 -24
- package/dist/firestore/refs.js.map +1 -1
- package/dist/firestore/sandbox/activity-query-display.d.ts +67 -0
- package/dist/firestore/sandbox/activity-query-display.d.ts.map +1 -0
- package/dist/firestore/sandbox/activity-query-display.js +119 -0
- package/dist/firestore/sandbox/activity-query-display.js.map +1 -0
- package/dist/firestore/sandbox/admin-compat/batch.d.ts +4 -8
- package/dist/firestore/sandbox/admin-compat/batch.d.ts.map +1 -1
- package/dist/firestore/sandbox/admin-compat/batch.js +27 -19
- package/dist/firestore/sandbox/admin-compat/batch.js.map +1 -1
- package/dist/firestore/sandbox/admin-compat/query-comparison.d.ts.map +1 -1
- package/dist/firestore/sandbox/admin-compat/query-comparison.js +8 -3
- package/dist/firestore/sandbox/admin-compat/query-comparison.js.map +1 -1
- package/dist/firestore/sandbox/admin-compat/query.d.ts +8 -0
- package/dist/firestore/sandbox/admin-compat/query.d.ts.map +1 -1
- package/dist/firestore/sandbox/admin-compat/query.js +44 -5
- package/dist/firestore/sandbox/admin-compat/query.js.map +1 -1
- package/dist/firestore/sandbox/admin-compat/read-translation.d.ts.map +1 -1
- package/dist/firestore/sandbox/admin-compat/read-translation.js +18 -9
- package/dist/firestore/sandbox/admin-compat/read-translation.js.map +1 -1
- package/dist/firestore/sandbox/admin-compat/transaction.d.ts +2 -2
- package/dist/firestore/sandbox/admin-compat/transaction.d.ts.map +1 -1
- package/dist/firestore/sandbox/admin-compat/transaction.js +13 -4
- package/dist/firestore/sandbox/admin-compat/transaction.js.map +1 -1
- package/dist/firestore/sandbox/admin-compat/types.d.ts +6 -33
- package/dist/firestore/sandbox/admin-compat/types.d.ts.map +1 -1
- package/dist/firestore/sandbox/admin-compat/types.js +1 -76
- package/dist/firestore/sandbox/admin-compat/types.js.map +1 -1
- package/dist/firestore/sandbox/atomic-state.d.ts +4 -0
- package/dist/firestore/sandbox/atomic-state.d.ts.map +1 -0
- package/dist/firestore/sandbox/atomic-state.js +105 -0
- package/dist/firestore/sandbox/atomic-state.js.map +1 -0
- package/dist/firestore/sandbox/atomic-write-pipeline.d.ts +3 -2
- package/dist/firestore/sandbox/atomic-write-pipeline.d.ts.map +1 -1
- package/dist/firestore/sandbox/atomic-write-pipeline.js +128 -58
- package/dist/firestore/sandbox/atomic-write-pipeline.js.map +1 -1
- package/dist/firestore/sandbox/batch-write-executor.d.ts.map +1 -1
- package/dist/firestore/sandbox/batch-write-executor.js +54 -28
- package/dist/firestore/sandbox/batch-write-executor.js.map +1 -1
- package/dist/firestore/sandbox/converters/user-timestamp.d.ts +6 -40
- package/dist/firestore/sandbox/converters/user-timestamp.d.ts.map +1 -1
- package/dist/firestore/sandbox/converters/user-timestamp.js +20 -43
- package/dist/firestore/sandbox/converters/user-timestamp.js.map +1 -1
- package/dist/firestore/sandbox/document-copy.d.ts +4 -0
- package/dist/firestore/sandbox/document-copy.d.ts.map +1 -0
- package/dist/firestore/sandbox/document-copy.js +28 -0
- package/dist/firestore/sandbox/document-copy.js.map +1 -0
- package/dist/firestore/sandbox/document-store.d.ts +99 -0
- package/dist/firestore/sandbox/document-store.d.ts.map +1 -0
- package/dist/firestore/sandbox/document-store.js +2 -0
- package/dist/firestore/sandbox/document-store.js.map +1 -0
- package/dist/firestore/sandbox/errors.d.ts +4 -1
- package/dist/firestore/sandbox/errors.d.ts.map +1 -1
- package/dist/firestore/sandbox/errors.js +2 -25
- package/dist/firestore/sandbox/errors.js.map +1 -1
- package/dist/firestore/sandbox/event-log.d.ts +22 -4
- package/dist/firestore/sandbox/event-log.d.ts.map +1 -1
- package/dist/firestore/sandbox/event-log.js +66 -6
- package/dist/firestore/sandbox/event-log.js.map +1 -1
- package/dist/firestore/sandbox/field-merge.d.ts.map +1 -1
- package/dist/firestore/sandbox/field-merge.js +10 -20
- package/dist/firestore/sandbox/field-merge.js.map +1 -1
- package/dist/firestore/sandbox/history-controls.d.ts +1 -1
- package/dist/firestore/sandbox/history-controls.d.ts.map +1 -1
- package/dist/firestore/sandbox/history-controls.js +1 -1
- package/dist/firestore/sandbox/history-controls.js.map +1 -1
- package/dist/firestore/sandbox/list-query-proof.d.ts +4 -1
- package/dist/firestore/sandbox/list-query-proof.d.ts.map +1 -1
- package/dist/firestore/sandbox/list-query-proof.js +32 -96
- package/dist/firestore/sandbox/list-query-proof.js.map +1 -1
- package/dist/firestore/sandbox/listener-dispatch.d.ts +26 -1
- package/dist/firestore/sandbox/listener-dispatch.d.ts.map +1 -1
- package/dist/firestore/sandbox/listener-dispatch.js +58 -5
- package/dist/firestore/sandbox/listener-dispatch.js.map +1 -1
- package/dist/firestore/sandbox/local-environment.d.ts +16 -2
- package/dist/firestore/sandbox/local-environment.d.ts.map +1 -1
- package/dist/firestore/sandbox/local-environment.js +33 -9
- package/dist/firestore/sandbox/local-environment.js.map +1 -1
- package/dist/firestore/sandbox/local-state.d.ts +5 -99
- package/dist/firestore/sandbox/local-state.d.ts.map +1 -1
- package/dist/firestore/sandbox/local-state.js +64 -117
- package/dist/firestore/sandbox/local-state.js.map +1 -1
- package/dist/firestore/sandbox/query-execution.d.ts +4 -1
- package/dist/firestore/sandbox/query-execution.d.ts.map +1 -1
- package/dist/firestore/sandbox/query-execution.js +51 -26
- package/dist/firestore/sandbox/query-execution.js.map +1 -1
- package/dist/firestore/sandbox/query-operand-equality.d.ts.map +1 -1
- package/dist/firestore/sandbox/query-operand-equality.js +50 -14
- package/dist/firestore/sandbox/query-operand-equality.js.map +1 -1
- package/dist/firestore/sandbox/query-operators.d.ts +4 -0
- package/dist/firestore/sandbox/query-operators.d.ts.map +1 -0
- package/dist/firestore/sandbox/query-operators.js +17 -0
- package/dist/firestore/sandbox/query-operators.js.map +1 -0
- package/dist/firestore/sandbox/query-value-registry.d.ts +1 -1
- package/dist/firestore/sandbox/query-value-registry.d.ts.map +1 -1
- package/dist/firestore/sandbox/query-value-registry.js +3 -1
- package/dist/firestore/sandbox/query-value-registry.js.map +1 -1
- package/dist/firestore/sandbox/request-events.d.ts +3 -0
- package/dist/firestore/sandbox/request-events.d.ts.map +1 -1
- package/dist/firestore/sandbox/request-events.js +4 -0
- package/dist/firestore/sandbox/request-events.js.map +1 -1
- package/dist/firestore/sandbox/rules-evidence.d.ts +7 -0
- package/dist/firestore/sandbox/rules-evidence.d.ts.map +1 -0
- package/dist/firestore/sandbox/rules-evidence.js +87 -0
- package/dist/firestore/sandbox/rules-evidence.js.map +1 -0
- package/dist/firestore/sandbox/rules-list-authorizer.d.ts +13 -1
- package/dist/firestore/sandbox/rules-list-authorizer.d.ts.map +1 -1
- package/dist/firestore/sandbox/rules-list-authorizer.js +53 -74
- package/dist/firestore/sandbox/rules-list-authorizer.js.map +1 -1
- package/dist/firestore/sandbox/rules-operation-reader.d.ts +8 -1
- package/dist/firestore/sandbox/rules-operation-reader.d.ts.map +1 -1
- package/dist/firestore/sandbox/rules-operation-reader.js +13 -5
- package/dist/firestore/sandbox/rules-operation-reader.js.map +1 -1
- package/dist/firestore/sandbox/rules-read-engine.d.ts +8 -1
- package/dist/firestore/sandbox/rules-read-engine.d.ts.map +1 -1
- package/dist/firestore/sandbox/rules-read-engine.js +21 -10
- package/dist/firestore/sandbox/rules-read-engine.js.map +1 -1
- package/dist/firestore/sandbox/rules-state.d.ts +5 -0
- package/dist/firestore/sandbox/rules-state.d.ts.map +1 -1
- package/dist/firestore/sandbox/rules-state.js +16 -0
- package/dist/firestore/sandbox/rules-state.js.map +1 -1
- package/dist/firestore/sandbox/snapshot-listeners.d.ts +9 -1
- package/dist/firestore/sandbox/snapshot-listeners.d.ts.map +1 -1
- package/dist/firestore/sandbox/snapshot-listeners.js.map +1 -1
- package/dist/firestore/sandbox/transaction-merge.d.ts +2 -33
- package/dist/firestore/sandbox/transaction-merge.d.ts.map +1 -1
- package/dist/firestore/sandbox/transaction-merge.js +19 -7
- package/dist/firestore/sandbox/transaction-merge.js.map +1 -1
- package/dist/firestore/sandbox/transaction-types.d.ts +11 -21
- package/dist/firestore/sandbox/transaction-types.d.ts.map +1 -1
- package/dist/firestore/sandbox/transaction-types.js.map +1 -1
- package/dist/firestore/sandbox/transaction-write-executor.d.ts +2 -1
- package/dist/firestore/sandbox/transaction-write-executor.d.ts.map +1 -1
- package/dist/firestore/sandbox/transaction-write-executor.js +110 -69
- package/dist/firestore/sandbox/transaction-write-executor.js.map +1 -1
- package/dist/firestore/sandbox/transaction.d.ts +3 -2
- package/dist/firestore/sandbox/transaction.d.ts.map +1 -1
- package/dist/firestore/sandbox/transaction.js +23 -6
- package/dist/firestore/sandbox/transaction.js.map +1 -1
- package/dist/firestore/sandbox/value-resolver.d.ts +1 -8
- package/dist/firestore/sandbox/value-resolver.d.ts.map +1 -1
- package/dist/firestore/sandbox/value-resolver.js +2 -13
- package/dist/firestore/sandbox/value-resolver.js.map +1 -1
- package/dist/firestore/sandbox/write-engine.d.ts +5 -1
- package/dist/firestore/sandbox/write-engine.d.ts.map +1 -1
- package/dist/firestore/sandbox/write-engine.js +14 -7
- package/dist/firestore/sandbox/write-engine.js.map +1 -1
- package/dist/firestore/sandbox/write-runtime.d.ts +12 -4
- package/dist/firestore/sandbox/write-runtime.d.ts.map +1 -1
- package/dist/firestore/sandbox/write-runtime.js +72 -38
- package/dist/firestore/sandbox/write-runtime.js.map +1 -1
- package/dist/firestore/sandbox/writes.d.ts +3 -1
- package/dist/firestore/sandbox/writes.d.ts.map +1 -1
- package/dist/firestore/sdk-activity.d.ts +8 -0
- package/dist/firestore/sdk-activity.d.ts.map +1 -0
- package/dist/firestore/sdk-activity.js +23 -0
- package/dist/firestore/sdk-activity.js.map +1 -0
- package/dist/firestore/snapshots.d.ts +18 -2
- package/dist/firestore/snapshots.d.ts.map +1 -1
- package/dist/firestore/snapshots.js +69 -16
- package/dist/firestore/snapshots.js.map +1 -1
- package/dist/firestore/state.d.ts +8 -3
- package/dist/firestore/state.d.ts.map +1 -1
- package/dist/firestore/state.js +30 -13
- package/dist/firestore/state.js.map +1 -1
- package/dist/firestore/timestamp.d.ts +28 -0
- package/dist/firestore/timestamp.d.ts.map +1 -0
- package/dist/firestore/timestamp.js +80 -0
- package/dist/firestore/timestamp.js.map +1 -0
- package/dist/firestore/tools.d.ts.map +1 -1
- package/dist/firestore/tools.js +2 -4
- package/dist/firestore/tools.js.map +1 -1
- package/dist/firestore/transactions.d.ts.map +1 -1
- package/dist/firestore/transactions.js +76 -3
- package/dist/firestore/transactions.js.map +1 -1
- package/dist/firestore/types.d.ts +26 -5
- package/dist/firestore/types.d.ts.map +1 -1
- package/dist/firestore/types.js.map +1 -1
- package/dist/firestore/vector-value.d.ts +11 -0
- package/dist/firestore/vector-value.d.ts.map +1 -0
- package/dist/firestore/vector-value.js +51 -0
- package/dist/firestore/vector-value.js.map +1 -0
- package/dist/firestore/writes.d.ts +0 -7
- package/dist/firestore/writes.d.ts.map +1 -1
- package/dist/firestore/writes.js +42 -25
- package/dist/firestore/writes.js.map +1 -1
- package/dist/functions/events.d.ts +12 -0
- package/dist/functions/events.d.ts.map +1 -0
- package/dist/functions/events.js +10 -0
- package/dist/functions/events.js.map +1 -0
- package/dist/messaging/broker/broker.d.ts +43 -30
- package/dist/messaging/broker/broker.d.ts.map +1 -1
- package/dist/messaging/broker/broker.js +148 -43
- package/dist/messaging/broker/broker.js.map +1 -1
- package/dist/messaging/broker/delivery-history.d.ts +5 -0
- package/dist/messaging/broker/delivery-history.d.ts.map +1 -0
- package/dist/messaging/broker/delivery-history.js +46 -0
- package/dist/messaging/broker/delivery-history.js.map +1 -0
- package/dist/messaging/broker/index.d.ts +2 -1
- package/dist/messaging/broker/index.d.ts.map +1 -1
- package/dist/messaging/broker/index.js +7 -0
- package/dist/messaging/broker/index.js.map +1 -1
- package/dist/messaging/broker/persistence.d.ts +12 -0
- package/dist/messaging/broker/persistence.d.ts.map +1 -0
- package/dist/messaging/broker/persistence.js +42 -0
- package/dist/messaging/broker/persistence.js.map +1 -0
- package/dist/messaging/broker/types.d.ts +44 -0
- package/dist/messaging/broker/types.d.ts.map +1 -1
- package/dist/messaging/broker/types.js +10 -1
- package/dist/messaging/broker/types.js.map +1 -1
- package/dist/messaging/events.d.ts +12 -0
- package/dist/messaging/events.d.ts.map +1 -0
- package/dist/messaging/events.js +19 -0
- package/dist/messaging/events.js.map +1 -0
- package/dist/rules/api/case-types.d.ts +7 -0
- package/dist/rules/api/case-types.d.ts.map +1 -1
- package/dist/rules/api/rtdb.d.ts.map +1 -1
- package/dist/rules/api/rtdb.js +20 -7
- package/dist/rules/api/rtdb.js.map +1 -1
- package/dist/rules/grammar/parse-error-wording.d.ts +31 -0
- package/dist/rules/grammar/parse-error-wording.d.ts.map +1 -0
- package/dist/rules/grammar/parse-error-wording.js +86 -0
- package/dist/rules/grammar/parse-error-wording.js.map +1 -0
- package/dist/rules/indexes/query-analysis.d.ts +33 -0
- package/dist/rules/indexes/query-analysis.d.ts.map +1 -0
- package/dist/rules/indexes/query-analysis.js +153 -0
- package/dist/rules/indexes/query-analysis.js.map +1 -0
- package/dist/rules/indexes/service-query.d.ts +48 -0
- package/dist/rules/indexes/service-query.d.ts.map +1 -0
- package/dist/rules/indexes/service-query.js +60 -0
- package/dist/rules/indexes/service-query.js.map +1 -0
- package/dist/rules/internal/index.d.ts +4 -0
- package/dist/rules/internal/index.d.ts.map +1 -1
- package/dist/rules/internal/index.js +10 -0
- package/dist/rules/internal/index.js.map +1 -1
- package/dist/rules/modules/rules-capabilities.generated.d.ts +1 -1
- package/dist/rules/modules/rules-capabilities.generated.js +1 -1
- package/dist/rules/modules/rules-capabilities.generated.js.map +1 -1
- package/dist/rules/rtdb/constraints/atoms.d.ts.map +1 -1
- package/dist/rules/rtdb/constraints/atoms.js +7 -7
- package/dist/rules/rtdb/constraints/atoms.js.map +1 -1
- package/dist/rules/rtdb/constraints/data.d.ts +2 -2
- package/dist/rules/rtdb/constraints/data.d.ts.map +1 -1
- package/dist/rules/rtdb/constraints/data.js +4 -4
- package/dist/rules/rtdb/constraints/data.js.map +1 -1
- package/dist/rules/rtdb/constraints/document.d.ts.map +1 -1
- package/dist/rules/rtdb/constraints/document.js +6 -2
- package/dist/rules/rtdb/constraints/document.js.map +1 -1
- package/dist/rules/rtdb/constraints/policies.d.ts +2 -2
- package/dist/rules/rtdb/constraints/policies.d.ts.map +1 -1
- package/dist/rules/rtdb/constraints/policies.js +3 -3
- package/dist/rules/rtdb/constraints/policies.js.map +1 -1
- package/dist/rules/rtdb/constraints/schema.js +3 -3
- package/dist/rules/rtdb/constraints/schema.js.map +1 -1
- package/dist/rules/rtdb/grammar/RtdbExpr.ohm +1 -3
- package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.d.ts +1 -1
- package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.d.ts.map +1 -1
- package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.js +1 -3
- package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.js.map +1 -1
- package/dist/rules/rtdb/grammar/linter.d.ts.map +1 -1
- package/dist/rules/rtdb/grammar/linter.js +28 -30
- package/dist/rules/rtdb/grammar/linter.js.map +1 -1
- package/dist/rules/rtdb/grammar/simulator.d.ts +15 -1
- package/dist/rules/rtdb/grammar/simulator.d.ts.map +1 -1
- package/dist/rules/rtdb/grammar/simulator.js +93 -65
- package/dist/rules/rtdb/grammar/simulator.js.map +1 -1
- package/dist/rules/rtdb/grammar/validator.d.ts.map +1 -1
- package/dist/rules/rtdb/grammar/validator.js +25 -26
- package/dist/rules/rtdb/grammar/validator.js.map +1 -1
- package/dist/rules/rtdb/simulation/handler.d.ts.map +1 -1
- package/dist/rules/rtdb/simulation/handler.js +136 -32
- package/dist/rules/rtdb/simulation/handler.js.map +1 -1
- package/dist/rules/rtdb/simulation/spec.d.ts +95 -5
- package/dist/rules/rtdb/simulation/spec.d.ts.map +1 -1
- package/dist/rules/rtdb/simulation/spec.js +22 -1
- package/dist/rules/rtdb/simulation/spec.js.map +1 -1
- package/dist/rules/rtdb/types.d.ts +18 -18
- package/dist/rules/simulator/evaluator.js +35 -69
- package/dist/rules/simulator/evaluator.js.map +1 -1
- package/dist/rules/simulator/handler.d.ts.map +1 -1
- package/dist/rules/simulator/handler.js +12 -3
- package/dist/rules/simulator/handler.js.map +1 -1
- package/dist/rules/simulator/mapdiff.d.ts +2 -0
- package/dist/rules/simulator/mapdiff.d.ts.map +1 -1
- package/dist/rules/simulator/mapdiff.js +7 -5
- package/dist/rules/simulator/mapdiff.js.map +1 -1
- package/dist/rules/simulator/query-proof-residual.d.ts +11 -0
- package/dist/rules/simulator/query-proof-residual.d.ts.map +1 -0
- package/dist/rules/simulator/query-proof-residual.js +177 -0
- package/dist/rules/simulator/query-proof-residual.js.map +1 -0
- package/dist/rules/simulator/query-proof.d.ts +21 -47
- package/dist/rules/simulator/query-proof.d.ts.map +1 -1
- package/dist/rules/simulator/query-proof.js +78 -13
- package/dist/rules/simulator/query-proof.js.map +1 -1
- package/dist/rules/simulator/request-path.d.ts +26 -0
- package/dist/rules/simulator/request-path.d.ts.map +1 -0
- package/dist/rules/simulator/request-path.js +36 -0
- package/dist/rules/simulator/request-path.js.map +1 -0
- package/dist/rules/simulator/trace-recorder.d.ts +1 -0
- package/dist/rules/simulator/trace-recorder.d.ts.map +1 -1
- package/dist/rules/simulator/trace-recorder.js +4 -0
- package/dist/rules/simulator/trace-recorder.js.map +1 -1
- package/dist/rules/simulator/wrappers/timestamp.d.ts +6 -0
- package/dist/rules/simulator/wrappers/timestamp.d.ts.map +1 -1
- package/dist/rules/simulator/wrappers/timestamp.js +8 -1
- package/dist/rules/simulator/wrappers/timestamp.js.map +1 -1
- package/dist/rules/simulator-tools-impl.d.ts.map +1 -1
- package/dist/rules/simulator-tools-impl.js +6 -3
- package/dist/rules/simulator-tools-impl.js.map +1 -1
- package/dist/rules/stdlib-tools.js +4 -4
- package/dist/rules/stdlib-tools.js.map +1 -1
- package/dist/rules/test/spec.d.ts +4 -4
- package/dist/sandbox/active-listeners.d.ts +69 -0
- package/dist/sandbox/active-listeners.d.ts.map +1 -0
- package/dist/sandbox/active-listeners.js +159 -0
- package/dist/sandbox/active-listeners.js.map +1 -0
- package/dist/sandbox/admin-firestore/error-translation.d.ts.map +1 -1
- package/dist/sandbox/admin-firestore/error-translation.js +15 -2
- package/dist/sandbox/admin-firestore/error-translation.js.map +1 -1
- package/dist/sandbox/admin-firestore/listeners.d.ts +0 -25
- package/dist/sandbox/admin-firestore/listeners.d.ts.map +1 -1
- package/dist/sandbox/admin-firestore/listeners.js +26 -2
- package/dist/sandbox/admin-firestore/listeners.js.map +1 -1
- package/dist/sandbox/admin-firestore/remote/listeners.d.ts.map +1 -1
- package/dist/sandbox/admin-firestore/remote/listeners.js +50 -29
- package/dist/sandbox/admin-firestore/remote/listeners.js.map +1 -1
- package/dist/sandbox/admin-firestore/remote/value-codec.d.ts +5 -12
- package/dist/sandbox/admin-firestore/remote/value-codec.d.ts.map +1 -1
- package/dist/sandbox/admin-firestore/remote/value-codec.js +7 -14
- package/dist/sandbox/admin-firestore/remote/value-codec.js.map +1 -1
- package/dist/sandbox/admin-firestore/remote/wire-types.d.ts +2 -0
- package/dist/sandbox/admin-firestore/remote/wire-types.d.ts.map +1 -1
- package/dist/sandbox/attribution/attribution-mode.d.ts +36 -0
- package/dist/sandbox/attribution/attribution-mode.d.ts.map +1 -0
- package/dist/sandbox/attribution/attribution-mode.js +68 -0
- package/dist/sandbox/attribution/attribution-mode.js.map +1 -0
- package/dist/sandbox/attribution/effect-regions.d.ts +37 -0
- package/dist/sandbox/attribution/effect-regions.d.ts.map +1 -0
- package/dist/sandbox/attribution/effect-regions.js +114 -0
- package/dist/sandbox/attribution/effect-regions.js.map +1 -0
- package/dist/sandbox/attribution/element-selector.d.ts +42 -0
- package/dist/sandbox/attribution/element-selector.d.ts.map +1 -0
- package/dist/sandbox/attribution/element-selector.js +109 -0
- package/dist/sandbox/attribution/element-selector.js.map +1 -0
- package/dist/sandbox/attribution/listener-owners.d.ts +111 -0
- package/dist/sandbox/attribution/listener-owners.d.ts.map +1 -0
- package/dist/sandbox/attribution/listener-owners.js +215 -0
- package/dist/sandbox/attribution/listener-owners.js.map +1 -0
- package/dist/sandbox/branches/engine.d.ts +129 -0
- package/dist/sandbox/branches/engine.d.ts.map +1 -0
- package/dist/sandbox/branches/engine.js +280 -0
- package/dist/sandbox/branches/engine.js.map +1 -0
- package/dist/sandbox/branches/index.d.ts +12 -139
- package/dist/sandbox/branches/index.d.ts.map +1 -1
- package/dist/sandbox/branches/index.js +8 -390
- package/dist/sandbox/branches/index.js.map +1 -1
- package/dist/sandbox/branches/promotion.d.ts +27 -0
- package/dist/sandbox/branches/promotion.d.ts.map +1 -0
- package/dist/sandbox/branches/promotion.js +160 -0
- package/dist/sandbox/branches/promotion.js.map +1 -0
- package/dist/sandbox/branches/state-diff.d.ts +66 -0
- package/dist/sandbox/branches/state-diff.d.ts.map +1 -0
- package/dist/sandbox/branches/state-diff.js +270 -0
- package/dist/sandbox/branches/state-diff.js.map +1 -0
- package/dist/sandbox/branches/store.d.ts +64 -0
- package/dist/sandbox/branches/store.d.ts.map +1 -0
- package/dist/sandbox/branches/store.js +264 -0
- package/dist/sandbox/branches/store.js.map +1 -0
- package/dist/sandbox/checkpoints/capture.d.ts +39 -0
- package/dist/sandbox/checkpoints/capture.d.ts.map +1 -0
- package/dist/sandbox/checkpoints/capture.js +69 -0
- package/dist/sandbox/checkpoints/capture.js.map +1 -0
- package/dist/sandbox/checkpoints/directory-backend.d.ts +30 -0
- package/dist/sandbox/checkpoints/directory-backend.d.ts.map +1 -0
- package/dist/sandbox/checkpoints/directory-backend.js +98 -0
- package/dist/sandbox/checkpoints/directory-backend.js.map +1 -0
- package/dist/sandbox/checkpoints/index.d.ts +15 -0
- package/dist/sandbox/checkpoints/index.d.ts.map +1 -0
- package/dist/sandbox/checkpoints/index.js +13 -0
- package/dist/sandbox/checkpoints/index.js.map +1 -0
- package/dist/sandbox/checkpoints/record-backend.d.ts +25 -0
- package/dist/sandbox/checkpoints/record-backend.d.ts.map +1 -0
- package/dist/sandbox/checkpoints/record-backend.js +81 -0
- package/dist/sandbox/checkpoints/record-backend.js.map +1 -0
- package/dist/sandbox/checkpoints/saved-states.d.ts +35 -0
- package/dist/sandbox/checkpoints/saved-states.d.ts.map +1 -0
- package/dist/sandbox/checkpoints/saved-states.js +47 -0
- package/dist/sandbox/checkpoints/saved-states.js.map +1 -0
- package/dist/sandbox/checkpoints/types.d.ts +84 -0
- package/dist/sandbox/checkpoints/types.d.ts.map +1 -0
- package/dist/sandbox/checkpoints/types.js +51 -0
- package/dist/sandbox/checkpoints/types.js.map +1 -0
- package/dist/sandbox/checkpoints/validation.d.ts +3 -0
- package/dist/sandbox/checkpoints/validation.d.ts.map +1 -0
- package/dist/sandbox/checkpoints/validation.js +99 -0
- package/dist/sandbox/checkpoints/validation.js.map +1 -0
- package/dist/sandbox/clock.d.ts +121 -0
- package/dist/sandbox/clock.d.ts.map +1 -0
- package/dist/sandbox/clock.js +167 -0
- package/dist/sandbox/clock.js.map +1 -0
- package/dist/sandbox/full-state.d.ts +160 -0
- package/dist/sandbox/full-state.d.ts.map +1 -0
- package/dist/sandbox/full-state.js +267 -0
- package/dist/sandbox/full-state.js.map +1 -0
- package/dist/sandbox/index.d.ts +13 -6
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +23 -9
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/internal/ai-evidence.d.ts +27 -0
- package/dist/sandbox/internal/ai-evidence.d.ts.map +1 -0
- package/dist/sandbox/internal/ai-evidence.js +29 -0
- package/dist/sandbox/internal/ai-evidence.js.map +1 -0
- package/dist/sandbox/internal/event-history.d.ts +32 -0
- package/dist/sandbox/internal/event-history.d.ts.map +1 -0
- package/dist/sandbox/internal/event-history.js +199 -0
- package/dist/sandbox/internal/event-history.js.map +1 -0
- package/dist/sandbox/internal/history-integrity.d.ts +3 -0
- package/dist/sandbox/internal/history-integrity.d.ts.map +1 -0
- package/dist/sandbox/internal/history-integrity.js +12 -0
- package/dist/sandbox/internal/history-integrity.js.map +1 -0
- package/dist/sandbox/internal/history-retention.d.ts +6 -0
- package/dist/sandbox/internal/history-retention.d.ts.map +1 -0
- package/dist/sandbox/internal/history-retention.js +12 -0
- package/dist/sandbox/internal/history-retention.js.map +1 -0
- package/dist/sandbox/internal/index.d.ts +27 -0
- package/dist/sandbox/internal/index.d.ts.map +1 -1
- package/dist/sandbox/internal/index.js +26 -0
- package/dist/sandbox/internal/index.js.map +1 -1
- package/dist/sandbox/internal/observation-history.d.ts +6 -0
- package/dist/sandbox/internal/observation-history.d.ts.map +1 -0
- package/dist/sandbox/internal/observation-history.js +6 -0
- package/dist/sandbox/internal/observation-history.js.map +1 -0
- package/dist/sandbox/internal/observation-payload.d.ts +6 -0
- package/dist/sandbox/internal/observation-payload.d.ts.map +1 -0
- package/dist/sandbox/internal/observation-payload.js +24 -0
- package/dist/sandbox/internal/observation-payload.js.map +1 -0
- package/dist/sandbox/internal/provenance.d.ts +0 -1
- package/dist/sandbox/internal/provenance.d.ts.map +1 -1
- package/dist/sandbox/internal/provenance.js +6 -0
- package/dist/sandbox/internal/provenance.js.map +1 -1
- package/dist/sandbox/internal/root.d.ts +2 -1
- package/dist/sandbox/internal/root.d.ts.map +1 -1
- package/dist/sandbox/internal/root.js +2 -2
- package/dist/sandbox/internal/root.js.map +1 -1
- package/dist/sandbox/internal/rules-evidence-retention.d.ts +11 -0
- package/dist/sandbox/internal/rules-evidence-retention.d.ts.map +1 -0
- package/dist/sandbox/internal/rules-evidence-retention.js +27 -0
- package/dist/sandbox/internal/rules-evidence-retention.js.map +1 -0
- package/dist/sandbox/internal/sandbox-impl.d.ts +40 -33
- package/dist/sandbox/internal/sandbox-impl.d.ts.map +1 -1
- package/dist/sandbox/internal/sandbox-impl.js +83 -40
- package/dist/sandbox/internal/sandbox-impl.js.map +1 -1
- package/dist/sandbox/internal/sdk-activity.d.ts +112 -0
- package/dist/sandbox/internal/sdk-activity.d.ts.map +1 -0
- package/dist/sandbox/internal/sdk-activity.js +240 -0
- package/dist/sandbox/internal/sdk-activity.js.map +1 -0
- package/dist/sandbox/internal/sdk-coverage.d.ts +10 -0
- package/dist/sandbox/internal/sdk-coverage.d.ts.map +1 -0
- package/dist/sandbox/internal/sdk-coverage.js +21 -0
- package/dist/sandbox/internal/sdk-coverage.js.map +1 -0
- package/dist/sandbox/internal/sdk-observation.d.ts +32 -0
- package/dist/sandbox/internal/sdk-observation.d.ts.map +1 -0
- package/dist/sandbox/internal/sdk-observation.js +29 -0
- package/dist/sandbox/internal/sdk-observation.js.map +1 -0
- package/dist/sandbox/internal/sdk-rates.d.ts +97 -0
- package/dist/sandbox/internal/sdk-rates.d.ts.map +1 -0
- package/dist/sandbox/internal/sdk-rates.js +187 -0
- package/dist/sandbox/internal/sdk-rates.js.map +1 -0
- package/dist/sandbox/internal/sdk-write-activity.d.ts +5 -0
- package/dist/sandbox/internal/sdk-write-activity.d.ts.map +1 -0
- package/dist/sandbox/internal/sdk-write-activity.js +13 -0
- package/dist/sandbox/internal/sdk-write-activity.js.map +1 -0
- package/dist/sandbox/internal/state-schemas.d.ts +120 -0
- package/dist/sandbox/internal/state-schemas.d.ts.map +1 -0
- package/dist/sandbox/internal/state-schemas.js +42 -0
- package/dist/sandbox/internal/state-schemas.js.map +1 -0
- package/dist/sandbox/internal/state-values.d.ts +6 -0
- package/dist/sandbox/internal/state-values.d.ts.map +1 -0
- package/dist/sandbox/internal/state-values.js +15 -0
- package/dist/sandbox/internal/state-values.js.map +1 -0
- package/dist/sandbox/internal/storage-activity.d.ts +13 -0
- package/dist/sandbox/internal/storage-activity.d.ts.map +1 -0
- package/dist/sandbox/internal/storage-activity.js +48 -0
- package/dist/sandbox/internal/storage-activity.js.map +1 -0
- package/dist/sandbox/internal/usage-evidence.d.ts +24 -0
- package/dist/sandbox/internal/usage-evidence.d.ts.map +1 -0
- package/dist/sandbox/internal/usage-evidence.js +56 -0
- package/dist/sandbox/internal/usage-evidence.js.map +1 -0
- package/dist/sandbox/operation-record.d.ts +20 -1
- package/dist/sandbox/operation-record.d.ts.map +1 -1
- package/dist/sandbox/operation-record.js +100 -4
- package/dist/sandbox/operation-record.js.map +1 -1
- package/dist/sandbox/persistence/changed-buckets.d.ts +19 -0
- package/dist/sandbox/persistence/changed-buckets.d.ts.map +1 -0
- package/dist/sandbox/persistence/changed-buckets.js +72 -0
- package/dist/sandbox/persistence/changed-buckets.js.map +1 -0
- package/dist/sandbox/persistence/chunk-format.d.ts +27 -1
- package/dist/sandbox/persistence/chunk-format.d.ts.map +1 -1
- package/dist/sandbox/persistence/chunk-format.js +37 -25
- package/dist/sandbox/persistence/chunk-format.js.map +1 -1
- package/dist/sandbox/persistence/controller.d.ts.map +1 -1
- package/dist/sandbox/persistence/controller.js +91 -36
- package/dist/sandbox/persistence/controller.js.map +1 -1
- package/dist/sandbox/persistence/import-bundle.d.ts +8 -0
- package/dist/sandbox/persistence/import-bundle.d.ts.map +1 -0
- package/dist/sandbox/persistence/import-bundle.js +66 -0
- package/dist/sandbox/persistence/import-bundle.js.map +1 -0
- package/dist/sandbox/persistence/serialize.d.ts +1 -1
- package/dist/sandbox/persistence/serialize.d.ts.map +1 -1
- package/dist/sandbox/persistence/serialize.js +16 -11
- package/dist/sandbox/persistence/serialize.js.map +1 -1
- package/dist/sandbox/persistence/types.d.ts +4 -0
- package/dist/sandbox/persistence/types.d.ts.map +1 -1
- package/dist/sandbox/persistence/validate-services.d.ts +7 -0
- package/dist/sandbox/persistence/validate-services.d.ts.map +1 -0
- package/dist/sandbox/persistence/validate-services.js +73 -0
- package/dist/sandbox/persistence/validate-services.js.map +1 -0
- package/dist/sandbox/remote.d.ts +6 -0
- package/dist/sandbox/remote.d.ts.map +1 -1
- package/dist/sandbox/remote.js.map +1 -1
- package/dist/sandbox/replay/index.d.ts +1 -1
- package/dist/sandbox/replay/index.d.ts.map +1 -1
- package/dist/sandbox/replay/index.js +18 -8
- package/dist/sandbox/replay/index.js.map +1 -1
- package/dist/sandbox/types/errors.d.ts +3 -1
- package/dist/sandbox/types/errors.d.ts.map +1 -1
- package/dist/sandbox/types/errors.js +0 -4
- package/dist/sandbox/types/errors.js.map +1 -1
- package/dist/sandbox/types/events.d.ts +105 -76
- package/dist/sandbox/types/events.d.ts.map +1 -1
- package/dist/sandbox/types/events.js +0 -5
- package/dist/sandbox/types/events.js.map +1 -1
- package/dist/sandbox/types/index.d.ts +2 -1
- package/dist/sandbox/types/index.d.ts.map +1 -1
- package/dist/sandbox/types/index.js +1 -0
- package/dist/sandbox/types/index.js.map +1 -1
- package/dist/sandbox/types/operation.d.ts +13 -4
- package/dist/sandbox/types/operation.d.ts.map +1 -1
- package/dist/sandbox/types/persistence.d.ts +2 -2
- package/dist/sandbox/types/query-proof.d.ts +25 -0
- package/dist/sandbox/types/query-proof.d.ts.map +1 -0
- package/dist/sandbox/types/query-proof.js +2 -0
- package/dist/sandbox/types/query-proof.js.map +1 -0
- package/dist/sandbox/types/request-observation.d.ts +19 -0
- package/dist/sandbox/types/request-observation.d.ts.map +1 -0
- package/dist/sandbox/types/request-observation.js +13 -0
- package/dist/sandbox/types/request-observation.js.map +1 -0
- package/dist/sandbox/types/rules-evidence.d.ts +48 -0
- package/dist/sandbox/types/rules-evidence.d.ts.map +1 -0
- package/dist/sandbox/types/rules-evidence.js +2 -0
- package/dist/sandbox/types/rules-evidence.js.map +1 -0
- package/dist/sandbox/types/service-event-record.d.ts +30 -0
- package/dist/sandbox/types/service-event-record.d.ts.map +1 -0
- package/dist/sandbox/types/service-event-record.js +13 -0
- package/dist/sandbox/types/service-event-record.js.map +1 -0
- package/dist/sandbox/types/service-event-records.d.ts +64 -0
- package/dist/sandbox/types/service-event-records.d.ts.map +1 -0
- package/dist/sandbox/types/service-event-records.js +31 -0
- package/dist/sandbox/types/service-event-records.js.map +1 -0
- package/dist/sandbox/types/service-mutation-event.d.ts +88 -0
- package/dist/sandbox/types/service-mutation-event.d.ts.map +1 -0
- package/dist/sandbox/types/service-mutation-event.js +2 -0
- package/dist/sandbox/types/service-mutation-event.js.map +1 -0
- package/dist/storage/activity-coverage.d.ts +9 -0
- package/dist/storage/activity-coverage.d.ts.map +1 -0
- package/dist/storage/activity-coverage.js +9 -0
- package/dist/storage/activity-coverage.js.map +1 -0
- package/dist/storage/base64.d.ts +14 -0
- package/dist/storage/base64.d.ts.map +1 -0
- package/dist/storage/base64.js +34 -0
- package/dist/storage/base64.js.map +1 -0
- package/dist/storage/download.d.ts +12 -4
- package/dist/storage/download.d.ts.map +1 -1
- package/dist/storage/download.js +19 -6
- package/dist/storage/download.js.map +1 -1
- package/dist/storage/enforce.d.ts +13 -2
- package/dist/storage/enforce.d.ts.map +1 -1
- package/dist/storage/enforce.js +21 -3
- package/dist/storage/enforce.js.map +1 -1
- package/dist/storage/errors.d.ts +29 -5
- package/dist/storage/errors.d.ts.map +1 -1
- package/dist/storage/errors.js +28 -0
- package/dist/storage/errors.js.map +1 -1
- package/dist/storage/events.d.ts +12 -0
- package/dist/storage/events.d.ts.map +1 -0
- package/dist/storage/events.js +10 -0
- package/dist/storage/events.js.map +1 -0
- package/dist/storage/index.d.ts +7 -7
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +7 -5
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/internal.d.ts +10 -1
- package/dist/storage/internal.d.ts.map +1 -1
- package/dist/storage/internal.js +9 -1
- package/dist/storage/internal.js.map +1 -1
- package/dist/storage/metadata.d.ts +19 -0
- package/dist/storage/metadata.d.ts.map +1 -1
- package/dist/storage/metadata.js +50 -19
- package/dist/storage/metadata.js.map +1 -1
- package/dist/storage/observed.d.ts +16 -0
- package/dist/storage/observed.d.ts.map +1 -0
- package/dist/storage/observed.js +17 -0
- package/dist/storage/observed.js.map +1 -0
- package/dist/storage/persistence.d.ts +157 -20
- package/dist/storage/persistence.d.ts.map +1 -1
- package/dist/storage/persistence.js +423 -53
- package/dist/storage/persistence.js.map +1 -1
- package/dist/storage/reference.d.ts +3 -1
- package/dist/storage/reference.d.ts.map +1 -1
- package/dist/storage/reference.js +3 -2
- package/dist/storage/reference.js.map +1 -1
- package/dist/storage/remote-bytes.d.ts +44 -0
- package/dist/storage/remote-bytes.d.ts.map +1 -0
- package/dist/storage/remote-bytes.js +97 -0
- package/dist/storage/remote-bytes.js.map +1 -0
- package/dist/storage/resumable.d.ts.map +1 -1
- package/dist/storage/resumable.js +16 -0
- package/dist/storage/resumable.js.map +1 -1
- package/dist/storage/rules-resolution.d.ts +13 -1
- package/dist/storage/rules-resolution.d.ts.map +1 -1
- package/dist/storage/rules-resolution.js +28 -0
- package/dist/storage/rules-resolution.js.map +1 -1
- package/dist/storage/sandbox/persistence-state.d.ts +25 -0
- package/dist/storage/sandbox/persistence-state.d.ts.map +1 -0
- package/dist/storage/sandbox/persistence-state.js +53 -0
- package/dist/storage/sandbox/persistence-state.js.map +1 -0
- package/dist/storage/sandbox/rules-bindings.d.ts +15 -0
- package/dist/storage/sandbox/rules-bindings.d.ts.map +1 -0
- package/dist/storage/sandbox/rules-bindings.js +69 -0
- package/dist/storage/sandbox/rules-bindings.js.map +1 -0
- package/dist/storage/sandbox/rules-collection-methods.d.ts +3 -0
- package/dist/storage/sandbox/rules-collection-methods.d.ts.map +1 -0
- package/dist/storage/sandbox/rules-collection-methods.js +149 -0
- package/dist/storage/sandbox/rules-collection-methods.js.map +1 -0
- package/dist/storage/sandbox/rules-evaluator.d.ts +2 -2
- package/dist/storage/sandbox/rules-evaluator.d.ts.map +1 -1
- package/dist/storage/sandbox/rules-evaluator.js +51 -129
- package/dist/storage/sandbox/rules-evaluator.js.map +1 -1
- package/dist/storage/sandbox/rules-firestore-lookup.d.ts +25 -0
- package/dist/storage/sandbox/rules-firestore-lookup.d.ts.map +1 -0
- package/dist/storage/sandbox/rules-firestore-lookup.js +94 -0
- package/dist/storage/sandbox/rules-firestore-lookup.js.map +1 -0
- package/dist/storage/sandbox/rules-hashing-methods.d.ts +16 -0
- package/dist/storage/sandbox/rules-hashing-methods.d.ts.map +1 -0
- package/dist/storage/sandbox/rules-hashing-methods.js +41 -0
- package/dist/storage/sandbox/rules-hashing-methods.js.map +1 -0
- package/dist/storage/sandbox/rules-method-calls.d.ts +40 -0
- package/dist/storage/sandbox/rules-method-calls.d.ts.map +1 -0
- package/dist/storage/sandbox/rules-method-calls.js +47 -0
- package/dist/storage/sandbox/rules-method-calls.js.map +1 -0
- package/dist/storage/sandbox/rules-methods.d.ts +11 -12
- package/dist/storage/sandbox/rules-methods.d.ts.map +1 -1
- package/dist/storage/sandbox/rules-methods.js +62 -359
- package/dist/storage/sandbox/rules-methods.js.map +1 -1
- package/dist/storage/sandbox/rules-operators.d.ts +32 -0
- package/dist/storage/sandbox/rules-operators.d.ts.map +1 -0
- package/dist/storage/sandbox/rules-operators.js +85 -0
- package/dist/storage/sandbox/rules-operators.js.map +1 -0
- package/dist/storage/sandbox/rules-string-methods.d.ts +3 -0
- package/dist/storage/sandbox/rules-string-methods.d.ts.map +1 -0
- package/dist/storage/sandbox/rules-string-methods.js +199 -0
- package/dist/storage/sandbox/rules-string-methods.js.map +1 -0
- package/dist/storage/sandbox/rules-time-methods.d.ts +25 -0
- package/dist/storage/sandbox/rules-time-methods.d.ts.map +1 -0
- package/dist/storage/sandbox/rules-time-methods.js +89 -0
- package/dist/storage/sandbox/rules-time-methods.js.map +1 -0
- package/dist/storage/sandbox/rules-values.d.ts +6 -0
- package/dist/storage/sandbox/rules-values.d.ts.map +1 -1
- package/dist/storage/sandbox/rules-values.js +29 -2
- package/dist/storage/sandbox/rules-values.js.map +1 -1
- package/dist/storage/sandbox/rules.d.ts +25 -13
- package/dist/storage/sandbox/rules.d.ts.map +1 -1
- package/dist/storage/sandbox/rules.js +19 -10
- package/dist/storage/sandbox/rules.js.map +1 -1
- package/dist/storage/sandbox/running-service.d.ts +65 -0
- package/dist/storage/sandbox/running-service.d.ts.map +1 -0
- package/dist/storage/sandbox/running-service.js +30 -0
- package/dist/storage/sandbox/running-service.js.map +1 -0
- package/dist/storage/service.d.ts +46 -28
- package/dist/storage/service.d.ts.map +1 -1
- package/dist/storage/service.js +169 -57
- package/dist/storage/service.js.map +1 -1
- package/dist/storage/string-format.d.ts +9 -0
- package/dist/storage/string-format.d.ts.map +1 -0
- package/dist/storage/string-format.js +8 -0
- package/dist/storage/string-format.js.map +1 -0
- package/dist/storage/upload.d.ts +2 -1
- package/dist/storage/upload.d.ts.map +1 -1
- package/dist/storage/upload.js +6 -2
- package/dist/storage/upload.js.map +1 -1
- package/dist/storage/url.d.ts +18 -0
- package/dist/storage/url.d.ts.map +1 -0
- package/dist/storage/url.js +84 -0
- package/dist/storage/url.js.map +1 -0
- package/package.json +17 -1
- package/src/ai/activity.ts +43 -0
- package/src/ai/broker/broker.ts +59 -6
- package/src/ai/broker/gemini-engine.ts +16 -0
- package/src/ai/broker/index.ts +1 -1
- package/src/ai/broker/openai-engine.ts +6 -3
- package/src/ai/broker/scripted-engine.ts +16 -5
- package/src/ai/broker/types.ts +6 -2
- package/src/ai/events.ts +29 -0
- package/src/ai/generation-enums.ts +48 -0
- package/src/ai/index.ts +9 -0
- package/src/ai/instances.ts +22 -2
- package/src/ai/internal.ts +5 -0
- package/src/ai/sandbox-plane.ts +23 -8
- package/src/ai/scripting.ts +42 -7
- package/src/app/internal.ts +1 -0
- package/src/auth/email-link.ts +32 -21
- package/src/auth/events.ts +29 -0
- package/src/auth/factor-id.ts +7 -0
- package/src/auth/index.ts +2 -0
- package/src/auth/instances.ts +13 -1
- package/src/auth/internal.ts +24 -0
- package/src/auth/modular.ts +27 -0
- package/src/auth/reauth.ts +3 -2
- package/src/auth/sandbox/default-avatar.ts +177 -0
- package/src/auth/sandbox/driver.ts +54 -0
- package/src/auth/sandbox/project-store.ts +0 -2
- package/src/auth/sandbox-backend-types.ts +31 -20
- package/src/auth/sandbox-backend.ts +400 -94
- package/src/auth/seed-user.ts +38 -0
- package/src/auth/tokens.ts +21 -18
- package/src/auth/types.ts +13 -1
- package/src/database/activity-coverage.ts +10 -0
- package/src/database/connection-lifecycle.ts +53 -24
- package/src/database/events.ts +20 -0
- package/src/database/instances.ts +52 -21
- package/src/database/internal/query-projection.ts +333 -0
- package/src/database/internal.ts +2 -0
- package/src/database/listeners.ts +162 -44
- package/src/database/operations.ts +73 -50
- package/src/database/replay.ts +6 -2
- package/src/database/routing.ts +4 -0
- package/src/database/sandbox/backend-for.ts +145 -25
- package/src/database/sandbox/backend-state.ts +15 -1
- package/src/database/sandbox/backend.ts +4 -2
- package/src/database/sandbox/child-listeners.ts +32 -13
- package/src/database/sandbox/listener-types.ts +5 -0
- package/src/database/sandbox/operation-events.ts +23 -9
- package/src/database/sandbox/persistence-state.ts +4 -11
- package/src/database/sandbox/priority-writes.ts +2 -2
- package/src/database/sandbox/query.ts +13 -268
- package/src/database/sandbox/rules-eval.ts +144 -10
- package/src/database/sandbox/transactions.ts +17 -39
- package/src/database/sandbox/value-listeners.ts +66 -23
- package/src/database/sandbox/write-plane.ts +29 -22
- package/src/database/sdk-activity.ts +26 -0
- package/src/database/transactions.ts +15 -11
- package/src/database/types.ts +12 -1
- package/src/deferred/entry.ts +16 -10
- package/src/firestore/activity-coverage.ts +8 -0
- package/src/firestore/aggregates.ts +17 -9
- package/src/firestore/bytes.ts +56 -0
- package/src/firestore/converter-method.ts +49 -0
- package/src/firestore/errors.ts +8 -0
- package/src/firestore/field-values.ts +3 -158
- package/src/firestore/geo-point.ts +56 -0
- package/src/firestore/index.ts +1 -1
- package/src/firestore/instances.ts +23 -2
- package/src/firestore/internal/document-data.ts +9 -0
- package/src/firestore/internal/index.ts +7 -0
- package/src/firestore/internal/value-codec.ts +150 -83
- package/src/firestore/internal/value-depth.ts +19 -0
- package/src/firestore/listeners.ts +60 -18
- package/src/firestore/persistence.ts +14 -9
- package/src/firestore/plain-object.ts +7 -0
- package/src/firestore/query-constraints.ts +4 -8
- package/src/firestore/reads.ts +81 -48
- package/src/firestore/refs.ts +56 -41
- package/src/firestore/sandbox/activity-query-display.ts +138 -0
- package/src/firestore/sandbox/admin-compat/batch.ts +26 -19
- package/src/firestore/sandbox/admin-compat/query-comparison.ts +9 -8
- package/src/firestore/sandbox/admin-compat/query.ts +46 -12
- package/src/firestore/sandbox/admin-compat/read-translation.ts +18 -6
- package/src/firestore/sandbox/admin-compat/transaction.ts +14 -4
- package/src/firestore/sandbox/admin-compat/types.ts +6 -88
- package/src/firestore/sandbox/atomic-state.ts +112 -0
- package/src/firestore/sandbox/atomic-write-pipeline.ts +129 -77
- package/src/firestore/sandbox/batch-write-executor.ts +51 -29
- package/src/firestore/sandbox/converters/user-timestamp.ts +19 -42
- package/src/firestore/sandbox/document-copy.ts +27 -0
- package/src/firestore/sandbox/document-store.ts +108 -0
- package/src/firestore/sandbox/errors.ts +5 -1
- package/src/firestore/sandbox/event-log.ts +72 -7
- package/src/firestore/sandbox/field-merge.ts +10 -19
- package/src/firestore/sandbox/history-controls.ts +1 -1
- package/src/firestore/sandbox/list-query-proof.ts +43 -72
- package/src/firestore/sandbox/listener-dispatch.ts +59 -4
- package/src/firestore/sandbox/local-environment.ts +35 -7
- package/src/firestore/sandbox/local-state.ts +72 -232
- package/src/firestore/sandbox/query-execution.ts +56 -34
- package/src/firestore/sandbox/query-operand-equality.ts +57 -14
- package/src/firestore/sandbox/query-operators.ts +20 -0
- package/src/firestore/sandbox/query-value-registry.ts +3 -2
- package/src/firestore/sandbox/request-events.ts +5 -0
- package/src/firestore/sandbox/rules-evidence.ts +94 -0
- package/src/firestore/sandbox/rules-list-authorizer.ts +62 -107
- package/src/firestore/sandbox/rules-operation-reader.ts +11 -4
- package/src/firestore/sandbox/rules-read-engine.ts +19 -8
- package/src/firestore/sandbox/rules-state.ts +21 -0
- package/src/firestore/sandbox/snapshot-listeners.ts +12 -1
- package/src/firestore/sandbox/transaction-merge.ts +33 -20
- package/src/firestore/sandbox/transaction-types.ts +11 -21
- package/src/firestore/sandbox/transaction-write-executor.ts +103 -69
- package/src/firestore/sandbox/transaction.ts +24 -7
- package/src/firestore/sandbox/value-resolver.ts +2 -13
- package/src/firestore/sandbox/write-engine.ts +13 -5
- package/src/firestore/sandbox/write-runtime.ts +68 -40
- package/src/firestore/sandbox/writes.ts +3 -1
- package/src/firestore/sdk-activity.ts +31 -0
- package/src/firestore/snapshots.ts +84 -18
- package/src/firestore/state.ts +34 -14
- package/src/firestore/timestamp.ts +86 -0
- package/src/firestore/tools.ts +3 -3
- package/src/firestore/transactions.ts +88 -8
- package/src/firestore/types.ts +26 -5
- package/src/firestore/vector-value.ts +54 -0
- package/src/firestore/writes.ts +53 -43
- package/src/functions/events.ts +27 -0
- package/src/messaging/broker/broker.test.ts +114 -0
- package/src/messaging/broker/broker.ts +152 -65
- package/src/messaging/broker/delivery-history.ts +49 -0
- package/src/messaging/broker/index.ts +11 -0
- package/src/messaging/broker/persistence.ts +54 -0
- package/src/messaging/broker/types.ts +50 -0
- package/src/messaging/events.ts +29 -0
- package/src/rules/api/case-types.ts +7 -0
- package/src/rules/api/rtdb.ts +15 -7
- package/src/rules/grammar/parse-error-wording.ts +98 -0
- package/src/rules/indexes/query-analysis.ts +136 -0
- package/src/rules/indexes/service-query.ts +69 -0
- package/src/rules/internal/index.ts +16 -0
- package/src/rules/modules/rules-capabilities.generated.ts +1 -1
- package/src/rules/rtdb/constraints/atoms.spec.ts +7 -7
- package/src/rules/rtdb/constraints/atoms.ts +7 -7
- package/src/rules/rtdb/constraints/data.ts +4 -4
- package/src/rules/rtdb/constraints/document.ts +4 -2
- package/src/rules/rtdb/constraints/game.spec.ts +4 -4
- package/src/rules/rtdb/constraints/policies.spec.ts +5 -5
- package/src/rules/rtdb/constraints/policies.ts +4 -4
- package/src/rules/rtdb/constraints/schema.ts +3 -3
- package/src/rules/rtdb/grammar/RtdbExpr.ohm +1 -3
- package/src/rules/rtdb/grammar/RtdbExpr.ohm.generated.ts +1 -3
- package/src/rules/rtdb/grammar/linter.ts +34 -30
- package/src/rules/rtdb/grammar/simulator.ts +112 -74
- package/src/rules/rtdb/grammar/validator.ts +30 -26
- package/src/rules/rtdb/simulation/handler.ts +139 -36
- package/src/rules/rtdb/simulation/spec.ts +24 -1
- package/src/rules/simulator/evaluator.ts +34 -41
- package/src/rules/simulator/handler.ts +12 -3
- package/src/rules/simulator/mapdiff.ts +7 -5
- package/src/rules/simulator/query-proof-residual.ts +209 -0
- package/src/rules/simulator/query-proof.ts +53 -27
- package/src/rules/simulator/request-path.ts +39 -0
- package/src/rules/simulator/trace-recorder.ts +3 -0
- package/src/rules/simulator/wrappers/timestamp.ts +8 -1
- package/src/rules/simulator-tools-impl.ts +6 -3
- package/src/rules/stdlib-tools.ts +4 -4
- package/src/sandbox/active-listeners.ts +245 -0
- package/src/sandbox/admin-firestore/error-translation.ts +16 -2
- package/src/sandbox/admin-firestore/listeners.ts +26 -1
- package/src/sandbox/admin-firestore/remote/listeners.ts +50 -32
- package/src/sandbox/admin-firestore/remote/value-codec.ts +7 -14
- package/src/sandbox/admin-firestore/remote/wire-types.ts +3 -0
- package/src/sandbox/attribution/attribution-mode.ts +74 -0
- package/src/sandbox/attribution/effect-regions.ts +130 -0
- package/src/sandbox/attribution/element-selector.ts +118 -0
- package/src/sandbox/attribution/listener-owners.ts +277 -0
- package/src/sandbox/branches/engine.ts +362 -0
- package/src/sandbox/branches/index.ts +12 -448
- package/src/sandbox/branches/promotion.ts +207 -0
- package/src/sandbox/branches/state-diff.ts +333 -0
- package/src/sandbox/branches/store.ts +317 -0
- package/src/sandbox/checkpoints/capture.ts +77 -0
- package/src/sandbox/checkpoints/directory-backend.ts +110 -0
- package/src/sandbox/checkpoints/index.ts +32 -0
- package/src/sandbox/checkpoints/record-backend.ts +109 -0
- package/src/sandbox/checkpoints/saved-states.ts +72 -0
- package/src/sandbox/checkpoints/types.ts +115 -0
- package/src/sandbox/checkpoints/validation.ts +102 -0
- package/src/sandbox/clock.ts +205 -0
- package/src/sandbox/full-state.ts +403 -0
- package/src/sandbox/index.ts +53 -10
- package/src/sandbox/internal/ai-evidence.ts +38 -0
- package/src/sandbox/internal/event-history.ts +193 -0
- package/src/sandbox/internal/history-integrity.ts +12 -0
- package/src/sandbox/internal/history-retention.ts +16 -0
- package/src/sandbox/internal/index.ts +65 -0
- package/src/sandbox/internal/observation-history.ts +5 -0
- package/src/sandbox/internal/observation-payload.ts +18 -0
- package/src/sandbox/internal/provenance.ts +5 -0
- package/src/sandbox/internal/root.ts +3 -2
- package/src/sandbox/internal/rules-evidence-retention.ts +28 -0
- package/src/sandbox/internal/sandbox-impl.ts +91 -45
- package/src/sandbox/internal/sdk-activity.ts +291 -0
- package/src/sandbox/internal/sdk-coverage.ts +28 -0
- package/src/sandbox/internal/sdk-observation.ts +62 -0
- package/src/sandbox/internal/sdk-rates.ts +240 -0
- package/src/sandbox/internal/sdk-write-activity.ts +14 -0
- package/src/sandbox/internal/state-schemas.ts +47 -0
- package/src/sandbox/internal/state-values.ts +20 -0
- package/src/sandbox/internal/storage-activity.ts +43 -0
- package/src/sandbox/internal/usage-evidence.ts +77 -0
- package/src/sandbox/operation-record.ts +107 -4
- package/src/sandbox/persistence/changed-buckets.ts +61 -0
- package/src/sandbox/persistence/chunk-format.ts +39 -27
- package/src/sandbox/persistence/controller.ts +85 -33
- package/src/sandbox/persistence/import-bundle.ts +64 -0
- package/src/sandbox/persistence/serialize.ts +16 -10
- package/src/sandbox/persistence/types.ts +4 -0
- package/src/sandbox/persistence/validate-services.ts +70 -0
- package/src/sandbox/remote.ts +7 -0
- package/src/sandbox/replay/index.ts +15 -8
- package/src/sandbox/types/errors.ts +3 -1
- package/src/sandbox/types/events.ts +118 -75
- package/src/sandbox/types/index.ts +12 -0
- package/src/sandbox/types/operation.ts +14 -4
- package/src/sandbox/types/persistence.ts +2 -2
- package/src/sandbox/types/query-proof.ts +26 -0
- package/src/sandbox/types/request-observation.ts +25 -0
- package/src/sandbox/types/rules-evidence.ts +37 -0
- package/src/sandbox/types/service-event-record.ts +34 -0
- package/src/sandbox/types/service-event-records.ts +42 -0
- package/src/sandbox/types/service-mutation-event.ts +93 -0
- package/src/storage/activity-coverage.ts +8 -0
- package/src/storage/base64.ts +35 -0
- package/src/storage/download.ts +19 -6
- package/src/storage/enforce.ts +26 -4
- package/src/storage/errors.ts +29 -14
- package/src/storage/events.ts +21 -0
- package/src/storage/index.ts +7 -7
- package/src/storage/internal.ts +21 -0
- package/src/storage/metadata.ts +68 -19
- package/src/storage/observed.ts +16 -0
- package/src/storage/persistence.ts +574 -66
- package/src/storage/reference.ts +6 -3
- package/src/storage/remote-bytes.ts +122 -0
- package/src/storage/resumable.ts +16 -3
- package/src/storage/rules-resolution.ts +43 -1
- package/src/storage/sandbox/persistence-state.ts +71 -0
- package/src/storage/sandbox/rules-bindings.ts +69 -0
- package/src/storage/sandbox/rules-collection-methods.ts +161 -0
- package/src/storage/sandbox/rules-evaluator.ts +65 -142
- package/src/storage/sandbox/rules-firestore-lookup.ts +112 -0
- package/src/storage/sandbox/rules-hashing-methods.ts +50 -0
- package/src/storage/sandbox/rules-method-calls.ts +67 -0
- package/src/storage/sandbox/rules-methods.ts +63 -404
- package/src/storage/sandbox/rules-operators.ts +93 -0
- package/src/storage/sandbox/rules-string-methods.ts +214 -0
- package/src/storage/sandbox/rules-time-methods.ts +98 -0
- package/src/storage/sandbox/rules-values.ts +20 -1
- package/src/storage/sandbox/rules.ts +27 -14
- package/src/storage/sandbox/running-service.ts +52 -0
- package/src/storage/service.ts +196 -85
- package/src/storage/string-format.ts +8 -0
- package/src/storage/upload.ts +8 -3
- package/src/storage/url.ts +106 -0
|
@@ -48,9 +48,11 @@ import {
|
|
|
48
48
|
createAuthProjectStore,
|
|
49
49
|
type AuthProjectStore,
|
|
50
50
|
} from './sandbox/project-store.js';
|
|
51
|
+
import { defaultAvatarMint, type AvatarMint } from './sandbox/default-avatar.js';
|
|
51
52
|
|
|
52
|
-
import type
|
|
53
|
-
import { emitSandboxEvent, makeServiceMutationEvent } from 'pyric/sandbox/internal';
|
|
53
|
+
import { normalizeAuthState, type AuthState, type Sandbox } from 'pyric/sandbox';
|
|
54
|
+
import { emitSandboxEvent, getClock, makeServiceMutationEvent } from 'pyric/sandbox/internal';
|
|
55
|
+
import type { AuthEventOperation } from './events.js';
|
|
54
56
|
|
|
55
57
|
import {
|
|
56
58
|
USER_INTERNAL,
|
|
@@ -98,6 +100,17 @@ export type {
|
|
|
98
100
|
* sibling app backends share account/provider maps but not currentUser,
|
|
99
101
|
* listeners, tokens, flow staging, or persistence mode.
|
|
100
102
|
*/
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The claims rules see on `auth.token` for a signed-in data context: the
|
|
106
|
+
* custom claims, plus the `firebase` namespace the minted ID token carries
|
|
107
|
+
* (`sign_in_provider`, and `tenant` for a tenant sign-in), as production's
|
|
108
|
+
* decoded ID token does.
|
|
109
|
+
*/
|
|
110
|
+
function rulesTokenClaims(claims: Record<string, unknown>, minted: IdTokenResult): Record<string, unknown> {
|
|
111
|
+
return { ...claims, firebase: minted.claims.firebase };
|
|
112
|
+
}
|
|
113
|
+
|
|
101
114
|
export class SandboxBackend {
|
|
102
115
|
/** Email → stored user. Lowercase keys so lookups are case-
|
|
103
116
|
* insensitive (matches upstream). */
|
|
@@ -131,7 +144,6 @@ export class SandboxBackend {
|
|
|
131
144
|
/** Monotonic uid counter for `createUser` calls without a uid. */
|
|
132
145
|
private readonly sharedCounters: {
|
|
133
146
|
nextAdminUserId: number;
|
|
134
|
-
nextAnonymousId: number;
|
|
135
147
|
};
|
|
136
148
|
|
|
137
149
|
/** Popup / redirect / credential flow-staging machinery — the
|
|
@@ -165,12 +177,12 @@ export class SandboxBackend {
|
|
|
165
177
|
* (direct sandbox writes, `reset()`, another handle). */
|
|
166
178
|
private applyingTransition = false;
|
|
167
179
|
|
|
168
|
-
/** Per-uid current ID token + result. Refreshed on each
|
|
180
|
+
/** Per-uid and signed-in tenant current ID token + result. Refreshed on each
|
|
169
181
|
* `getIdToken(forceRefresh=true)` and on each new sign-in
|
|
170
182
|
* transition (so a sign-out / sign-in round-trip mints a fresh
|
|
171
183
|
* token, matching prod's "new session = new token" semantics).
|
|
172
184
|
* Subsequent `getIdToken(false)` reads return the cached value. */
|
|
173
|
-
private readonly tokenCache = new Map<string, { token: string; result: IdTokenResult }
|
|
185
|
+
private readonly tokenCache = new Map<string, Map<string | null, { token: string; result: IdTokenResult }>>();
|
|
174
186
|
|
|
175
187
|
/** Monotonic counter used to disambiguate freshly-minted tokens
|
|
176
188
|
* for the same uid + claims map. Without this, two refreshes that
|
|
@@ -248,6 +260,42 @@ export class SandboxBackend {
|
|
|
248
260
|
* persisted: a runtime wiring decision, not project config. */
|
|
249
261
|
private providerEnforcementDelegated = false;
|
|
250
262
|
|
|
263
|
+
/**
|
|
264
|
+
* The hook that assigns a default `photoURL` to a federated-provider record
|
|
265
|
+
* at creation (see {@link makeStored}). The built-in mint returns a
|
|
266
|
+
* deterministic SVG data URI, which resolves with no server at all — so an
|
|
267
|
+
* in-page sandbox and any host that configures nothing behave identically.
|
|
268
|
+
*
|
|
269
|
+
* A HOST OVERRIDES IT ({@link setAvatarMint}): the served dev server swaps in
|
|
270
|
+
* a mint that returns its `/__pyric/assets/avatar/<uid>` route, and a server
|
|
271
|
+
* with avatars disabled swaps in one that returns `null`, which restores
|
|
272
|
+
* Firebase's own no-photo behaviour. Not persisted: a runtime wiring
|
|
273
|
+
* decision, not project config — but the URL it returns IS persisted, so a
|
|
274
|
+
* host must install its mint before any user record is created.
|
|
275
|
+
*/
|
|
276
|
+
private avatarMint: AvatarMint = defaultAvatarMint;
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Tenant the NEXT sign-in through this handle authenticates against, or
|
|
280
|
+
* `null` for the project-level pool. Backs `Auth.tenantId`: the handle is a
|
|
281
|
+
* thin accessor over this field, so the value an app assigns before calling
|
|
282
|
+
* a sign-in function is the value {@link applyTenantScope} stamps onto the
|
|
283
|
+
* user and its stored record.
|
|
284
|
+
*/
|
|
285
|
+
private tenantId: string | null = null;
|
|
286
|
+
|
|
287
|
+
/** Read `Auth.tenantId`. */
|
|
288
|
+
getTenantId(): string | null {
|
|
289
|
+
return this.tenantId;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** Write `Auth.tenantId`. Takes effect on the next sign-in; the current
|
|
293
|
+
* session keeps the tenant it authenticated with, matching prod, where the
|
|
294
|
+
* tenant is fixed at the moment credentials are exchanged. */
|
|
295
|
+
setTenantId(tenantId: string | null): void {
|
|
296
|
+
this.tenantId = tenantId;
|
|
297
|
+
}
|
|
298
|
+
|
|
251
299
|
constructor(
|
|
252
300
|
sandbox: Sandbox,
|
|
253
301
|
session: Pick<Sandbox, 'currentUser' | 'onCurrentUserChanged'> = sandbox,
|
|
@@ -311,6 +359,20 @@ export class SandboxBackend {
|
|
|
311
359
|
return this.cachedUser;
|
|
312
360
|
}
|
|
313
361
|
|
|
362
|
+
/**
|
|
363
|
+
* The provider the current session signed in through. This is the same
|
|
364
|
+
* value {@link mintToken} puts on `IdTokenResult.signInProvider` and on the
|
|
365
|
+
* `firebase.sign_in_provider` claim, read without minting a token.
|
|
366
|
+
*
|
|
367
|
+
* `null` while the app is signed out, and `null` for an identity driven
|
|
368
|
+
* straight through the test driver, which records no provider.
|
|
369
|
+
*/
|
|
370
|
+
getCurrentSignInProvider(): string | null {
|
|
371
|
+
const user = this.cachedUser;
|
|
372
|
+
if (user === null) return null;
|
|
373
|
+
return this.signInProviderByUid.get(user.uid) ?? null;
|
|
374
|
+
}
|
|
375
|
+
|
|
314
376
|
// ─── Listener registries ────────────────────────────────────────────
|
|
315
377
|
|
|
316
378
|
/**
|
|
@@ -412,11 +474,26 @@ export class SandboxBackend {
|
|
|
412
474
|
|
|
413
475
|
// ─── User DB ────────────────────────────────────────────────────────
|
|
414
476
|
|
|
415
|
-
/**
|
|
477
|
+
/**
|
|
478
|
+
* Build a fresh {@link StoredUser} with admin-field defaults.
|
|
479
|
+
*
|
|
480
|
+
* THE ONE PLACE A DEFAULT PHOTO IS ASSIGNED. A federated-provider record
|
|
481
|
+
* that arrives without a photo gets one from {@link avatarMint} here, so
|
|
482
|
+
* `photoURL` is populated the instant the user object exists — never null
|
|
483
|
+
* for a moment and then patched. Every other path is untouched: an update,
|
|
484
|
+
* `updateProfile`, or `linkProvider` on an existing record never mints, and
|
|
485
|
+
* a caller-supplied photo always wins (see {@link mintsDefaultPhoto}).
|
|
486
|
+
*
|
|
487
|
+
* `signInProviderId` is the provider a flow is creating this record under,
|
|
488
|
+
* for the two paths that link the provider AFTER the record exists
|
|
489
|
+
* (`recordProviderSignIn`, `createSignInCredential`). Every other path
|
|
490
|
+
* carries its providers in `init.providerUserInfo`.
|
|
491
|
+
*/
|
|
416
492
|
private makeStored(
|
|
417
493
|
init: Partial<StoredUser> & { uid: string },
|
|
494
|
+
signInProviderId: string | null = null,
|
|
418
495
|
): StoredUser {
|
|
419
|
-
|
|
496
|
+
const record: StoredUser = {
|
|
420
497
|
email: null,
|
|
421
498
|
password: null,
|
|
422
499
|
displayName: null,
|
|
@@ -427,10 +504,21 @@ export class SandboxBackend {
|
|
|
427
504
|
providerUserInfo: [],
|
|
428
505
|
disabled: false,
|
|
429
506
|
emailVerified: false,
|
|
430
|
-
createdAt:
|
|
507
|
+
createdAt: this.now().toISOString(),
|
|
431
508
|
lastLoginAt: null,
|
|
509
|
+
tenantId: null,
|
|
432
510
|
...init,
|
|
433
511
|
};
|
|
512
|
+
const providerId = creationProviderId(record, signInProviderId);
|
|
513
|
+
if (mintsDefaultPhoto(record, providerId)) {
|
|
514
|
+
record.photoUrl = this.avatarMint({
|
|
515
|
+
uid: record.uid,
|
|
516
|
+
displayName: record.displayName,
|
|
517
|
+
email: record.email,
|
|
518
|
+
providerId,
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
return record;
|
|
434
522
|
}
|
|
435
523
|
|
|
436
524
|
/** Fan a coarse "user DB changed" notification out to
|
|
@@ -446,6 +534,17 @@ export class SandboxBackend {
|
|
|
446
534
|
}
|
|
447
535
|
}
|
|
448
536
|
|
|
537
|
+
/**
|
|
538
|
+
* The sandbox's current time. Every time this backend records reads it: an
|
|
539
|
+
* account's `createdAt` and `lastLoginAt`, and a minted token's `iat`,
|
|
540
|
+
* `auth_time`, and `exp`. So a token minted while the sandbox clock is
|
|
541
|
+
* pinned to a date carries that date, and a rule reading
|
|
542
|
+
* `request.auth.token.iat` sees the same instant the write pipeline stamps.
|
|
543
|
+
*/
|
|
544
|
+
private now(): Date {
|
|
545
|
+
return getClock(this.sandbox).date();
|
|
546
|
+
}
|
|
547
|
+
|
|
449
548
|
/**
|
|
450
549
|
* Emit an auth {@link ServiceMutationEvent} onto the sandbox's unified
|
|
451
550
|
* `onEvent`/`history()` stream (Pyric Studio keystone). Best-effort and
|
|
@@ -457,13 +556,14 @@ export class SandboxBackend {
|
|
|
457
556
|
* via `stampProvenance`.
|
|
458
557
|
*/
|
|
459
558
|
private emitAuthEvent(
|
|
460
|
-
op:
|
|
559
|
+
op: AuthEventOperation,
|
|
461
560
|
fields: { path?: string; auth?: AuthState; before?: unknown; after?: unknown; detail?: Record<string, unknown> } = {},
|
|
462
561
|
): void {
|
|
463
562
|
try {
|
|
464
563
|
emitSandboxEvent(
|
|
465
564
|
this.sandbox,
|
|
466
565
|
makeServiceMutationEvent({
|
|
566
|
+
at: this.now().getTime(),
|
|
467
567
|
service: 'auth',
|
|
468
568
|
op,
|
|
469
569
|
path: fields.path,
|
|
@@ -556,6 +656,17 @@ export class SandboxBackend {
|
|
|
556
656
|
this.providerEnforcementDelegated = delegated;
|
|
557
657
|
}
|
|
558
658
|
|
|
659
|
+
/**
|
|
660
|
+
* Install the {@link AvatarMint} this backend assigns default photos with,
|
|
661
|
+
* replacing the built-in data-URI mint. A host installs its mint during
|
|
662
|
+
* boot, before it seeds or signs anyone in: the minted URL is written into
|
|
663
|
+
* the stored record, so records created earlier keep the mint that was
|
|
664
|
+
* installed when they were created.
|
|
665
|
+
*/
|
|
666
|
+
setAvatarMint(mint: AvatarMint): void {
|
|
667
|
+
this.avatarMint = mint;
|
|
668
|
+
}
|
|
669
|
+
|
|
559
670
|
/**
|
|
560
671
|
* Gate a provider entry point. Throws real Firebase's
|
|
561
672
|
* `auth/operation-not-allowed` (exactly the code/shape prod throws
|
|
@@ -694,46 +805,94 @@ export class SandboxBackend {
|
|
|
694
805
|
// in (AUTH-B9) — otherwise both emails would resolve, the old one
|
|
695
806
|
// to a now-orphaned record.
|
|
696
807
|
const prior = this.usersByUid.get(u.uid);
|
|
697
|
-
|
|
698
|
-
|
|
808
|
+
const priorEmail = prior?.email;
|
|
809
|
+
const hasPriorEmail = typeof priorEmail === 'string' && priorEmail.length > 0;
|
|
810
|
+
const changesEmail = hasPriorEmail && priorEmail.toLowerCase() !== u.email?.toLowerCase();
|
|
811
|
+
if (changesEmail) {
|
|
812
|
+
this.usersByEmail.delete(priorEmail.toLowerCase());
|
|
699
813
|
}
|
|
814
|
+
const isAnonymousSeed = u.providerId === 'anonymous';
|
|
815
|
+
const linkedProviders = u.providerUserInfo ?? [{ providerId: u.providerId ?? 'password' }];
|
|
816
|
+
const providerUserInfo = isAnonymousSeed ? [] : linkedProviders.map(provider => ({ ...provider }));
|
|
817
|
+
const hasPasswordProvider = providerUserInfo.some(provider => provider.providerId === 'password');
|
|
818
|
+
const hasLegacyPlaceholder = u.password === NO_PASSWORD_SENTINEL || u.password === '__pyric_popup_no_password__';
|
|
819
|
+
const isLegacyPasswordlessAccount = hasLegacyPlaceholder && !hasPasswordProvider;
|
|
820
|
+
const hasNoPassword = isAnonymousSeed || isLegacyPasswordlessAccount;
|
|
700
821
|
const record = this.makeStored({
|
|
701
822
|
uid: u.uid,
|
|
702
|
-
email: u.email,
|
|
703
|
-
password: u.password,
|
|
823
|
+
email: isAnonymousSeed ? null : (u.email ?? null),
|
|
824
|
+
password: hasNoPassword ? null : (u.password ?? null),
|
|
704
825
|
displayName: u.displayName ?? null,
|
|
826
|
+
phoneNumber: u.phoneNumber ?? null,
|
|
827
|
+
photoUrl: u.photoUrl ?? null,
|
|
705
828
|
customClaims: u.customClaims ?? {},
|
|
706
|
-
|
|
829
|
+
emailVerified: u.emailVerified ?? false,
|
|
830
|
+
disabled: u.disabled ?? false,
|
|
831
|
+
isAnonymous: isAnonymousSeed,
|
|
832
|
+
providerUserInfo,
|
|
833
|
+
tenantId: u.tenantId ?? null,
|
|
707
834
|
});
|
|
708
|
-
|
|
835
|
+
const { createdAt, lastLoginAt, email } = u;
|
|
836
|
+
const hasCreatedAt = createdAt !== undefined;
|
|
837
|
+
if (hasCreatedAt) record.createdAt = createdAt;
|
|
838
|
+
const hasLastLoginAt = lastLoginAt !== undefined;
|
|
839
|
+
if (hasLastLoginAt) record.lastLoginAt = lastLoginAt;
|
|
840
|
+
const indexesEmail = !isAnonymousSeed && email !== undefined;
|
|
841
|
+
if (indexesEmail) this.usersByEmail.set(email.toLowerCase(), record);
|
|
709
842
|
this.usersByUid.set(u.uid, record);
|
|
710
843
|
}
|
|
711
|
-
|
|
844
|
+
const hasSeedUsers = users.length > 0;
|
|
845
|
+
if (hasSeedUsers) this.notifyUsersChanged();
|
|
712
846
|
}
|
|
713
847
|
|
|
714
848
|
/**
|
|
715
849
|
* Export the user DB as `SeedUser`s — the exact shape `seedUsers`
|
|
716
|
-
* accepts,
|
|
717
|
-
* the
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
*
|
|
721
|
-
*
|
|
722
|
-
* ephemeral by design; documented divergence from prod's persisted
|
|
723
|
-
* anonymous sessions.
|
|
850
|
+
* accepts, including every linked provider. Passwordless accounts omit
|
|
851
|
+
* the password; legacy placeholder values are decoded only on import.
|
|
852
|
+
* Anonymous users (no email) export with
|
|
853
|
+
* `providerId: 'anonymous'` and no email or password, so a checkpoint,
|
|
854
|
+
* a branch, and a restart keep them, matching real Firebase, which
|
|
855
|
+
* keeps anonymous accounts in its user pool rather than discarding them.
|
|
724
856
|
*/
|
|
725
857
|
exportUsers(): SeedUser[] {
|
|
726
858
|
const out: SeedUser[] = [];
|
|
727
859
|
for (const u of this.usersByUid.values()) {
|
|
728
|
-
|
|
860
|
+
const { email, displayName, photoUrl, tenantId, phoneNumber, isAnonymous, disabled, emailVerified } = u;
|
|
861
|
+
const hasDisplayName = displayName !== null;
|
|
862
|
+
const hasPhotoUrl = photoUrl !== null;
|
|
863
|
+
const hasCustomClaims = Object.keys(u.customClaims).length > 0;
|
|
864
|
+
const hasTenant = tenantId !== null;
|
|
865
|
+
if (isAnonymous) {
|
|
866
|
+
const seed: SeedUser = { uid: u.uid, providerId: 'anonymous', createdAt: u.createdAt, lastLoginAt: u.lastLoginAt };
|
|
867
|
+
if (hasDisplayName) seed.displayName = displayName;
|
|
868
|
+
if (hasPhotoUrl) seed.photoUrl = photoUrl;
|
|
869
|
+
if (hasCustomClaims) seed.customClaims = u.customClaims;
|
|
870
|
+
if (disabled) seed.disabled = true;
|
|
871
|
+
if (hasTenant) seed.tenantId = tenantId;
|
|
872
|
+
out.push(seed);
|
|
873
|
+
continue;
|
|
874
|
+
}
|
|
875
|
+
const hasNoEmail = email === null;
|
|
876
|
+
if (hasNoEmail) continue; // credential-less, non-anonymous: not round-trippable
|
|
729
877
|
const seed: SeedUser = {
|
|
730
878
|
uid: u.uid,
|
|
731
|
-
|
|
732
|
-
|
|
879
|
+
createdAt: u.createdAt,
|
|
880
|
+
lastLoginAt: u.lastLoginAt,
|
|
881
|
+
email,
|
|
733
882
|
providerId: u.providerUserInfo[0]?.providerId ?? 'password',
|
|
883
|
+
providerUserInfo: u.providerUserInfo.map(provider => ({ ...provider })),
|
|
734
884
|
};
|
|
735
|
-
|
|
736
|
-
|
|
885
|
+
const { password } = u;
|
|
886
|
+
const hasPassword = password !== null;
|
|
887
|
+
if (hasPassword) seed.password = password;
|
|
888
|
+
if (hasDisplayName) seed.displayName = displayName;
|
|
889
|
+
if (hasPhotoUrl) seed.photoUrl = photoUrl;
|
|
890
|
+
const hasPhoneNumber = phoneNumber !== null;
|
|
891
|
+
if (hasPhoneNumber) seed.phoneNumber = phoneNumber;
|
|
892
|
+
if (hasCustomClaims) seed.customClaims = u.customClaims;
|
|
893
|
+
if (emailVerified) seed.emailVerified = true;
|
|
894
|
+
if (disabled) seed.disabled = true;
|
|
895
|
+
if (hasTenant) seed.tenantId = tenantId;
|
|
737
896
|
out.push(seed);
|
|
738
897
|
}
|
|
739
898
|
return out;
|
|
@@ -892,8 +1051,10 @@ export class SandboxBackend {
|
|
|
892
1051
|
validateEmailFormat(email);
|
|
893
1052
|
const key = email.toLowerCase();
|
|
894
1053
|
const existing = this.usersByEmail.get(key);
|
|
895
|
-
|
|
896
|
-
|
|
1054
|
+
const hasAccount = existing !== undefined;
|
|
1055
|
+
if (hasAccount) {
|
|
1056
|
+
const needsPasswordProvider = !existing.providerUserInfo.some((p) => p.providerId === 'password');
|
|
1057
|
+
if (needsPasswordProvider) {
|
|
897
1058
|
existing.providerUserInfo.push({ providerId: 'password' });
|
|
898
1059
|
}
|
|
899
1060
|
// Redeeming a link mailed to this address proves control of it.
|
|
@@ -901,7 +1062,8 @@ export class SandboxBackend {
|
|
|
901
1062
|
this.notifyUsersChanged();
|
|
902
1063
|
return { stored: existing, isNewUser: false };
|
|
903
1064
|
}
|
|
904
|
-
|
|
1065
|
+
// Email punctuation is invalid in common UID-keyed RTDB paths.
|
|
1066
|
+
const uid = `email-${globalThis.crypto.randomUUID()}`;
|
|
905
1067
|
const record = this.makeStored({
|
|
906
1068
|
uid,
|
|
907
1069
|
email,
|
|
@@ -1042,13 +1204,15 @@ export class SandboxBackend {
|
|
|
1042
1204
|
validateEmailFormat(email);
|
|
1043
1205
|
validatePasswordStrength(password);
|
|
1044
1206
|
const key = email.toLowerCase();
|
|
1045
|
-
|
|
1207
|
+
const emailInUse = this.usersByEmail.has(key);
|
|
1208
|
+
if (emailInUse) {
|
|
1046
1209
|
throw makeAuthError(
|
|
1047
1210
|
'auth/email-already-in-use',
|
|
1048
1211
|
`An account already exists for ${email}.`,
|
|
1049
1212
|
);
|
|
1050
1213
|
}
|
|
1051
|
-
|
|
1214
|
+
// Email punctuation is invalid in common UID-keyed RTDB paths.
|
|
1215
|
+
const uid = `email-${globalThis.crypto.randomUUID()}`;
|
|
1052
1216
|
const record = this.makeStored({
|
|
1053
1217
|
uid,
|
|
1054
1218
|
email,
|
|
@@ -1160,6 +1324,13 @@ export class SandboxBackend {
|
|
|
1160
1324
|
* pre-resolved promise on the fast path instead of ever suspending.
|
|
1161
1325
|
*/
|
|
1162
1326
|
transitionCurrentUser(user: User | null, signInProvider?: string | null): Promise<void> {
|
|
1327
|
+
// A `signInProvider` argument marks a REAL sign-in, which is the moment
|
|
1328
|
+
// the tenant is fixed (the test driver omits it and leaves the tenant
|
|
1329
|
+
// alone). Applied before the gate runs so a `beforeAuthStateChanged`
|
|
1330
|
+
// callback inspecting the user sees the tenant it will sign in under.
|
|
1331
|
+
if (user !== null && signInProvider !== undefined) {
|
|
1332
|
+
this.scopeSignInToTenant(user);
|
|
1333
|
+
}
|
|
1163
1334
|
const hasActiveGate = this.beforeStateSubs.some((reg) => reg.active);
|
|
1164
1335
|
if (!hasActiveGate || user === this.cachedUser) {
|
|
1165
1336
|
this.setCurrentUser(user, signInProvider);
|
|
@@ -1187,8 +1358,24 @@ export class SandboxBackend {
|
|
|
1187
1358
|
* test driver (`sandbox.setUser`), which leaves any previous value
|
|
1188
1359
|
* in place.
|
|
1189
1360
|
*/
|
|
1361
|
+
/**
|
|
1362
|
+
* Fix a signing-in user to the handle's current {@link tenantId}. This is
|
|
1363
|
+
* the sandbox's stand-in for Identity Platform resolving credentials against
|
|
1364
|
+
* one tenant's user pool. The value lands in two places: on the `User` (so
|
|
1365
|
+
* `user.tenantId` reads back, matching `firebase/auth`) and on the stored
|
|
1366
|
+
* record (so a session restored after a reload, which rebuilds the user from
|
|
1367
|
+
* that record, keeps the tenant it authenticated with).
|
|
1368
|
+
*/
|
|
1369
|
+
private scopeSignInToTenant(user: User): void {
|
|
1370
|
+
const tenantId = this.tenantId;
|
|
1371
|
+
(user as Mutable<User>).tenantId = tenantId;
|
|
1372
|
+
const stored = this.usersByUid.get(user.uid);
|
|
1373
|
+
if (stored) stored.tenantId = tenantId;
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1190
1376
|
setCurrentUser(user: User | null, signInProvider?: string | null): void {
|
|
1191
|
-
|
|
1377
|
+
const signsOut = user === null;
|
|
1378
|
+
if (signsOut) {
|
|
1192
1379
|
// Sign-out. Drop the cached token so a later re-sign-in for the
|
|
1193
1380
|
// same uid mints a fresh one ("new session = new token"). Fire
|
|
1194
1381
|
// listeners only if we were actually signed in (signing out an
|
|
@@ -1201,7 +1388,8 @@ export class SandboxBackend {
|
|
|
1201
1388
|
} finally {
|
|
1202
1389
|
this.applyingTransition = false;
|
|
1203
1390
|
}
|
|
1204
|
-
|
|
1391
|
+
const hadUser = previousUser !== null;
|
|
1392
|
+
if (hadUser) {
|
|
1205
1393
|
this.tokenCache.delete(previousUser.uid);
|
|
1206
1394
|
this.notifyAuthListeners();
|
|
1207
1395
|
this.notifySessionChanged();
|
|
@@ -1216,9 +1404,10 @@ export class SandboxBackend {
|
|
|
1216
1404
|
return;
|
|
1217
1405
|
}
|
|
1218
1406
|
|
|
1407
|
+
const isSignIn = signInProvider !== undefined;
|
|
1219
1408
|
// Record this session's provider BEFORE any token mint below so
|
|
1220
1409
|
// the freshly-minted token carries the right sign_in_provider.
|
|
1221
|
-
if (
|
|
1410
|
+
if (isSignIn) {
|
|
1222
1411
|
this.signInProviderByUid.set(user.uid, signInProvider);
|
|
1223
1412
|
}
|
|
1224
1413
|
|
|
@@ -1230,8 +1419,9 @@ export class SandboxBackend {
|
|
|
1230
1419
|
|
|
1231
1420
|
// A `signInProvider` argument marks an actual sign-in (the test
|
|
1232
1421
|
// driver omits it) — bump the record's lastLoginAt.
|
|
1233
|
-
|
|
1234
|
-
|
|
1422
|
+
const recordsSignIn = isSignIn && stored !== undefined;
|
|
1423
|
+
if (recordsSignIn) {
|
|
1424
|
+
stored.lastLoginAt = this.now().toISOString();
|
|
1235
1425
|
this.notifyUsersChanged();
|
|
1236
1426
|
}
|
|
1237
1427
|
|
|
@@ -1242,12 +1432,15 @@ export class SandboxBackend {
|
|
|
1242
1432
|
// is unchanged (AUTH-B8: a same-uid re-sign-in still rotates the
|
|
1243
1433
|
// token, which `onIdTokenChanged` then observes). Matches prod's
|
|
1244
1434
|
// "new session = new token".
|
|
1245
|
-
this.
|
|
1435
|
+
const minted = this.mintToken(user.uid, claims, user.tenantId ?? null);
|
|
1246
1436
|
|
|
1247
1437
|
// Push to the sandbox under the guard so the synchronous subscriber
|
|
1248
1438
|
// doesn't notify — we drive the fan-out below with the correct
|
|
1249
1439
|
// id-token / auth-state split.
|
|
1250
|
-
const
|
|
1440
|
+
const signedInState: NonNullable<AuthState> = { uid: user.uid, token: rulesTokenClaims(claims, minted.result) };
|
|
1441
|
+
const hasTenant = typeof user.tenantId === 'string';
|
|
1442
|
+
if (hasTenant) signedInState.tenant = user.tenantId;
|
|
1443
|
+
const nextState: AuthState = signedInState;
|
|
1251
1444
|
this.applyingTransition = true;
|
|
1252
1445
|
try {
|
|
1253
1446
|
this.session.currentUser = nextState;
|
|
@@ -1265,7 +1458,7 @@ export class SandboxBackend {
|
|
|
1265
1458
|
// the test driver (`sandbox.setUser`) omits it and is not a sign-in
|
|
1266
1459
|
// worth surfacing on the activity stream. The acting identity IS the
|
|
1267
1460
|
// user that just signed in.
|
|
1268
|
-
if (
|
|
1461
|
+
if (isSignIn) {
|
|
1269
1462
|
this.emitAuthEvent('sign_in', {
|
|
1270
1463
|
path: user.uid,
|
|
1271
1464
|
auth: nextState,
|
|
@@ -1310,21 +1503,27 @@ export class SandboxBackend {
|
|
|
1310
1503
|
* with its real provider. Upserts: unknown uids get a fresh record
|
|
1311
1504
|
* (no password — these identities can't sign in via
|
|
1312
1505
|
* `signInWithEmailAndPassword`); known uids get the provider
|
|
1313
|
-
* appended to `providerUserInfo` if it isn't already linked
|
|
1506
|
+
* appended to `providerUserInfo` if it isn't already linked, and their
|
|
1507
|
+
* stored photo refreshed when the identity carries one (see
|
|
1508
|
+
* {@link refreshStoredPhoto}).
|
|
1314
1509
|
*/
|
|
1315
1510
|
recordProviderSignIn(user: User, providerId: string): void {
|
|
1316
1511
|
let changed = false;
|
|
1512
|
+
const identityPhotoUrl = user.photoURL ?? null;
|
|
1317
1513
|
let stored = this.usersByUid.get(user.uid);
|
|
1318
1514
|
if (!stored) {
|
|
1319
1515
|
stored = this.makeStored({
|
|
1320
1516
|
uid: user.uid,
|
|
1321
1517
|
email: user.email,
|
|
1322
1518
|
displayName: user.displayName,
|
|
1519
|
+
photoUrl: identityPhotoUrl,
|
|
1323
1520
|
isAnonymous: user.isAnonymous,
|
|
1324
|
-
});
|
|
1521
|
+
}, providerId);
|
|
1325
1522
|
this.usersByUid.set(user.uid, stored);
|
|
1326
1523
|
if (user.email) this.usersByEmail.set(user.email.toLowerCase(), stored);
|
|
1327
1524
|
changed = true;
|
|
1525
|
+
} else if (refreshStoredPhoto(stored, identityPhotoUrl)) {
|
|
1526
|
+
changed = true;
|
|
1328
1527
|
}
|
|
1329
1528
|
if (!stored.providerUserInfo.some((p) => p.providerId === providerId)) {
|
|
1330
1529
|
stored.providerUserInfo.push({ providerId });
|
|
@@ -1354,7 +1553,10 @@ export class SandboxBackend {
|
|
|
1354
1553
|
* and NO password (provider identities can't sign in via
|
|
1355
1554
|
* `signInWithEmailAndPassword`).
|
|
1356
1555
|
*
|
|
1357
|
-
* In both shapes the provider is linked into `providerUserInfo`.
|
|
1556
|
+
* In both shapes the provider is linked into `providerUserInfo`. A
|
|
1557
|
+
* `spec.photoUrl` is stored on a fresh record and refreshes a reused
|
|
1558
|
+
* same-email one; a spec without a photo never clears a stored one (see
|
|
1559
|
+
* {@link refreshStoredPhoto}).
|
|
1358
1560
|
* The credential does NOT sign the user in — hand it to the
|
|
1359
1561
|
* resolver's promise; `signInWithPopup`/`signInWithRedirect`
|
|
1360
1562
|
* complete the sign-in.
|
|
@@ -1374,19 +1576,24 @@ export class SandboxBackend {
|
|
|
1374
1576
|
`createSignInCredential: no identity with uid ${req.uid}. Use the {spec} shape to create one.`,
|
|
1375
1577
|
);
|
|
1376
1578
|
}
|
|
1579
|
+
this.assertUserEnabled(found);
|
|
1377
1580
|
stored = found;
|
|
1378
1581
|
} else {
|
|
1379
1582
|
const { spec } = req;
|
|
1583
|
+
const specPhotoUrl = spec.photoUrl ?? null;
|
|
1380
1584
|
const byEmail = this.usersByEmail.get(spec.email.toLowerCase());
|
|
1381
1585
|
if (byEmail) {
|
|
1586
|
+
this.assertUserEnabled(byEmail);
|
|
1382
1587
|
stored = byEmail;
|
|
1588
|
+
if (refreshStoredPhoto(stored, specPhotoUrl)) this.notifyUsersChanged();
|
|
1383
1589
|
} else {
|
|
1384
1590
|
stored = this.makeStored({
|
|
1385
1591
|
uid: spec.uid ?? mintProviderUid(),
|
|
1386
1592
|
email: spec.email,
|
|
1387
1593
|
displayName: spec.displayName ?? null,
|
|
1594
|
+
photoUrl: specPhotoUrl,
|
|
1388
1595
|
customClaims: spec.customClaims ?? {},
|
|
1389
|
-
});
|
|
1596
|
+
}, providerId);
|
|
1390
1597
|
this.usersByUid.set(stored.uid, stored);
|
|
1391
1598
|
this.usersByEmail.set(spec.email.toLowerCase(), stored);
|
|
1392
1599
|
this.notifyUsersChanged();
|
|
@@ -1447,6 +1654,7 @@ export class SandboxBackend {
|
|
|
1447
1654
|
isAnonymous: u.isAnonymous,
|
|
1448
1655
|
disabled: u.disabled,
|
|
1449
1656
|
emailVerified: u.emailVerified,
|
|
1657
|
+
tenantId: u.tenantId,
|
|
1450
1658
|
createdAt: u.createdAt,
|
|
1451
1659
|
lastLoginAt: u.lastLoginAt,
|
|
1452
1660
|
};
|
|
@@ -1487,11 +1695,20 @@ export class SandboxBackend {
|
|
|
1487
1695
|
return next;
|
|
1488
1696
|
}
|
|
1489
1697
|
|
|
1698
|
+
/** Restored or explicitly seeded users may already occupy generated IDs. */
|
|
1699
|
+
private nextAvailableAdminUid(): string {
|
|
1700
|
+
for (;;) {
|
|
1701
|
+
const uid = `user-${this.sharedCounters.nextAdminUserId++}`;
|
|
1702
|
+
const isAvailable = !this.usersByUid.has(uid);
|
|
1703
|
+
if (isAvailable) return uid;
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1490
1707
|
/** Admin user creation. Does NOT sign the user in (unlike
|
|
1491
1708
|
* `createUserWithEmailAndPassword`) — matches the emulator's
|
|
1492
1709
|
* add-user flow / admin SDK semantics. */
|
|
1493
1710
|
createUser(req: CreateUserRequest): AuthUserRecord {
|
|
1494
|
-
const uid = req.uid ??
|
|
1711
|
+
const uid = req.uid ?? this.nextAvailableAdminUid();
|
|
1495
1712
|
if (this.usersByUid.has(uid)) {
|
|
1496
1713
|
throw makeAuthError(
|
|
1497
1714
|
'auth/uid-already-exists',
|
|
@@ -1656,6 +1873,7 @@ export class SandboxBackend {
|
|
|
1656
1873
|
emailVerified: stored.emailVerified,
|
|
1657
1874
|
phoneNumber: stored.phoneNumber,
|
|
1658
1875
|
providers: stored.providerUserInfo,
|
|
1876
|
+
tenantId: stored.tenantId,
|
|
1659
1877
|
});
|
|
1660
1878
|
}
|
|
1661
1879
|
|
|
@@ -1664,7 +1882,7 @@ export class SandboxBackend {
|
|
|
1664
1882
|
* the emulator) so `listIdentities` / future user-admin surfaces
|
|
1665
1883
|
* see anonymous accounts too. */
|
|
1666
1884
|
mintAnonymousUser(): User {
|
|
1667
|
-
const uid = `anonymous-${
|
|
1885
|
+
const uid = `anonymous-${globalThis.crypto.randomUUID()}`;
|
|
1668
1886
|
const record = this.makeStored({ uid, isAnonymous: true });
|
|
1669
1887
|
this.usersByUid.set(uid, record);
|
|
1670
1888
|
this.notifyUsersChanged();
|
|
@@ -1706,36 +1924,44 @@ export class SandboxBackend {
|
|
|
1706
1924
|
* authenticated session, same as real Firebase.
|
|
1707
1925
|
*/
|
|
1708
1926
|
mintDetachedSession(request: MintSessionRequest): MintedSession {
|
|
1927
|
+
const tenantId = request.tenantId ?? null;
|
|
1709
1928
|
switch (request.kind) {
|
|
1710
1929
|
case 'anonymous':
|
|
1711
1930
|
this.assertProviderEnabled('anonymous');
|
|
1712
|
-
return this.establishDetachedSession(this.mintAnonymousUser(), 'anonymous');
|
|
1931
|
+
return this.establishDetachedSession(this.mintAnonymousUser(), 'anonymous', tenantId);
|
|
1713
1932
|
case 'password':
|
|
1714
1933
|
this.assertProviderEnabled('password');
|
|
1715
1934
|
return this.establishDetachedSession(
|
|
1716
1935
|
this.buildUserFromStored(this.validatePassword(request.email, request.password)),
|
|
1717
1936
|
'password',
|
|
1937
|
+
tenantId,
|
|
1718
1938
|
);
|
|
1719
1939
|
case 'createPassword':
|
|
1720
1940
|
this.assertProviderEnabled('password');
|
|
1721
1941
|
return this.establishDetachedSession(
|
|
1722
1942
|
this.buildUserFromStored(this.createEmailPasswordUser(request.email, request.password)),
|
|
1723
1943
|
'password',
|
|
1944
|
+
tenantId,
|
|
1724
1945
|
);
|
|
1946
|
+
case 'provider':
|
|
1947
|
+
case 'custom':
|
|
1725
1948
|
case 'uid': {
|
|
1949
|
+
const isProviderSignIn = request.kind === 'provider';
|
|
1950
|
+
if (isProviderSignIn) this.assertProviderEnabled(request.providerId);
|
|
1726
1951
|
// restoreSession semantics minus the global set: an EXISTING
|
|
1727
1952
|
// identity (per-tab session restore / provider-bridge accept).
|
|
1728
1953
|
const stored = this.usersByUid.get(request.uid);
|
|
1729
|
-
|
|
1954
|
+
const missingUser = stored === undefined;
|
|
1955
|
+
if (missingUser) {
|
|
1730
1956
|
throw makeAuthError('auth/user-not-found', `mintSession: no identity with uid ${request.uid}.`);
|
|
1731
1957
|
}
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
return this.establishDetachedSession(this.buildUserFromStored(stored), providerId);
|
|
1958
|
+
this.assertUserEnabled(stored);
|
|
1959
|
+
const isAnonymous = stored.isAnonymous;
|
|
1960
|
+
const restoredProvider = isAnonymous ? 'anonymous' : (stored.providerUserInfo[0]?.providerId ?? 'password');
|
|
1961
|
+
let providerId = isProviderSignIn ? request.providerId : restoredProvider;
|
|
1962
|
+
const isCustomSignIn = request.kind === 'custom';
|
|
1963
|
+
if (isCustomSignIn) providerId = 'custom';
|
|
1964
|
+
return this.establishDetachedSession(this.buildUserFromStored(stored), providerId, tenantId);
|
|
1739
1965
|
}
|
|
1740
1966
|
}
|
|
1741
1967
|
}
|
|
@@ -1743,16 +1969,27 @@ export class SandboxBackend {
|
|
|
1743
1969
|
/** The shared sign-in bookkeeping behind {@link mintDetachedSession} —
|
|
1744
1970
|
* everything {@link setCurrentUser} does for a real sign-in EXCEPT the
|
|
1745
1971
|
* global-session parts. */
|
|
1746
|
-
private establishDetachedSession(
|
|
1972
|
+
private establishDetachedSession(
|
|
1973
|
+
user: User,
|
|
1974
|
+
signInProvider: string,
|
|
1975
|
+
tenantId: string | null,
|
|
1976
|
+
): MintedSession {
|
|
1747
1977
|
this.signInProviderByUid.set(user.uid, signInProvider);
|
|
1748
1978
|
const stored = this.usersByUid.get(user.uid);
|
|
1749
1979
|
const claims = stored?.customClaims ?? {};
|
|
1750
|
-
|
|
1751
|
-
|
|
1980
|
+
const hasStoredUser = stored !== undefined;
|
|
1981
|
+
if (hasStoredUser) {
|
|
1982
|
+
stored.lastLoginAt = this.now().toISOString();
|
|
1752
1983
|
this.notifyUsersChanged();
|
|
1753
1984
|
}
|
|
1754
|
-
|
|
1755
|
-
|
|
1985
|
+
// The tenant rides on the session, not on the shared record: ports are
|
|
1986
|
+
// independent sessions over one user pool, so two ports can hold the same
|
|
1987
|
+
// identity under different tenants and neither may overwrite the other.
|
|
1988
|
+
(user as Mutable<User>).tenantId = tenantId;
|
|
1989
|
+
const minted = this.mintToken(user.uid, claims, tenantId);
|
|
1990
|
+
const state: NonNullable<AuthState> = { uid: user.uid, token: rulesTokenClaims(claims, minted.result) };
|
|
1991
|
+
const hasTenant = tenantId !== null;
|
|
1992
|
+
if (hasTenant) state.tenant = tenantId;
|
|
1756
1993
|
this.emitAuthEvent('sign_in', {
|
|
1757
1994
|
path: user.uid,
|
|
1758
1995
|
auth: state,
|
|
@@ -1776,6 +2013,7 @@ export class SandboxBackend {
|
|
|
1776
2013
|
return this.buildUserFromStored({
|
|
1777
2014
|
...stored,
|
|
1778
2015
|
customClaims: state.token ?? stored.customClaims,
|
|
2016
|
+
tenantId: state.tenant ?? stored.tenantId,
|
|
1779
2017
|
});
|
|
1780
2018
|
}
|
|
1781
2019
|
return this.makeUser({
|
|
@@ -1784,6 +2022,7 @@ export class SandboxBackend {
|
|
|
1784
2022
|
displayName: null,
|
|
1785
2023
|
isAnonymous: state.uid.startsWith('anonymous-'),
|
|
1786
2024
|
claims: state.token ?? {},
|
|
2025
|
+
tenantId: state.tenant ?? null,
|
|
1787
2026
|
});
|
|
1788
2027
|
}
|
|
1789
2028
|
|
|
@@ -1799,12 +2038,12 @@ export class SandboxBackend {
|
|
|
1799
2038
|
private mintToken(
|
|
1800
2039
|
uid: string,
|
|
1801
2040
|
claims: Record<string, unknown>,
|
|
2041
|
+
tenantId: string | null,
|
|
1802
2042
|
): { token: string; result: IdTokenResult } {
|
|
1803
|
-
const issuedAt =
|
|
2043
|
+
const issuedAt = this.now();
|
|
1804
2044
|
// 100 years out — sandbox tokens never expire.
|
|
1805
2045
|
const expires = new Date(issuedAt.getTime() + 100 * 365 * 24 * 60 * 60 * 1000);
|
|
1806
2046
|
const serial = this.nextTokenSerial++;
|
|
1807
|
-
const token = sandboxTokenFor(uid, claims, serial);
|
|
1808
2047
|
// The provider of the current sign-in session for this uid —
|
|
1809
2048
|
// recorded by setCurrentUser at sign-in time. Null for identities
|
|
1810
2049
|
// driven via the test driver (no prod analog for that path).
|
|
@@ -1823,15 +2062,23 @@ export class SandboxBackend {
|
|
|
1823
2062
|
// `firebase.sign_in_provider`.
|
|
1824
2063
|
firebase: { sign_in_provider: signInProvider },
|
|
1825
2064
|
};
|
|
2065
|
+
const identity = normalizeAuthState({ uid, tenant: tenantId ?? undefined, token: fullClaims });
|
|
2066
|
+
const tokenClaims = identity?.token ?? fullClaims;
|
|
2067
|
+
const sessionClaims = { ...claims, firebase: tokenClaims.firebase };
|
|
2068
|
+
const token = sandboxTokenFor(uid, sessionClaims, serial);
|
|
1826
2069
|
const result: IdTokenResult = {
|
|
1827
2070
|
token,
|
|
1828
|
-
claims:
|
|
2071
|
+
claims: tokenClaims,
|
|
1829
2072
|
expirationTime: expires.toISOString(),
|
|
1830
2073
|
issuedAtTime: issuedAt.toISOString(),
|
|
1831
2074
|
authTime: issuedAt.toISOString(),
|
|
1832
2075
|
signInProvider,
|
|
1833
2076
|
};
|
|
1834
|
-
|
|
2077
|
+
const entry = { token, result };
|
|
2078
|
+
const tokens = this.tokenCache.get(uid) ?? new Map<string | null, typeof entry>();
|
|
2079
|
+
tokens.set(tenantId, entry);
|
|
2080
|
+
this.tokenCache.set(uid, tokens);
|
|
2081
|
+
return entry;
|
|
1835
2082
|
}
|
|
1836
2083
|
|
|
1837
2084
|
/**
|
|
@@ -1850,20 +2097,9 @@ export class SandboxBackend {
|
|
|
1850
2097
|
uid: string,
|
|
1851
2098
|
claims: Record<string, unknown>,
|
|
1852
2099
|
forceRefresh: boolean,
|
|
2100
|
+
tenantId: string | null = null,
|
|
1853
2101
|
): string {
|
|
1854
|
-
|
|
1855
|
-
const fresh = this.mintToken(uid, claims);
|
|
1856
|
-
this.tokenCache.set(uid, fresh);
|
|
1857
|
-
// Fan out to onIdTokenChanged listeners only — identity is
|
|
1858
|
-
// unchanged, so onAuthStateChanged stays silent.
|
|
1859
|
-
this.fanOut('id-token');
|
|
1860
|
-
return fresh.token;
|
|
1861
|
-
}
|
|
1862
|
-
const cached = this.tokenCache.get(uid);
|
|
1863
|
-
if (cached) return cached.token;
|
|
1864
|
-
const fresh = this.mintToken(uid, claims);
|
|
1865
|
-
this.tokenCache.set(uid, fresh);
|
|
1866
|
-
return fresh.token;
|
|
2102
|
+
return this.getIdTokenResultFor(uid, claims, forceRefresh, tenantId).token;
|
|
1867
2103
|
}
|
|
1868
2104
|
|
|
1869
2105
|
/** {@link getIdTokenFor} variant returning the full IdTokenResult.
|
|
@@ -1872,17 +2108,28 @@ export class SandboxBackend {
|
|
|
1872
2108
|
uid: string,
|
|
1873
2109
|
claims: Record<string, unknown>,
|
|
1874
2110
|
forceRefresh: boolean,
|
|
2111
|
+
tenantId: string | null = null,
|
|
1875
2112
|
): IdTokenResult {
|
|
1876
2113
|
if (forceRefresh) {
|
|
1877
|
-
const fresh = this.mintToken(uid, claims);
|
|
1878
|
-
this.
|
|
2114
|
+
const fresh = this.mintToken(uid, claims, tenantId);
|
|
2115
|
+
const current = this.session.currentUser;
|
|
2116
|
+
const refreshesCurrentUser = current !== null && current.uid === uid && (current.tenant ?? null) === tenantId;
|
|
2117
|
+
if (refreshesCurrentUser) {
|
|
2118
|
+
// Rules follow refreshed claims without turning a token refresh into a sign-in.
|
|
2119
|
+
this.applyingTransition = true;
|
|
2120
|
+
try {
|
|
2121
|
+
this.session.currentUser = { ...current, token: rulesTokenClaims(claims, fresh.result) };
|
|
2122
|
+
} finally {
|
|
2123
|
+
this.applyingTransition = false;
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
1879
2126
|
this.fanOut('id-token');
|
|
1880
2127
|
return fresh.result;
|
|
1881
2128
|
}
|
|
1882
|
-
const cached = this.tokenCache.get(uid);
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
this.
|
|
2129
|
+
const cached = this.tokenCache.get(uid)?.get(tenantId);
|
|
2130
|
+
const hasCachedToken = cached !== undefined;
|
|
2131
|
+
if (hasCachedToken) return cached.result;
|
|
2132
|
+
const fresh = this.mintToken(uid, claims, tenantId);
|
|
1886
2133
|
return fresh.result;
|
|
1887
2134
|
}
|
|
1888
2135
|
|
|
@@ -1903,6 +2150,8 @@ export class SandboxBackend {
|
|
|
1903
2150
|
phoneNumber?: string | null;
|
|
1904
2151
|
/** The identity's LINKED providers, from its stored record. */
|
|
1905
2152
|
providers?: ProviderUserInfo[];
|
|
2153
|
+
/** Tenant this identity authenticated under. Absent means untenanted. */
|
|
2154
|
+
tenantId?: string | null;
|
|
1906
2155
|
}): User {
|
|
1907
2156
|
const photoURL = args.photoURL ?? null;
|
|
1908
2157
|
const phoneNumber = args.phoneNumber ?? null;
|
|
@@ -1927,7 +2176,8 @@ export class SandboxBackend {
|
|
|
1927
2176
|
// `unlink` of the last provider produces. Falling back on `[]` would
|
|
1928
2177
|
// resurrect the very provider the user just removed.
|
|
1929
2178
|
const linked: ProviderUserInfo[] = args.providers ?? [{ providerId: 'password' }];
|
|
1930
|
-
const
|
|
2179
|
+
const isAnonymous = args.isAnonymous === true;
|
|
2180
|
+
const providerData: UserInfo[] = isAnonymous
|
|
1931
2181
|
? []
|
|
1932
2182
|
: linked.map((p) => ({
|
|
1933
2183
|
uid: args.uid,
|
|
@@ -1945,6 +2195,7 @@ export class SandboxBackend {
|
|
|
1945
2195
|
photoURL,
|
|
1946
2196
|
phoneNumber,
|
|
1947
2197
|
isAnonymous: args.isAnonymous,
|
|
2198
|
+
tenantId: args.tenantId ?? null,
|
|
1948
2199
|
providerId,
|
|
1949
2200
|
providerData,
|
|
1950
2201
|
// Read LIVE claims by uid on each token call (not the claims frozen
|
|
@@ -1954,9 +2205,9 @@ export class SandboxBackend {
|
|
|
1954
2205
|
// Falls back to the closed-over claims for users not in the DB
|
|
1955
2206
|
// (anonymous / popup), matching how they were minted.
|
|
1956
2207
|
getIdToken: async (forceRefresh?: boolean) =>
|
|
1957
|
-
this.getIdTokenFor(args.uid, this.liveClaims(args.uid, args.claims), forceRefresh === true),
|
|
2208
|
+
this.getIdTokenFor(args.uid, this.liveClaims(args.uid, args.claims), forceRefresh === true, user.tenantId),
|
|
1958
2209
|
getIdTokenResult: async (forceRefresh?: boolean) =>
|
|
1959
|
-
this.getIdTokenResultFor(args.uid, this.liveClaims(args.uid, args.claims), forceRefresh === true),
|
|
2210
|
+
this.getIdTokenResultFor(args.uid, this.liveClaims(args.uid, args.claims), forceRefresh === true, user.tenantId),
|
|
1960
2211
|
};
|
|
1961
2212
|
// Stamp the backend-dispatch hook non-enumerably so the top-level
|
|
1962
2213
|
// `updateProfile(user, …)` free function can update THIS user (and the
|
|
@@ -2200,6 +2451,12 @@ export class SandboxBackend {
|
|
|
2200
2451
|
return this.usersByUid.get(uid)?.customClaims ?? fallback;
|
|
2201
2452
|
}
|
|
2202
2453
|
|
|
2454
|
+
private assertUserEnabled(user: StoredUser): void {
|
|
2455
|
+
if (user.disabled) {
|
|
2456
|
+
throw makeAuthError('auth/user-disabled', 'The user account has been disabled by an administrator.');
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
|
|
2203
2460
|
/** Internal validator for email/password — checks the password
|
|
2204
2461
|
* matches the stored record. Throws `auth/invalid-email` on a
|
|
2205
2462
|
* malformed email, `auth/wrong-password` on mismatch,
|
|
@@ -2238,12 +2495,7 @@ export class SandboxBackend {
|
|
|
2238
2495
|
// exact prod ordering (disabled-vs-wrong-password) is flagged for
|
|
2239
2496
|
// an oracle capture; the code (`auth/user-disabled`) and message
|
|
2240
2497
|
// match prod's documented shape.
|
|
2241
|
-
|
|
2242
|
-
throw makeAuthError(
|
|
2243
|
-
'auth/user-disabled',
|
|
2244
|
-
'The user account has been disabled by an administrator.',
|
|
2245
|
-
);
|
|
2246
|
-
}
|
|
2498
|
+
this.assertUserEnabled(stored);
|
|
2247
2499
|
if (stored.password !== password) {
|
|
2248
2500
|
throw makeAuthError(
|
|
2249
2501
|
'auth/wrong-password',
|
|
@@ -2254,6 +2506,60 @@ export class SandboxBackend {
|
|
|
2254
2506
|
}
|
|
2255
2507
|
}
|
|
2256
2508
|
|
|
2509
|
+
/**
|
|
2510
|
+
* Apply a provider sign-in's photo to an already-stored identity, reporting
|
|
2511
|
+
* whether the record changed.
|
|
2512
|
+
*
|
|
2513
|
+
* A provider sign-in refreshes the provider profile data it actually carries.
|
|
2514
|
+
* An identity that carries no photo leaves the stored one alone rather than
|
|
2515
|
+
* blanking it, mirroring Firebase: a provider refresh updates the fields the
|
|
2516
|
+
* provider supplied and never clears one it omitted.
|
|
2517
|
+
*/
|
|
2518
|
+
/**
|
|
2519
|
+
* The provider a record is being created under: the provider a sign-in flow
|
|
2520
|
+
* names explicitly, otherwise the first provider already on the record. Null
|
|
2521
|
+
* when neither exists — an anonymous or provider-less record.
|
|
2522
|
+
*/
|
|
2523
|
+
function creationProviderId(
|
|
2524
|
+
record: StoredUser,
|
|
2525
|
+
signInProviderId: string | null,
|
|
2526
|
+
): string | null {
|
|
2527
|
+
if (signInProviderId !== null) return signInProviderId;
|
|
2528
|
+
const firstLinked = record.providerUserInfo[0];
|
|
2529
|
+
if (firstLinked === undefined) return null;
|
|
2530
|
+
return firstLinked.providerId;
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2533
|
+
/**
|
|
2534
|
+
* Whether a freshly built record gets a default photo.
|
|
2535
|
+
*
|
|
2536
|
+
* Firebase populates `photoURL` only for federated identities: a real Google
|
|
2537
|
+
* or GitHub sign-in always returns one, while `password`, `phone`, email-link,
|
|
2538
|
+
* and anonymous users return null in production. Federated provider ids are
|
|
2539
|
+
* exactly the dotted ones (`google.com`, `github.com`, `oidc.acme`,
|
|
2540
|
+
* `saml.corp`); the first-party ids never contain a dot. Defaulting everyone
|
|
2541
|
+
* would trade this divergence for a new one.
|
|
2542
|
+
*
|
|
2543
|
+
* A photo the caller supplied always wins — the mint only fills a record that
|
|
2544
|
+
* would otherwise be photo-less.
|
|
2545
|
+
*/
|
|
2546
|
+
function mintsDefaultPhoto(
|
|
2547
|
+
record: StoredUser,
|
|
2548
|
+
providerId: string | null,
|
|
2549
|
+
): providerId is string {
|
|
2550
|
+
if (record.photoUrl !== null) return false;
|
|
2551
|
+
if (record.isAnonymous) return false;
|
|
2552
|
+
if (providerId === null) return false;
|
|
2553
|
+
return providerId.includes('.');
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
function refreshStoredPhoto(stored: StoredUser, photoUrl: string | null): boolean {
|
|
2557
|
+
if (photoUrl === null) return false;
|
|
2558
|
+
if (stored.photoUrl === photoUrl) return false;
|
|
2559
|
+
stored.photoUrl = photoUrl;
|
|
2560
|
+
return true;
|
|
2561
|
+
}
|
|
2562
|
+
|
|
2257
2563
|
/** Provider UIDs are opaque Firebase identifiers, not encoded credentials. */
|
|
2258
2564
|
function mintProviderUid(): string {
|
|
2259
2565
|
return `provider-${globalThis.crypto.randomUUID()}`;
|