@feltdb/core 0.4.14 → 0.4.16

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.
Files changed (44) hide show
  1. package/dist/cli/index.js +1 -1
  2. package/dist/collection.d.ts.map +1 -1
  3. package/dist/collection.js +11 -5
  4. package/dist/create/package-versions.js +1 -1
  5. package/dist/create/server-source/crates/feltdb/Cargo.toml +1 -1
  6. package/dist/create/server-source/crates/feltdb/src/application.rs +93 -0
  7. package/dist/create/server-source/crates/feltdb/src/authorization_security_tests.rs +787 -0
  8. package/dist/create/server-source/crates/feltdb/src/lib.rs +139 -0
  9. package/dist/create/server-source/crates/feltdb/src/policy_evaluation.rs +1669 -0
  10. package/dist/create/server-source/crates/feltdb/src/state_contract.rs +1269 -15
  11. package/dist/create/server-source/crates/feltdb/tests/pr7_self_authorization_proof.rs +406 -0
  12. package/dist/create/server-source/crates/feltdb/tests/pr8_vocabulary_assessment.rs +908 -0
  13. package/dist/create/server-source/crates/feltdb/tests/pr9_phase2_boundary_tests.rs +1028 -0
  14. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3a_path_a_tests.rs +332 -0
  15. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_authorized_mutations.rs +342 -0
  16. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_role_based_authorization.rs +313 -0
  17. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_simple_auth_delete.rs +90 -0
  18. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_team_delete_role_authorization.rs +571 -0
  19. package/dist/create/server-source/crates/feltdb/tests/pr9_teams_role_based_access.rs +506 -0
  20. package/dist/create/server-source/crates/feltdb/tests/saas_authorization_integration.rs +81 -0
  21. package/dist/create/server-source/crates/feltdb/tests/saas_invitation_lifecycle.rs +434 -0
  22. package/dist/create/server-source/crates/feltdb-server/src/main.rs +130 -23
  23. package/dist/create/server-source/crates/feltdb-wasm/src/lib.rs +2 -2
  24. package/dist/db.d.ts +10 -0
  25. package/dist/db.d.ts.map +1 -1
  26. package/dist/db.js +3 -1
  27. package/dist/feltdb.d.ts +1 -1
  28. package/dist/feltdb.d.ts.map +1 -1
  29. package/dist/file-db.d.ts +69 -0
  30. package/dist/file-db.d.ts.map +1 -0
  31. package/dist/file-db.js +355 -0
  32. package/dist/index.d.ts +1 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +1 -0
  35. package/dist/indexeddb-db.d.ts +20 -1
  36. package/dist/indexeddb-db.d.ts.map +1 -1
  37. package/dist/indexeddb-db.js +167 -26
  38. package/dist/studio-app/assets/{feltdb_wasm-Bb1Pg6qz.js → feltdb_wasm-CBGD0zRu.js} +1 -1
  39. package/dist/studio-app/assets/feltdb_wasm_bg-C6ATF9mJ.wasm +0 -0
  40. package/dist/studio-app/assets/{index-DVdvmf69.js → index-D74dfBgZ.js} +9 -9
  41. package/dist/studio-app/index.html +1 -1
  42. package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
  43. package/package.json +7 -2
  44. package/dist/studio-app/assets/feltdb_wasm_bg-2_wVudcZ.wasm +0 -0
package/dist/cli/index.js CHANGED
@@ -23,7 +23,7 @@ import * as path from 'path';
23
23
  import * as readline from 'readline';
24
24
  import { getClient } from './api-client.js';
25
25
  import { loadFeltDBConfig, createDefaultConfig, validateModel, } from './config.js';
