pyric 0.1.0-alpha.20 → 0.1.0-alpha.21
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 +64 -89
- package/dist/ai/blocked.d.ts +52 -0
- package/dist/ai/blocked.d.ts.map +1 -0
- package/dist/ai/blocked.js +83 -0
- package/dist/ai/blocked.js.map +1 -0
- package/dist/ai/broker/broker.d.ts +49 -0
- package/dist/ai/broker/broker.d.ts.map +1 -1
- package/dist/ai/broker/broker.js +90 -0
- package/dist/ai/broker/broker.js.map +1 -1
- package/dist/ai/broker/gemini-engine.d.ts +14 -1
- package/dist/ai/broker/gemini-engine.d.ts.map +1 -1
- package/dist/ai/broker/gemini-engine.js +30 -9
- package/dist/ai/broker/gemini-engine.js.map +1 -1
- package/dist/ai/broker/index.d.ts +2 -2
- package/dist/ai/broker/index.d.ts.map +1 -1
- package/dist/ai/broker/index.js +2 -2
- package/dist/ai/broker/index.js.map +1 -1
- package/dist/ai/broker/openai-engine.d.ts +10 -1
- package/dist/ai/broker/openai-engine.d.ts.map +1 -1
- package/dist/ai/broker/openai-engine.js +26 -4
- package/dist/ai/broker/openai-engine.js.map +1 -1
- package/dist/ai/broker/synthesizer.d.ts +14 -0
- package/dist/ai/broker/synthesizer.d.ts.map +1 -1
- package/dist/ai/broker/synthesizer.js +31 -0
- package/dist/ai/broker/synthesizer.js.map +1 -1
- package/dist/ai/broker/types.d.ts +24 -0
- package/dist/ai/broker/types.d.ts.map +1 -1
- package/dist/ai/internal.d.ts +5 -0
- package/dist/ai/internal.d.ts.map +1 -1
- package/dist/ai/internal.js +5 -0
- package/dist/ai/internal.js.map +1 -1
- package/dist/ai/response-helpers.d.ts.map +1 -1
- package/dist/ai/response-helpers.js +6 -24
- package/dist/ai/response-helpers.js.map +1 -1
- package/dist/analytics/index.d.ts +40 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +25 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/app-check/index.d.ts +31 -0
- package/dist/app-check/index.d.ts.map +1 -0
- package/dist/app-check/index.js +20 -0
- package/dist/app-check/index.js.map +1 -0
- package/dist/database/controls.d.ts +1 -1
- package/dist/database/controls.js +1 -1
- package/dist/database/sandbox/rules-eval.d.ts +1 -1
- package/dist/database/sandbox/rules-eval.d.ts.map +1 -1
- package/dist/database/sandbox/rules-eval.js +2 -2
- package/dist/database/sandbox/rules-eval.js.map +1 -1
- package/dist/database/sandbox/write-plane.js +2 -2
- package/dist/database/sandbox/write-plane.js.map +1 -1
- package/dist/database/sandbox-controls.d.ts +12 -5
- package/dist/database/sandbox-controls.d.ts.map +1 -1
- package/dist/database/sandbox-controls.js +20 -9
- package/dist/database/sandbox-controls.js.map +1 -1
- package/dist/deferred/entry.d.ts +75 -0
- package/dist/deferred/entry.d.ts.map +1 -0
- package/dist/deferred/entry.js +143 -0
- package/dist/deferred/entry.js.map +1 -0
- package/dist/firestore/lite.d.ts +72 -0
- package/dist/firestore/lite.d.ts.map +1 -0
- package/dist/firestore/lite.js +22 -0
- package/dist/firestore/lite.js.map +1 -0
- package/dist/firestore/persistence.d.ts +2 -2
- package/dist/firestore/persistence.js +1 -1
- package/dist/functions/index.d.ts +29 -0
- package/dist/functions/index.d.ts.map +1 -0
- package/dist/functions/index.js +20 -0
- package/dist/functions/index.js.map +1 -0
- package/dist/performance/index.d.ts +22 -0
- package/dist/performance/index.d.ts.map +1 -0
- package/dist/performance/index.js +19 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/remote-config/index.d.ts +40 -0
- package/dist/remote-config/index.d.ts.map +1 -0
- package/dist/remote-config/index.js +25 -0
- package/dist/remote-config/index.js.map +1 -0
- package/dist/rules/grammar/FirestoreValidator.d.ts.map +1 -1
- package/dist/rules/grammar/FirestoreValidator.js +43 -27
- package/dist/rules/grammar/FirestoreValidator.js.map +1 -1
- package/dist/rules/grammar/document-access-count.d.ts +24 -0
- package/dist/rules/grammar/document-access-count.d.ts.map +1 -0
- package/dist/rules/grammar/document-access-count.js +100 -0
- package/dist/rules/grammar/document-access-count.js.map +1 -0
- package/dist/rules/linter/ast-utils.d.ts +2 -6
- package/dist/rules/linter/ast-utils.d.ts.map +1 -1
- package/dist/rules/linter/ast-utils.js +2 -63
- package/dist/rules/linter/ast-utils.js.map +1 -1
- package/dist/rules/linter/hallucinations.d.ts +8 -0
- package/dist/rules/linter/hallucinations.d.ts.map +1 -1
- package/dist/rules/linter/hallucinations.js +121 -31
- package/dist/rules/linter/hallucinations.js.map +1 -1
- package/dist/rules/linter/linter.d.ts +10 -1
- package/dist/rules/linter/linter.d.ts.map +1 -1
- package/dist/rules/linter/linter.js +23 -9
- package/dist/rules/linter/linter.js.map +1 -1
- package/dist/rules/rtdb/grammar/simulator.d.ts.map +1 -1
- package/dist/rules/rtdb/grammar/simulator.js +13 -13
- package/dist/rules/rtdb/grammar/simulator.js.map +1 -1
- package/dist/rules/rtdb/simulation/handler.d.ts.map +1 -1
- package/dist/rules/rtdb/simulation/handler.js +96 -35
- package/dist/rules/rtdb/simulation/handler.js.map +1 -1
- package/dist/rules/simulator/document-lookups.d.ts +4 -0
- package/dist/rules/simulator/document-lookups.d.ts.map +1 -1
- package/dist/rules/simulator/document-lookups.js +42 -3
- package/dist/rules/simulator/document-lookups.js.map +1 -1
- package/dist/rules/simulator/eval-error.d.ts +11 -0
- package/dist/rules/simulator/eval-error.d.ts.map +1 -1
- package/dist/rules/simulator/eval-error.js +14 -0
- package/dist/rules/simulator/eval-error.js.map +1 -1
- package/dist/rules/simulator/evaluation-builtins.d.ts.map +1 -1
- package/dist/rules/simulator/evaluation-builtins.js +33 -8
- package/dist/rules/simulator/evaluation-builtins.js.map +1 -1
- package/dist/rules/simulator/evaluation-context.d.ts +12 -0
- package/dist/rules/simulator/evaluation-context.d.ts.map +1 -1
- package/dist/rules/simulator/evaluator.d.ts +1 -1
- package/dist/rules/simulator/evaluator.d.ts.map +1 -1
- package/dist/rules/simulator/evaluator.js +16 -4
- 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 +52 -5
- package/dist/rules/simulator/handler.js.map +1 -1
- package/dist/rules/simulator/lookup-budget.d.ts +37 -0
- package/dist/rules/simulator/lookup-budget.d.ts.map +1 -0
- package/dist/rules/simulator/lookup-budget.js +96 -0
- package/dist/rules/simulator/lookup-budget.js.map +1 -0
- package/dist/rules/stdlib-modules.d.ts +7 -0
- package/dist/rules/stdlib-modules.d.ts.map +1 -1
- package/dist/rules/stdlib-modules.js +11 -11
- package/dist/rules/stdlib-modules.js.map +1 -1
- package/dist/sandbox/admin-firestore/get-firestore.d.ts +6 -0
- package/dist/sandbox/admin-firestore/get-firestore.d.ts.map +1 -1
- package/dist/sandbox/admin-firestore/get-firestore.js +22 -3
- package/dist/sandbox/admin-firestore/get-firestore.js.map +1 -1
- package/dist/sandbox/index.d.ts +1 -1
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +1 -1
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/persistence/types.d.ts +1 -1
- package/dist/sandbox/remote.d.ts +2 -2
- package/dist/sandbox/sandbox-context.d.ts +8 -1
- package/dist/sandbox/sandbox-context.d.ts.map +1 -1
- package/dist/sandbox/sandbox-context.js +59 -8
- package/dist/sandbox/sandbox-context.js.map +1 -1
- package/dist/sandbox/types/auth-state.d.ts +1 -0
- package/dist/sandbox/types/auth-state.d.ts.map +1 -1
- package/dist/sandbox/types/events.d.ts +2 -1
- package/dist/sandbox/types/events.d.ts.map +1 -1
- package/dist/sandbox/types/operation.d.ts +1 -0
- package/dist/sandbox/types/operation.d.ts.map +1 -1
- package/dist/storage/enforce.d.ts +20 -1
- package/dist/storage/enforce.d.ts.map +1 -1
- package/dist/storage/enforce.js +47 -14
- package/dist/storage/enforce.js.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/list.js +1 -1
- package/dist/storage/list.js.map +1 -1
- package/dist/storage/sandbox/rules-evaluation-error.d.ts +25 -0
- package/dist/storage/sandbox/rules-evaluation-error.d.ts.map +1 -1
- package/dist/storage/sandbox/rules-evaluation-error.js +29 -0
- package/dist/storage/sandbox/rules-evaluation-error.js.map +1 -1
- package/dist/storage/sandbox/rules-evaluator.d.ts +10 -5
- package/dist/storage/sandbox/rules-evaluator.d.ts.map +1 -1
- package/dist/storage/sandbox/rules-evaluator.js +105 -33
- package/dist/storage/sandbox/rules-evaluator.js.map +1 -1
- package/dist/storage/sandbox/rules-methods.d.ts.map +1 -1
- package/dist/storage/sandbox/rules-methods.js +17 -7
- package/dist/storage/sandbox/rules-methods.js.map +1 -1
- package/dist/storage/service.d.ts +23 -2
- package/dist/storage/service.d.ts.map +1 -1
- package/dist/storage/service.js +36 -26
- package/dist/storage/service.js.map +1 -1
- package/package.json +41 -1
- package/src/ai/blocked.ts +97 -0
- package/src/ai/broker/broker.ts +88 -0
- package/src/ai/broker/gemini-engine.ts +36 -9
- package/src/ai/broker/index.ts +2 -1
- package/src/ai/broker/openai-engine.ts +31 -3
- package/src/ai/broker/synthesizer.ts +34 -0
- package/src/ai/broker/types.ts +25 -0
- package/src/ai/internal.ts +5 -0
- package/src/ai/response-helpers.ts +6 -25
- package/src/analytics/index.ts +53 -0
- package/src/app/dispatch.test.ts +3 -1
- package/src/app-check/index.ts +41 -0
- package/src/database/controls.ts +1 -1
- package/src/database/sandbox/rules-eval.ts +2 -2
- package/src/database/sandbox/write-plane.ts +2 -2
- package/src/database/sandbox-controls.ts +29 -9
- package/src/deferred/entry.ts +167 -0
- package/src/firestore/lite.ts +91 -0
- package/src/firestore/persistence.ts +2 -2
- package/src/functions/index.ts +38 -0
- package/src/performance/index.ts +31 -0
- package/src/remote-config/index.ts +53 -0
- package/src/rules/grammar/FirestoreValidator.ts +44 -28
- package/src/rules/grammar/document-access-count.ts +75 -0
- package/src/rules/linter/ast-utils.ts +2 -36
- package/src/rules/linter/hallucinations.ts +123 -25
- package/src/rules/linter/linter.ts +32 -10
- package/src/rules/rtdb/grammar/simulator.ts +12 -13
- package/src/rules/rtdb/simulation/handler.ts +149 -46
- package/src/rules/simulator/document-lookups.ts +46 -3
- package/src/rules/simulator/eval-error.ts +16 -0
- package/src/rules/simulator/evaluation-builtins.ts +35 -8
- package/src/rules/simulator/evaluation-context.ts +12 -0
- package/src/rules/simulator/evaluator.ts +14 -3
- package/src/rules/simulator/handler.ts +68 -4
- package/src/rules/simulator/lookup-budget.ts +101 -0
- package/src/rules/stdlib-modules.ts +19 -11
- package/src/sandbox/admin-firestore/get-firestore.ts +19 -3
- package/src/sandbox/index.ts +5 -1
- package/src/sandbox/persistence/types.ts +1 -1
- package/src/sandbox/remote.ts +2 -2
- package/src/sandbox/sandbox-context.ts +69 -9
- package/src/sandbox/types/auth-state.ts +1 -1
- package/src/sandbox/types/events.ts +2 -1
- package/src/sandbox/types/operation.ts +1 -1
- package/src/storage/enforce.ts +53 -14
- package/src/storage/index.ts +1 -1
- package/src/storage/list.ts +1 -1
- package/src/storage/sandbox/rules-evaluation-error.ts +32 -0
- package/src/storage/sandbox/rules-evaluator.ts +109 -32
- package/src/storage/sandbox/rules-methods.ts +21 -7
- package/src/storage/service.ts +92 -27
package/src/storage/service.ts
CHANGED
|
@@ -92,6 +92,20 @@ export interface FirebaseStorage {
|
|
|
92
92
|
/** Storage handle returned by Firebase-shaped app overloads. */
|
|
93
93
|
export type AppFirebaseStorage = FirebaseStorage & { readonly app: FirebaseApp };
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Cross-service IAM posture for `firestore.get()/exists()` in Storage rules.
|
|
97
|
+
*
|
|
98
|
+
* Production Storage rules can read Firestore ONLY when the project's
|
|
99
|
+
* Storage service agent holds `roles/firebaserules.firestoreServiceAgent`.
|
|
100
|
+
* `'granted'` (the default, the common configured-project state) serves
|
|
101
|
+
* lookups from the same-sandbox Firestore store; `'denied'` makes every
|
|
102
|
+
* EXECUTED lookup fail exactly like production without the role (error →
|
|
103
|
+
* rule denies), while short-circuited lookups are never executed and stay
|
|
104
|
+
* unaffected. Captured boundary: conformance observation
|
|
105
|
+
* `stdlib-realstorage-p3-lookup-budget` (registry row storage-rules#134).
|
|
106
|
+
*/
|
|
107
|
+
export type CrossServiceIam = 'granted' | 'denied';
|
|
108
|
+
|
|
95
109
|
/**
|
|
96
110
|
* Internal sandbox service — owns the IDB connection + parsed rules.
|
|
97
111
|
* Only constructed inside the sandbox `getStorageSandbox` path.
|
|
@@ -100,6 +114,7 @@ export class StorageService {
|
|
|
100
114
|
constructor(
|
|
101
115
|
readonly backend: StorageBackend,
|
|
102
116
|
readonly rules: StorageRules | null = null,
|
|
117
|
+
readonly crossServiceIam: CrossServiceIam = 'granted',
|
|
103
118
|
) {}
|
|
104
119
|
}
|
|
105
120
|
|
|
@@ -124,7 +139,7 @@ export interface StorageOptions {
|
|
|
124
139
|
* origin-scoped, so without this every project served on the same
|
|
125
140
|
* localhost port shared one storage database (issue #359). Ignored when
|
|
126
141
|
* an explicit `dbName` is given; only honored on the FIRST call per
|
|
127
|
-
* `Sandbox`. Hosts pass their project identity here (`pyric
|
|
142
|
+
* `Sandbox`. Hosts pass their project identity here (`pyric sandbox` passes
|
|
128
143
|
* the served project's key; app handles pass `options.projectId`).
|
|
129
144
|
*/
|
|
130
145
|
projectId?: string;
|
|
@@ -134,12 +149,36 @@ export interface StorageOptions {
|
|
|
134
149
|
* `Sandbox`.
|
|
135
150
|
*/
|
|
136
151
|
rules?: string;
|
|
152
|
+
/**
|
|
153
|
+
* Model the production Storage→Firestore IAM dependency (see
|
|
154
|
+
* {@link CrossServiceIam}). Defaults to `'granted'`. Like `rules`,
|
|
155
|
+
* only honored on the FIRST storage call per `Sandbox`; a LATER,
|
|
156
|
+
* DIFFERING value throws instead of silently flipping the mode.
|
|
157
|
+
*/
|
|
158
|
+
crossServiceIam?: CrossServiceIam;
|
|
137
159
|
}
|
|
138
160
|
|
|
139
161
|
// ─── Caches ─────────────────────────────────────────────────────────
|
|
140
162
|
|
|
141
|
-
/**
|
|
142
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Everything one `Sandbox` opened its storage service WITH, in one record.
|
|
165
|
+
* These four facts are written together on the first storage call and read
|
|
166
|
+
* together afterwards, so they live in one map rather than four parallel
|
|
167
|
+
* ones that can drift out of step.
|
|
168
|
+
*/
|
|
169
|
+
interface OpenStorageService {
|
|
170
|
+
/** The service itself, resolving once its IndexedDB backend is open. */
|
|
171
|
+
readonly service: Promise<StorageService>;
|
|
172
|
+
/** The rules source it was opened with, `null` when opened without rules. */
|
|
173
|
+
readonly rulesSource: string | null;
|
|
174
|
+
/** The module-resolution record for that source, `null` without rules. */
|
|
175
|
+
readonly rulesResolution: StorageRulesResolution | null;
|
|
176
|
+
/** The cross-service IAM mode it was opened with. */
|
|
177
|
+
readonly crossServiceIam: CrossServiceIam;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** One open storage service, with its opening configuration, per `Sandbox`. */
|
|
181
|
+
const OPEN_SERVICES = new WeakMap<Sandbox, OpenStorageService>();
|
|
143
182
|
|
|
144
183
|
/** One sandbox `FirebaseStorage` handle per `SandboxContext`. */
|
|
145
184
|
const SANDBOX_HANDLES = new WeakMap<SandboxContext, FirebaseStorage>();
|
|
@@ -155,15 +194,32 @@ const SANDBOX_HANDLES = new WeakMap<SandboxContext, FirebaseStorage>();
|
|
|
155
194
|
const BARE_SANDBOX_HANDLES = new WeakMap<Sandbox, FirebaseStorage>();
|
|
156
195
|
|
|
157
196
|
/**
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
197
|
+
* Reject a late option that differs from the one the service is already
|
|
198
|
+
* open with. Both `rules` and `crossServiceIam` are honored only on the
|
|
199
|
+
* FIRST storage call per `Sandbox`. Silently discarding a later, differing
|
|
200
|
+
* value would wipe the rules, or reopen the false-ALLOW surface the IAM
|
|
201
|
+
* mode models, without a word. Re-supplying the IDENTICAL value stays fine
|
|
202
|
+
* (idempotent multi-handle construction, for example per-user contexts),
|
|
203
|
+
* and so does omitting it.
|
|
164
204
|
*/
|
|
165
|
-
|
|
166
|
-
|
|
205
|
+
function rejectDifferingLateConfig(
|
|
206
|
+
option: string,
|
|
207
|
+
descriptor: string,
|
|
208
|
+
supplied: string | undefined,
|
|
209
|
+
openedWith: string | null,
|
|
210
|
+
caller: string,
|
|
211
|
+
): void {
|
|
212
|
+
if (supplied === undefined || supplied === openedWith) return;
|
|
213
|
+
const openedDescription = openedWith === null
|
|
214
|
+
? `without ${option}`
|
|
215
|
+
: `with a different ${descriptor}`;
|
|
216
|
+
throw new Error(
|
|
217
|
+
`pyric/storage: ${caller} received a ${descriptor}, but this sandbox's storage service ` +
|
|
218
|
+
`is already open ${openedDescription}. ${option} is honored only on the FIRST storage ` +
|
|
219
|
+
'call per Sandbox, so this value would be silently discarded. Configure it on the first ' +
|
|
220
|
+
'storage call for this sandbox.',
|
|
221
|
+
);
|
|
222
|
+
}
|
|
167
223
|
|
|
168
224
|
/**
|
|
169
225
|
* Get (or open) the ONE per-sandbox `StorageService`. Loud on the
|
|
@@ -177,18 +233,23 @@ function ensureService(
|
|
|
177
233
|
options: StorageOptions,
|
|
178
234
|
caller: string,
|
|
179
235
|
): Promise<StorageService> {
|
|
180
|
-
const existing =
|
|
236
|
+
const existing = OPEN_SERVICES.get(sandbox);
|
|
181
237
|
if (existing) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
238
|
+
rejectDifferingLateConfig(
|
|
239
|
+
'rules',
|
|
240
|
+
'rules source',
|
|
241
|
+
options.rules,
|
|
242
|
+
existing.rulesSource,
|
|
243
|
+
caller,
|
|
244
|
+
);
|
|
245
|
+
rejectDifferingLateConfig(
|
|
246
|
+
'crossServiceIam',
|
|
247
|
+
'crossServiceIam mode',
|
|
248
|
+
options.crossServiceIam,
|
|
249
|
+
existing.crossServiceIam,
|
|
250
|
+
caller,
|
|
251
|
+
);
|
|
252
|
+
return existing.service;
|
|
192
253
|
}
|
|
193
254
|
let rules: StorageRules | null = null;
|
|
194
255
|
let resolution: StorageRulesResolution | null = null;
|
|
@@ -221,14 +282,18 @@ function ensureService(
|
|
|
221
282
|
}
|
|
222
283
|
// Explicit dbName wins; otherwise scope the default by project identity so
|
|
223
284
|
// two projects on one origin never share a storage database (issue #359).
|
|
285
|
+
const crossServiceIam = options.crossServiceIam ?? 'granted';
|
|
224
286
|
const servicePromise = openStorageBackend(
|
|
225
287
|
options.dbName ?? storageDbName(options.projectId),
|
|
226
288
|
).then(
|
|
227
|
-
(backend) => new StorageService(backend, rules),
|
|
289
|
+
(backend) => new StorageService(backend, rules, crossServiceIam),
|
|
228
290
|
);
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
291
|
+
OPEN_SERVICES.set(sandbox, {
|
|
292
|
+
service: servicePromise,
|
|
293
|
+
rulesSource: options.rules ?? null,
|
|
294
|
+
rulesResolution: resolution,
|
|
295
|
+
crossServiceIam,
|
|
296
|
+
});
|
|
232
297
|
// Join the sandbox's persistable-service REGISTRY so `sandbox.resetAll()`
|
|
233
298
|
// reaches storage (issue #359: Studio's reset cleared Firestore + auth but
|
|
234
299
|
// never storage — storage was invisible to the sandbox). Storage does NOT
|
|
@@ -428,5 +493,5 @@ export function getStorageService(storage: FirebaseStorage): Promise<StorageServ
|
|
|
428
493
|
export function getStorageRulesResolution(
|
|
429
494
|
storage: FirebaseStorage,
|
|
430
495
|
): StorageRulesResolution | null {
|
|
431
|
-
return
|
|
496
|
+
return OPEN_SERVICES.get(targetOf(storage).sandbox)?.rulesResolution ?? null;
|
|
432
497
|
}
|