26
- const VERSION = '0.4.14';
26
+ const VERSION = '0.4.16';
27
27
  function prompt(question) {
28
28
  const rl = readline.createInterface({
29
29
  input: process.stdin,
@@ -1 +1 @@
1
- {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"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"}
@@ -258,10 +258,16 @@ export class Collection {
258
258
  }
259
259
  // Subscribe to changes via reactive dependency graph
260
260
  if (!this.graphUnsubscribe) {
261
- const notify = async () => {
262
- await this.refresh();
263
- for (const sub of this.subscribers)
264
- sub([...this.cache]);
261
+ let refreshInFlight = null;
262
+ const notify = () => {
263
+ if (refreshInFlight)
264
+ return refreshInFlight;
265
+ refreshInFlight = (async () => {
266
+ await this.refresh();
267
+ for (const sub of this.subscribers)
268
+ sub([...this.cache]);
269
+ })().finally(() => { refreshInFlight = null; });
270
+ return refreshInFlight;
265
271
  };
266
272
  const graph = getReactiveDependencyGraph();
267
273
  this.graphUnsubscribe = graph.subscribe(this.name, notify);
@@ -269,7 +275,7 @@ export class Collection {
269
275
  this.runtimeUnsubscribe = this.db.subscribe_changes(collection => {
270
276
  if (collection === this.name)
271
277
  void notify();
272
- });
278
+ }, this.name);
273
279
  }
274
280
  }
275
281
  // Return unsubscribe function
@@ -1,4 +1,4 @@
1
1
  // One release train keeps generated applications installable. The repository
2
2
  // validation script checks these values against every workspace manifest.
3
- export const FELTDB_PACKAGE_VERSION = '0.4.14';
3
+ export const FELTDB_PACKAGE_VERSION = '0.4.16';
4
4
  export const feltdbPackageRange = `^${FELTDB_PACKAGE_VERSION}`;
@@ -15,7 +15,7 @@ rand = "0.8"
15
15
  bincode = "1"
16
16
 
17
17
  [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
18
- tokio = { version = "1", features = ["net", "io-util"] }
18
+ tokio = { version = "1", features = ["net", "io-util", "rt-multi-thread"] }
19
19
 
20
20
  [dev-dependencies]
21
21
  criterion = { version = "0.5", features = ["html_reports"] }
@@ -152,6 +152,10 @@ pub struct PolicyDefinition {
152
152
  pub name: String,
153
153
  pub resource: String,
154
154
  #[serde(default)]
155
+ pub read: Option<String>,
156
+ #[serde(default)]
157
+ pub write: Option<String>,
158
+ #[serde(default)]
155
159
  pub capabilities: Vec<String>,
156
160
  }
157
161
  #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
@@ -363,6 +367,10 @@ pub struct ValidationReport {
363
367
  pub issues: Vec<ValidationIssue>,
364
368
  }
365
369
 
370
+ fn is_valid_policy_subject(subject: &str) -> bool {
371
+ matches!(subject, "authenticated" | "owner" | "member")
372
+ }
373
+
366
374
  fn unique(
367
375
  issues: &mut Vec<ValidationIssue>,
368
376
  category: &str,
@@ -734,6 +742,24 @@ pub fn validate_manifest(
734
742
  ));
735
743
  }
736
744
  }
745
+ if let Some(ref read_subject) = policy.read {
746
+ if !is_valid_policy_subject(read_subject) {
747
+ issues.push(issue(
748
+ "semantic",
749
+ format!("policies.{}.read", policy.name),
750
+ &format!("invalid policy subject '{}'", read_subject),
751
+ ));
752
+ }
753
+ }
754
+ if let Some(ref write_subject) = policy.write {
755
+ if !is_valid_policy_subject(write_subject) {
756
+ issues.push(issue(
757
+ "semantic",
758
+ format!("policies.{}.write", policy.name),
759
+ &format!("invalid policy subject '{}'", write_subject),
760
+ ));
761
+ }
762
+ }
737
763
  }
738
764
  let state_schema = crate::state_contract::schema_from_manifest(manifest, "validation");
739
765
  let schema_validation = crate::state_contract::validate_schema(&state_schema);
@@ -2241,4 +2267,71 @@ mod tests {
2241
2267
  Some(promotion.diff_hash.as_str())
2242
2268
  );
2243
2269
  }
2270
+
2271
+ #[test]
2272
+ fn policy_with_valid_authenticated_subject() {
2273
+ let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
2274
+ manifest.policies.push(PolicyDefinition {
2275
+ name: "TodoPolicy".into(),
2276
+ resource: "Todo".into(),
2277
+ read: Some("authenticated".into()),
2278
+ write: Some("authenticated".into()),
2279
+ capabilities: vec![],
2280
+ });
2281
+
2282
+ let report = validate_manifest(&manifest, "tenant", "app", None);
2283
+ assert!(report.valid, "Policy with authenticated subject should be valid: {:?}", report.issues);
2284
+ }
2285
+
2286
+ #[test]
2287
+ fn policy_with_valid_owner_subject() {
2288
+ let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
2289
+ manifest.policies.push(PolicyDefinition {
2290
+ name: "ProjectPolicy".into(),
2291
+ resource: "Project".into(),
2292
+ read: Some("authenticated".into()),
2293
+ write: Some("owner".into()),
2294
+ capabilities: vec![],
2295
+ });
2296
+
2297
+ let report = validate_manifest(&manifest, "tenant", "app", None);
2298
+ assert!(report.valid, "Policy with owner subject should be valid: {:?}", report.issues);
2299
+ }
2300
+
2301
+ #[test]
2302
+ fn policy_with_invalid_subject_rejected() {
2303
+ let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
2304
+ manifest.policies.push(PolicyDefinition {
2305
+ name: "BadPolicy".into(),
2306
+ resource: "BadCollection".into(),
2307
+ read: Some("unknown_subject".into()),
2308
+ write: None,
2309
+ capabilities: vec![],
2310
+ });
2311
+
2312
+ let report = validate_manifest(&manifest, "tenant", "app", None);
2313
+ assert!(!report.valid, "Policy with unknown subject should be invalid");
2314
+ assert!(
2315
+ report.issues.iter().any(|i|
2316
+ i.path.contains("BadPolicy") && i.path.contains("read") &&
2317
+ i.message.contains("invalid policy subject")
2318
+ ),
2319
+ "Should have error about invalid policy subject"
2320
+ );
2321
+ }
2322
+
2323
+ #[test]
2324
+ fn policy_without_subjects_is_valid() {
2325
+ let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
2326
+ manifest.policies.push(PolicyDefinition {
2327
+ name: "LegacyPolicy".into(),
2328
+ resource: "SomeCollection".into(),
2329
+ read: None,
2330
+ write: None,
2331
+ capabilities: vec!["some:capability".into()],
2332
+ });
2333
+
2334
+ let report = validate_manifest(&manifest, "tenant", "app", None);
2335
+ assert!(report.valid, "Policy without subjects should be valid (backward compatible)");
2336
+ }
2244
2337
  }