@feltdb/core 0.7.4 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +25 -0
  2. package/dist/application-development.d.ts +3 -1
  3. package/dist/application-development.d.ts.map +1 -1
  4. package/dist/application-development.js +16 -0
  5. package/dist/application-manifest.d.ts +1 -0
  6. package/dist/application-manifest.d.ts.map +1 -1
  7. package/dist/canonical-application.d.ts +1 -0
  8. package/dist/canonical-application.d.ts.map +1 -1
  9. package/dist/canonical-application.js +3 -2
  10. package/dist/cli/cli.js +1 -1
  11. package/dist/cli/commands.js +225 -42
  12. package/dist/cli/index.js +1 -1
  13. package/dist/cli/managed-environment.js +6 -0
  14. package/dist/cli/managed-project.js +6 -0
  15. package/dist/cli/proposal-client.js +12 -3
  16. package/dist/cli/publish-engine.js +7 -4
  17. package/dist/cli/source-sync.js +47 -3
  18. package/dist/create/cli.js +10 -1
  19. package/dist/create/create.js +10 -12
  20. package/dist/create/managed-account.js +71 -7
  21. package/dist/create/package-versions.js +1 -1
  22. package/dist/create/server-source/crates/feltdb/src/application.rs +10 -0
  23. package/dist/create/server-source/crates/feltdb/src/lib.rs +20 -2
  24. package/dist/create/server-source/crates/feltdb-server/src/app_state.rs +12 -24
  25. package/dist/create/server-source/crates/feltdb-server/src/application_contract.rs +11 -3
  26. package/dist/create/server-source/crates/feltdb-server/src/authenticated_principal.rs +0 -1
  27. package/dist/create/server-source/crates/feltdb-server/src/certification_harness.rs +23 -22
  28. package/dist/create/server-source/crates/feltdb-server/src/delegation_token.rs +5 -15
  29. package/dist/create/server-source/crates/feltdb-server/src/durable_operations.rs +13 -28
  30. package/dist/create/server-source/crates/feltdb-server/src/identity.rs +79 -14
  31. package/dist/create/server-source/crates/feltdb-server/src/key_management.rs +28 -7
  32. package/dist/create/server-source/crates/feltdb-server/src/lib.rs +5 -5
  33. package/dist/create/server-source/crates/feltdb-server/src/main.rs +1777 -259
  34. package/dist/create/server-source/crates/feltdb-server/src/managed_diagnostics.rs +10 -30
  35. package/dist/create/server-source/crates/feltdb-server/src/membership_policy.rs +12 -4
  36. package/dist/create/server-source/crates/feltdb-server/src/request_telemetry.rs +8 -6
  37. package/dist/create/server-source/crates/feltdb-server/src/snapshot_cursor.rs +10 -14
  38. package/dist/create/server-source/crates/feltdb-server/src/tenancy.rs +183 -21
  39. package/dist/create/server-source/crates/feltdb-server/src/tenant_policies.rs +9 -21
  40. package/dist/create/server-source/crates/feltdb-server/src/transaction_idempotency.rs +5 -3
  41. package/dist/create/server-source/crates/feltdb-server/src/transaction_recovery.rs +9 -8
  42. package/dist/create/server-source/crates/feltdb-server/tests/revision_recovery_integration_test.rs +1 -4
  43. package/dist/create/template/default-project/feltdb.flow +5 -0
  44. package/dist/flowspec.d.ts +1 -0
  45. package/dist/flowspec.d.ts.map +1 -1
  46. package/dist/flowspec.js +46 -12
  47. package/dist/http-client.d.ts +135 -14
  48. package/dist/http-client.d.ts.map +1 -1
  49. package/dist/http-client.js +79 -31
  50. package/dist/index-core.d.ts +2 -0
  51. package/dist/index-core.d.ts.map +1 -1
  52. package/dist/index-core.js +2 -0
  53. package/dist/module-intent.d.ts +37 -0
  54. package/dist/module-intent.d.ts.map +1 -0
  55. package/dist/module-intent.js +81 -0
  56. package/dist/module.d.ts +76 -0
  57. package/dist/module.d.ts.map +1 -0
  58. package/dist/module.js +61 -0
  59. package/dist/proposal.d.ts +80 -4
  60. package/dist/proposal.d.ts.map +1 -1
  61. package/dist/proposal.js +132 -5
  62. package/dist/studio/app.d.ts +3 -1
  63. package/dist/studio/app.d.ts.map +1 -1
  64. package/dist/studio/components/AskFeltDB.d.ts +2 -1
  65. package/dist/studio/components/AskFeltDB.d.ts.map +1 -1
  66. package/dist/studio/components/ContractInspector.d.ts +7 -0
  67. package/dist/studio/components/ContractInspector.d.ts.map +1 -0
  68. package/dist/studio/components/ManagedInstancePanel.d.ts.map +1 -1
  69. package/dist/studio/components/ManagedInstancePanel.js +1 -5
  70. package/dist/studio/components/ModuleExplorer.d.ts +6 -0
  71. package/dist/studio/components/ModuleExplorer.d.ts.map +1 -0
  72. package/dist/studio/components/ProposalBrowser.d.ts +10 -1
  73. package/dist/studio/components/ProposalBrowser.d.ts.map +1 -1
  74. package/dist/studio/components/StateExplorer.d.ts +6 -7
  75. package/dist/studio/components/StateExplorer.d.ts.map +1 -1
  76. package/dist/studio/components/index.d.ts +2 -0
  77. package/dist/studio/components/index.d.ts.map +1 -1
  78. package/dist/studio/components/index.js +4 -4
  79. package/dist/studio/components-CNSNrmA9.js +2787 -0
  80. package/dist/studio/index.js +193 -147
  81. package/dist/studio/studio.css +1 -1
  82. package/dist/studio/utils/index.d.ts +2 -0
  83. package/dist/studio/utils/index.d.ts.map +1 -1
  84. package/dist/studio/utils/index.js +14 -12
  85. package/dist/studio/utils/managed-instance.d.ts +0 -4
  86. package/dist/studio/utils/managed-instance.d.ts.map +1 -1
  87. package/dist/studio/utils/managed-instance.js +0 -4
  88. package/dist/studio/utils/proposal-api.d.ts +53 -0
  89. package/dist/studio/utils/proposal-api.d.ts.map +1 -0
  90. package/dist/studio/utils/proposal-api.js +91 -0
  91. package/dist/studio/utils/service-api.d.ts +81 -0
  92. package/dist/studio/utils/service-api.d.ts.map +1 -0
  93. package/dist/studio/utils/service-api.js +51 -0
  94. package/dist/studio-app/assets/{dist-DA1MYSzp.js → dist-CCOk39Uc.js} +1 -1
  95. package/dist/studio-app/assets/{feltdb_wasm-B-Ccgccb.js → feltdb_wasm-CSB6KVgw.js} +1 -1
  96. package/dist/studio-app/assets/feltdb_wasm_bg-Dd1fnO9U.wasm +0 -0
  97. package/dist/studio-app/assets/index-Bncji3aN.js +43 -0
  98. package/dist/studio-app/assets/{index-BRrmvaKw.css → index-yazaWMUN.css} +1 -1
  99. package/dist/studio-app/index.html +2 -2
  100. package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
  101. package/dist/workspace/local-development-authority.d.ts.map +1 -1
  102. package/dist/workspace/local-development-authority.js +64 -3
  103. package/package.json +1 -1
  104. package/dist/studio/components-Bm4sjhcX.js +0 -2162
  105. package/dist/studio-app/assets/feltdb_wasm_bg-wH3enJIA.wasm +0 -0
  106. package/dist/studio-app/assets/index-CEIqowCh.js +0 -42
@@ -0,0 +1,81 @@
1
+ import { formatFlowSpec, parseFlowSpec } from './flowspec.js';
2
+ import { findFeltDBModules, listFeltDBModules, resolveFeltDBModule } from './module.js';
3
+ async function sourceHash(source) {
4
+ const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(source.replace(/\r\n/g, '\n')));
5
+ return `sha256:${Array.from(new Uint8Array(digest), byte => byte.toString(16).padStart(2, '0')).join('')}`;
6
+ }
7
+ export function resolveModuleIntent(value) {
8
+ const match = /^\s*implement\s+([a-z0-9][a-z0-9-]*)\s*[.!]?\s*$/i.exec(value);
9
+ const incrementalBilling = /^\s*(?:add|support|enable)\b.+\b(?:billing|plan|subscription)\b.*$/i.test(value);
10
+ if (!match && !incrementalBilling)
11
+ return undefined;
12
+ const requested = match ? match[1].toLowerCase() : 'billing';
13
+ const matches = findFeltDBModules(requested);
14
+ if (!matches.length)
15
+ throw new Error(`MODULE_NOT_AVAILABLE: ${requested}. No proposal created. Available modules: ${listFeltDBModules().map(module => module.id).join(', ')}`);
16
+ if (matches.length > 1)
17
+ throw new Error(`AMBIGUOUS_MODULE_INTENT: ${requested}. Available providers: ${matches.map(module => module.provider).join(', ')}`);
18
+ const module = matches[0];
19
+ return { action: match ? 'implement' : 'extend', module: module.id, provider: module.provider, version: module.version, original: value };
20
+ }
21
+ function billingOwner(spec, module) {
22
+ const names = new Set(spec.collections.map(collection => collection.name));
23
+ for (const pattern of module.patterns)
24
+ for (const candidate of pattern.owner_candidates)
25
+ if (names.has(candidate))
26
+ return candidate;
27
+ return spec.collections.find(collection => /user|account|member/i.test(collection.name))?.name ?? spec.collections[0]?.name ?? 'User';
28
+ }
29
+ export function planModuleImplementation(intent, snapshot, currentFlow) {
30
+ const module = resolveFeltDBModule({ name: intent.module, provider: intent.provider, version: intent.version });
31
+ const spec = parseFlowSpec(currentFlow);
32
+ const owner = billingOwner(spec, module);
33
+ const alreadyInstalled = Boolean(spec.modules?.some(value => value.name === module.id));
34
+ const pattern = module.patterns.find(value => value.owner_candidates.includes(owner)) ?? module.patterns[0];
35
+ const implementedEvents = new Set(spec.triggers.map(value => value.event));
36
+ const implementedWorkflows = new Set(spec.workflows.map(value => value.name));
37
+ return { intent, module, alreadyInstalled, owner, applicationModels: pattern.application_models,
38
+ relationships: [`BillingAccount.owner -> ${owner}`, `BillingAccount.customer -> ${module.id}.Customer`, `BillingAccount.subscription -> ${module.id}.Subscription`, `Entitlement.billing_account -> BillingAccount`],
39
+ events: module.reconciliation.map(value => value.event).filter(value => !implementedEvents.has(value)),
40
+ workflows: module.reconciliation.map(value => value.workflow).filter(value => !implementedWorkflows.has(value)),
41
+ capabilities: ['stripe.checkout.create', 'stripe.subscription.read', 'stripe.subscription.cancel'].filter(value => module.capabilities.includes(value)),
42
+ authorization: module.authorization, configuration: module.configuration.map(value => value.name), secrets: module.secrets.map(value => value.name),
43
+ stateFlow: [`${module.id}.subscription.updated`, `ReconcileSubscription`, `BillingAccount`, `Entitlement`],
44
+ warnings: ['Production webhook configuration and signature verification required'],
45
+ };
46
+ }
47
+ function addCollection(spec, collection) { if (!spec.collections.some(value => value.name === collection.name))
48
+ spec.collections.push(collection); }
49
+ export async function createModuleImplementationProposal(input) {
50
+ const resolved = resolveModuleIntent(input.intent);
51
+ if (!resolved)
52
+ throw new Error('NOT_A_MODULE_INTENT');
53
+ const plan = planModuleImplementation(resolved, input.snapshot, input.currentFlow);
54
+ const spec = parseFlowSpec(input.currentFlow);
55
+ if (resolved.action === 'extend' && !plan.alreadyInstalled)
56
+ throw new Error(`MODULE_NOT_INSTALLED: ${plan.module.id}. Run implement ${plan.module.id} first.`);
57
+ if (!spec.modules?.some(value => value.name === plan.module.id))
58
+ spec.modules.push({ name: plan.module.id, provider: plan.module.provider, version: plan.module.version });
59
+ addCollection(spec, { name: 'BillingAccount', fields: [
60
+ { name: 'owner', type: `ref ${plan.owner}`, optional: false }, { name: 'customer', type: `ref ${plan.module.id}.Customer`, optional: false },
61
+ { name: 'subscription', type: `ref ${plan.module.id}.Subscription`, optional: true }, { name: 'status', type: 'text', optional: false },
62
+ ], indexes: [] });
63
+ addCollection(spec, { name: 'Entitlement', fields: [{ name: 'billing_account', type: 'ref BillingAccount', optional: false }, { name: 'key', type: 'text', optional: false }, { name: 'active', type: 'boolean', optional: false }], indexes: [] });
64
+ if (resolved.action === 'extend')
65
+ addCollection(spec, { name: 'BillingPlan', fields: [
66
+ { name: 'code', type: 'text', optional: false }, { name: 'interval', type: 'enum(monthly,annual)', optional: false },
67
+ { name: 'price', type: `ref ${plan.module.id}.Price`, optional: false }, { name: 'active', type: 'boolean', optional: false },
68
+ ], indexes: [] });
69
+ for (const reconciliation of plan.module.reconciliation) {
70
+ if (!spec.workflows.some(value => value.name === reconciliation.workflow))
71
+ spec.workflows.push({ name: reconciliation.workflow, parameters: '', steps: [{ name: 'reconcile', statements: ['read BillingAccount', 'write BillingAccount', 'write Entitlement', `capability ${plan.module.id}.subscription.read`] }] });
72
+ if (!spec.triggers.some(value => value.event === reconciliation.event))
73
+ spec.triggers.push({ event: reconciliation.event, statements: [`run ${reconciliation.workflow}`] });
74
+ }
75
+ if (!spec.policies.some(value => value.name === 'BillingAccount'))
76
+ spec.policies.push({ name: 'BillingAccount', statements: ['read: owner', 'write: owner'] });
77
+ const prefix = resolved.action === 'extend' ? 'Extend' : plan.alreadyInstalled ? 'Complete' : 'Implement';
78
+ return { baseContractHash: input.snapshot.contract_hash, baseFlowHash: await sourceHash(input.currentFlow), proposedFlow: formatFlowSpec(spec),
79
+ summary: `${prefix} ${plan.module.name}`, changes: [...(resolved.action === 'extend' ? ['BillingPlan (application-authoritative)', 'BillingPlan.price -> stripe.Price'] : plan.applicationModels.map(value => `${value.name} (${value.ownership})`)), ...plan.relationships, ...plan.workflows, ...plan.capabilities],
80
+ warnings: [...plan.warnings, ...(resolved.action === 'extend' ? ['Plan and price records must be configured through application data; no provider values were invented'] : [])], implementation: plan };
81
+ }
@@ -0,0 +1,76 @@
1
+ export type FeltDBModuleOwnership = 'external-authoritative' | 'application-authoritative' | 'derived' | 'synchronized';
2
+ export interface FeltDBModuleModel {
3
+ name: string;
4
+ authority: 'external';
5
+ ownership: FeltDBModuleOwnership;
6
+ fields: {
7
+ name: string;
8
+ type: string;
9
+ optional?: boolean;
10
+ immutable?: boolean;
11
+ externally_owned?: boolean;
12
+ application_readable?: boolean;
13
+ }[];
14
+ }
15
+ export interface FeltDBModuleRelationship {
16
+ from: string;
17
+ to: string;
18
+ kind: 'one' | 'many';
19
+ }
20
+ export interface FeltDBModuleRequirement {
21
+ name: string;
22
+ required: boolean;
23
+ environments?: string[];
24
+ description: string;
25
+ }
26
+ export interface FeltDBModulePattern {
27
+ name: string;
28
+ when: string;
29
+ owner_candidates: string[];
30
+ application_models: Array<{
31
+ name: string;
32
+ ownership: FeltDBModuleOwnership;
33
+ purpose: string;
34
+ }>;
35
+ }
36
+ export interface FeltDBModuleReconciliation {
37
+ event: string;
38
+ workflow: string;
39
+ reads: string[];
40
+ writes: string[];
41
+ outcome: string;
42
+ }
43
+ export interface FeltDBModuleDefinition {
44
+ id: string;
45
+ name: string;
46
+ version: string;
47
+ provider: string;
48
+ compatibility: string[];
49
+ models: FeltDBModuleModel[];
50
+ relationships: FeltDBModuleRelationship[];
51
+ events: string[];
52
+ capabilities: string[];
53
+ workflows: string[];
54
+ configuration: FeltDBModuleRequirement[];
55
+ secrets: FeltDBModuleRequirement[];
56
+ validation: string[];
57
+ dependencies: string[];
58
+ authorization: Array<{
59
+ capability: string;
60
+ subject: string;
61
+ implication: string;
62
+ }>;
63
+ patterns: FeltDBModulePattern[];
64
+ reconciliation: FeltDBModuleReconciliation[];
65
+ }
66
+ export interface FlowModuleDeclaration {
67
+ name: string;
68
+ provider: string;
69
+ version?: string;
70
+ }
71
+ export declare function listFeltDBModules(): FeltDBModuleDefinition[];
72
+ export declare function resolveFeltDBModule(declaration: FlowModuleDeclaration): FeltDBModuleDefinition;
73
+ export declare function findFeltDBModules(query: string): FeltDBModuleDefinition[];
74
+ export declare function resolveFeltDBModules(declarations?: FlowModuleDeclaration[]): FeltDBModuleDefinition[];
75
+ export declare function validateResolvedModules(modules: FeltDBModuleDefinition[], environment?: string): string[];
76
+ //# sourceMappingURL=module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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"}
package/dist/module.js ADDED
@@ -0,0 +1,61 @@
1
+ const stripe = {
2
+ id: 'stripe', name: 'Stripe-compatible billing', version: '1.0.0', provider: 'stripe-compatible',
3
+ compatibility: ['stripe', 'stripe-compatible'],
4
+ models: ['Customer', 'Product', 'Price', 'Subscription', 'SubscriptionItem', 'Invoice', 'PaymentIntent', 'CheckoutSession', 'PaymentMethod', 'Refund', 'WebhookEvent']
5
+ .map(name => ({ name, authority: 'external', ownership: 'external-authoritative', fields: [
6
+ { name: 'id', type: 'text', immutable: true, externally_owned: true, application_readable: true },
7
+ { name: 'status', type: 'text', optional: true, externally_owned: true, application_readable: true },
8
+ { name: 'created_at', type: 'datetime', externally_owned: true, application_readable: true },
9
+ { name: 'metadata', type: 'json', optional: true, externally_owned: true, application_readable: true },
10
+ ] })),
11
+ relationships: [
12
+ { from: 'Customer', to: 'Subscription', kind: 'many' }, { from: 'Subscription', to: 'SubscriptionItem', kind: 'many' },
13
+ { from: 'SubscriptionItem', to: 'Price', kind: 'one' }, { from: 'Price', to: 'Product', kind: 'one' },
14
+ { from: 'Customer', to: 'Invoice', kind: 'many' }, { from: 'Invoice', to: 'PaymentIntent', kind: 'one' },
15
+ ],
16
+ events: ['stripe.customer.created', 'stripe.customer.updated', 'stripe.subscription.created', 'stripe.subscription.updated', 'stripe.subscription.deleted', 'stripe.invoice.paid', 'stripe.invoice.payment_failed', 'stripe.checkout.session.completed'],
17
+ capabilities: ['stripe.customer.read', 'stripe.customer.create', 'stripe.checkout.create', 'stripe.subscription.read', 'stripe.subscription.create', 'stripe.subscription.cancel', 'stripe.invoice.read', 'stripe.webhooks.receive'],
18
+ workflows: ['ReconcileSubscription', 'ReconcileFailedPayment'],
19
+ configuration: [{ name: 'STRIPE_PUBLISHABLE_KEY', required: false, description: 'Browser-safe publishable provider key' }],
20
+ secrets: [{ name: 'STRIPE_SECRET_KEY', required: true, description: 'Server-side provider credential' }, { name: 'STRIPE_WEBHOOK_SECRET', required: true, environments: ['production'], description: 'Webhook signature verification secret' }],
21
+ validation: ['Webhook receivers must verify signatures', 'Checkout creation requires authenticated authorization'],
22
+ dependencies: [],
23
+ authorization: [
24
+ { capability: 'stripe.checkout.create', subject: 'authenticated', implication: 'A signed-in billing owner may create a hosted checkout session' },
25
+ { capability: 'stripe.subscription.cancel', subject: 'owner', implication: 'Only the billing owner may cancel a subscription' },
26
+ ],
27
+ patterns: [
28
+ { name: 'organization billing', when: 'The application contains Organization or Workspace state', owner_candidates: ['Organization', 'Workspace'], application_models: [
29
+ { name: 'BillingAccount', ownership: 'application-authoritative', purpose: 'Connect the application billing owner to provider state' },
30
+ { name: 'Entitlement', ownership: 'derived', purpose: 'Materialize product access from reconciled subscription state' },
31
+ ] },
32
+ { name: 'user billing', when: 'The application is user-centric and has no organizational owner', owner_candidates: ['User', 'Account'], application_models: [
33
+ { name: 'BillingAccount', ownership: 'application-authoritative', purpose: 'Connect the user to provider state' },
34
+ { name: 'Entitlement', ownership: 'derived', purpose: 'Materialize product access from reconciled subscription state' },
35
+ ] },
36
+ ],
37
+ reconciliation: [
38
+ { event: 'stripe.subscription.updated', workflow: 'ReconcileSubscription', reads: ['stripe.Subscription', 'BillingAccount'], writes: ['BillingAccount', 'Entitlement'], outcome: 'Subscription changes become application entitlements' },
39
+ { event: 'stripe.invoice.payment_failed', workflow: 'ReconcileFailedPayment', reads: ['stripe.Invoice', 'BillingAccount'], writes: ['BillingAccount', 'Entitlement'], outcome: 'Failed payment state restricts derived entitlements' },
40
+ ],
41
+ };
42
+ const definitions = new Map([[stripe.id, stripe]]);
43
+ export function listFeltDBModules() { return [...definitions.values()].map(value => structuredClone(value)); }
44
+ export function resolveFeltDBModule(declaration) {
45
+ const definition = definitions.get(declaration.name);
46
+ if (!definition)
47
+ throw new Error(`UNKNOWN_MODULE: ${declaration.name}`);
48
+ if (!definition.compatibility.includes(declaration.provider))
49
+ throw new Error(`INCOMPATIBLE_MODULE_PROVIDER: ${declaration.name} does not support ${declaration.provider}`);
50
+ if (declaration.version && declaration.version !== definition.version)
51
+ throw new Error(`INCOMPATIBLE_MODULE_VERSION: ${declaration.name}@${declaration.version}; available ${definition.version}`);
52
+ return { ...structuredClone(definition), provider: declaration.provider };
53
+ }
54
+ export function findFeltDBModules(query) {
55
+ const normalized = query.trim().toLowerCase();
56
+ return listFeltDBModules().filter(module => module.id === normalized || module.name.toLowerCase().includes(normalized) || module.compatibility.some(value => value.includes(normalized)));
57
+ }
58
+ export function resolveFeltDBModules(declarations = []) { return declarations.map(resolveFeltDBModule).sort((a, b) => a.id.localeCompare(b.id)); }
59
+ export function validateResolvedModules(modules, environment = 'development') {
60
+ return modules.flatMap(module => [...module.secrets.filter(value => value.required && (!value.environments || value.environments.includes(environment))).map(value => `${value.name} is required in ${environment} runtime configuration`), ...module.capabilities.filter(value => value.endsWith('.create')).map(value => `${value} requires an explicit authorization policy`)]);
61
+ }
@@ -1,6 +1,7 @@
1
1
  import { type FeltDBContractSnapshot } from './application-development.js';
2
2
  export declare const FELTDB_PROPOSAL_COLLECTION = "_feltdb.Proposal";
3
3
  export declare const FELTDB_PROPOSAL_EVENT_COLLECTION = "_feltdb.ProposalEvent";
4
+ export declare const FELTDB_PROPOSAL_PREVIEW_COLLECTION = "_feltdb.ProposalPreview";
4
5
  export declare const FELTDB_PROPOSAL_VERSION = 1;
5
6
  export type ProposalStatus = 'proposed' | 'validated' | 'previewed' | 'approved' | 'applied' | 'rejected' | 'expired';
6
7
  export interface ProposalSourceOperation {
@@ -28,9 +29,33 @@ export interface FeltDBProposalRecord {
28
29
  approved_by?: string;
29
30
  approved_at?: string | number;
30
31
  applied_at?: string | number;
32
+ preview_id?: string;
31
33
  expires_at?: string | number;
32
34
  metadata: Record<string, string>;
33
35
  parent_proposal_id?: string;
36
+ module_versions: {
37
+ id: string;
38
+ provider: string;
39
+ version: string;
40
+ }[];
41
+ base_module_versions?: {
42
+ id: string;
43
+ provider: string;
44
+ version: string;
45
+ }[];
46
+ module_impact: {
47
+ modules: string[];
48
+ models: string[];
49
+ relationships: string[];
50
+ events: string[];
51
+ workflows: string[];
52
+ capabilities: string[];
53
+ authorization: string[];
54
+ configuration: string[];
55
+ secrets: string[];
56
+ ownership: Record<string, string>;
57
+ state_flow: string[];
58
+ };
34
59
  }
35
60
  export interface FeltDBProposalEvent {
36
61
  id: string;
@@ -41,6 +66,58 @@ export interface FeltDBProposalEvent {
41
66
  created_at: string | number;
42
67
  metadata: Record<string, string>;
43
68
  }
69
+ export interface ProposalReadiness {
70
+ status: ProposalStatus;
71
+ readiness: 'ready' | 'blocked';
72
+ blockers: ('contract_changed' | 'flow_changed' | 'module_versions_changed' | 'expired')[];
73
+ notes: string[];
74
+ current_contract_hash: string;
75
+ proposal_contract_hash: string;
76
+ current_flow_hash: string;
77
+ proposal_flow_hash: string;
78
+ stale: boolean;
79
+ expires_at?: string | number;
80
+ }
81
+ export interface FeltDBProposalPreviewArtifact {
82
+ preview_id: string;
83
+ proposal_id: string;
84
+ application_id: string;
85
+ environment: string;
86
+ proposal_hash: string;
87
+ created_at: string;
88
+ expires_at: string;
89
+ status: 'ready';
90
+ current: FeltDBContractSnapshot;
91
+ proposed: FeltDBContractSnapshot;
92
+ current_contract: FeltDBContractSnapshot;
93
+ proposed_contract: FeltDBContractSnapshot;
94
+ semantic_diff: string[];
95
+ state_flow: string[];
96
+ capabilities: unknown[];
97
+ workflows: unknown[];
98
+ authorization: unknown[];
99
+ configuration: string[];
100
+ secrets: string[];
101
+ modules: string[];
102
+ ownership: Record<string, string>;
103
+ relationships: string[];
104
+ events: string[];
105
+ seeded_records: {
106
+ collection: string;
107
+ id: string;
108
+ preview_data: true;
109
+ }[];
110
+ data_classification: 'synthetic_preview';
111
+ external_side_effects: 'simulated';
112
+ readiness: ProposalReadiness;
113
+ proposal: FeltDBProposalRecord;
114
+ }
115
+ /** Canonical human diagnostic used by CLI and Studio text surfaces. */
116
+ export declare function renderProposalDiagnostic(proposal: FeltDBProposalRecord, options?: {
117
+ readiness?: ProposalReadiness;
118
+ history?: FeltDBProposalEvent[];
119
+ preview?: FeltDBProposalPreviewArtifact;
120
+ }): string[];
44
121
  export interface ProposalStore {
45
122
  get<T>(collection: string, id: string): Promise<T | undefined>;
46
123
  list<T>(collection: string): Promise<T[]>;
@@ -72,11 +149,10 @@ export declare class FeltDBProposalService {
72
149
  list(): Promise<FeltDBProposalRecord[]>;
73
150
  get(id: string): Promise<FeltDBProposalRecord>;
74
151
  history(id: string): Promise<FeltDBProposalEvent[]>;
152
+ readiness(id: string): Promise<ProposalReadiness>;
75
153
  validate(id: string, actor: string): Promise<FeltDBProposalRecord>;
76
- preview(id: string, actor: string): Promise<{
77
- proposal: FeltDBProposalRecord;
78
- contract: FeltDBContractSnapshot;
79
- }>;
154
+ preview(id: string, actor: string): Promise<FeltDBProposalPreviewArtifact>;
155
+ getPreview(id: string): Promise<FeltDBProposalPreviewArtifact>;
80
156
  transition(id: string, status: 'approved' | 'rejected' | 'expired' | 'applied', actor: string, authority?: string, approveAuthorization?: boolean): Promise<FeltDBProposalRecord>;
81
157
  private assertMutable;
82
158
  private move;
@@ -1 +1 @@
1
- {"version":3,"file":"proposal.d.ts","sourceRoot":"","sources":["../src/proposal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proposal.d.ts","sourceRoot":"","sources":["../src/proposal.ts"],"names":[],"mappings":"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"}
package/dist/proposal.js CHANGED
@@ -1,7 +1,53 @@
1
1
  import { createContractSnapshot, flowSourceHash, validateFlowProposal, } from './application-development.js';
2
+ import { validateResolvedModules } from './module.js';
2
3
  export const FELTDB_PROPOSAL_COLLECTION = '_feltdb.Proposal';
3
4
  export const FELTDB_PROPOSAL_EVENT_COLLECTION = '_feltdb.ProposalEvent';
5
+ export const FELTDB_PROPOSAL_PREVIEW_COLLECTION = '_feltdb.ProposalPreview';
4
6
  export const FELTDB_PROPOSAL_VERSION = 1;
7
+ function redactProposalSecretValues(input) {
8
+ const visit = (value, key = '') => {
9
+ if (value === null || value === undefined)
10
+ return value;
11
+ if (typeof value === 'string')
12
+ return /(?:sk_(?:live|test)_|whsec_|-----BEGIN PRIVATE KEY-----)/.test(value) ? '[REDACTED]' : value;
13
+ if (Array.isArray(value))
14
+ return value.map(item => visit(item));
15
+ if (typeof value === 'object')
16
+ return Object.fromEntries(Object.entries(value).map(([name, child]) => [/secret|password|token|api_?key|credential|private_?key/i.test(name) ? name : name, /secret|password|token|api_?key|credential|private_?key/i.test(name) ? '[REDACTED]' : visit(child, name)]));
17
+ return /secret|password|token|api_?key|credential|private_?key/i.test(key) ? '[REDACTED]' : value;
18
+ };
19
+ return visit(structuredClone(input));
20
+ }
21
+ /** Canonical human diagnostic used by CLI and Studio text surfaces. */
22
+ export function renderProposalDiagnostic(proposal, options = {}) {
23
+ const impact = proposal.module_impact;
24
+ const section = (name, values) => values.length ? [name, ...values.map(value => ` ${value}`)] : [];
25
+ const readiness = options.readiness;
26
+ return [
27
+ `Proposal: ${proposal.id}`,
28
+ proposal.summary,
29
+ `Status ${proposal.status.toUpperCase()}`,
30
+ `Application ${proposal.application_id}`,
31
+ `Environment ${proposal.environment}`,
32
+ `Contract v${proposal.base_contract_version} ${proposal.base_contract_hash}`,
33
+ `Flow ${proposal.base_flow_hash}`,
34
+ ...(proposal.parent_proposal_id ? [`Based on ${proposal.parent_proposal_id}`] : []),
35
+ ...section('MODULES', proposal.module_versions.map(value => `+ ${value.id} (${value.provider}) ${value.version}`)),
36
+ ...section('STATE', impact.models.map(value => `+ ${value}`)),
37
+ ...section('RELATIONSHIPS', impact.relationships.map(value => `+ ${value}`)),
38
+ ...section('WORKFLOWS', impact.workflows.map(value => `+ ${value}`)),
39
+ ...section('EVENTS', impact.events.map(value => `+ ${value}`)),
40
+ ...section('CAPABILITIES', impact.capabilities.map(value => `+ ${value}`)),
41
+ ...section('AUTHORIZATION', impact.authorization.map(value => `+ ${value}`)),
42
+ ...section('CONFIGURATION', [...impact.configuration.map(value => `${value} configuration`), ...impact.secrets.map(value => `${value} required / secret`)]),
43
+ ...(readiness ? ['READINESS',
44
+ ` ${readiness.stale ? '!' : '✓'} Contract and flow ${readiness.stale ? 'stale' : 'current'}`,
45
+ ` ${readiness.blockers.length ? readiness.blockers.join(', ') : 'No blockers'}`] : []),
46
+ ...(options.preview ? ['PREVIEW', ' Current → Proposed available', ` ${options.preview.preview_id}`] : []),
47
+ ...section('HISTORY', (options.history ?? []).map(value => `✓ ${value.to_status}`)),
48
+ ...section('WARNINGS', proposal.warnings.map(value => `! ${value}`)),
49
+ ];
50
+ }
5
51
  const transitions = {
6
52
  proposed: ['validated', 'rejected'], validated: ['previewed', 'rejected'], previewed: ['approved', 'rejected'],
7
53
  approved: ['applied', 'expired'], applied: [], rejected: [], expired: [],
@@ -22,11 +68,15 @@ export class FeltDBProposalService {
22
68
  if (input.base_contract_hash !== current.snapshot.contract_hash || input.base_flow_hash !== await flowSourceHash(current.source))
23
69
  throw new Error('STALE_PROPOSAL');
24
70
  const id = `p_${crypto.randomUUID().replace(/-/g, '')}`;
25
- const record = { id, application_id: input.application_id, environment: input.environment,
71
+ const safeInput = redactProposalSecretValues(input);
72
+ const record = { id, application_id: safeInput.application_id, environment: safeInput.environment,
26
73
  status: 'proposed', proposal_version: FELTDB_PROPOSAL_VERSION, base_contract_version: current.snapshot.contract_version,
27
- base_contract_hash: input.base_contract_hash, base_flow_hash: input.base_flow_hash, proposed_flow: input.proposed_flow,
28
- contract_diff: [], source_plan: { files: [] }, summary: input.summary, warnings: input.warnings ?? [], created_by: input.actor,
29
- created_at: new Date().toISOString(), expires_at: input.expires_at, metadata: input.metadata ?? {}, parent_proposal_id: input.parent_proposal_id };
74
+ base_contract_hash: safeInput.base_contract_hash, base_flow_hash: safeInput.base_flow_hash, proposed_flow: safeInput.proposed_flow,
75
+ contract_diff: [], source_plan: { files: [] }, summary: safeInput.summary, warnings: safeInput.warnings ?? [], created_by: safeInput.actor,
76
+ created_at: new Date().toISOString(), expires_at: safeInput.expires_at, metadata: safeInput.metadata ?? {}, parent_proposal_id: safeInput.parent_proposal_id,
77
+ base_module_versions: current.snapshot.modules.map(value => ({ id: value.id, provider: value.provider, version: value.version })),
78
+ module_versions: current.snapshot.modules.map(value => ({ id: value.id, provider: value.provider, version: value.version })),
79
+ module_impact: { modules: [], models: [], relationships: [], events: [], workflows: [], capabilities: [], authorization: [], configuration: [], secrets: [], ownership: {}, state_flow: [] } };
30
80
  await this.store.create(FELTDB_PROPOSAL_COLLECTION, id, record);
31
81
  await this.event(id, undefined, 'proposed', input.actor);
32
82
  return record;
@@ -41,6 +91,25 @@ export class FeltDBProposalService {
41
91
  async history(id) {
42
92
  return (await this.store.list(FELTDB_PROPOSAL_EVENT_COLLECTION)).filter(value => value.proposal_id === id);
43
93
  }
94
+ async readiness(id) {
95
+ const record = await this.get(id);
96
+ const current = await this.context();
97
+ const currentFlowHash = await flowSourceHash(current.source);
98
+ const currentModules = current.snapshot.modules.map(value => ({ id: value.id, provider: value.provider, version: value.version }));
99
+ const blockers = [];
100
+ if (record.base_contract_hash !== current.snapshot.contract_hash)
101
+ blockers.push('contract_changed');
102
+ if (record.base_flow_hash !== currentFlowHash)
103
+ blockers.push('flow_changed');
104
+ if (JSON.stringify(record.base_module_versions ?? []) !== JSON.stringify(currentModules))
105
+ blockers.push('module_versions_changed');
106
+ if (record.expires_at && (typeof record.expires_at === 'number' ? record.expires_at * 1000 : Date.parse(record.expires_at)) <= Date.now())
107
+ blockers.push('expired');
108
+ return { status: record.status, readiness: blockers.length ? 'blocked' : 'ready', blockers, notes: [],
109
+ current_contract_hash: current.snapshot.contract_hash, proposal_contract_hash: record.base_contract_hash,
110
+ current_flow_hash: currentFlowHash, proposal_flow_hash: record.base_flow_hash,
111
+ stale: blockers.some(value => value !== 'expired'), expires_at: record.expires_at };
112
+ }
44
113
  async validate(id, actor) {
45
114
  const record = await this.get(id);
46
115
  this.assertMutable(record, 'proposed');
@@ -54,6 +123,22 @@ export class FeltDBProposalService {
54
123
  ];
55
124
  record.source_plan = { files: [{ path: 'feltdb.flow', operation: 'modify' }, { path: 'src/feltdb/generated-contract.ts', operation: 'modify' }] };
56
125
  record.warnings = [...new Set([...record.warnings, ...review.authorizationChanges.map(value => `Authorization ${value.widening ? 'widened' : 'changed'}: ${value.policy}: ${(value.before ?? []).join(' | ')} -> ${(value.after ?? []).join(' | ')}`)])];
126
+ record.warnings = [...new Set([...record.warnings, ...validateResolvedModules(review.proposedContract.manifest.modules ?? [], record.environment)])];
127
+ record.module_versions = (review.proposedContract.manifest.modules ?? []).map(value => ({ id: value.id, provider: value.provider, version: value.version }));
128
+ const moduleIds = new Set((review.proposedContract.manifest.modules ?? []).map(value => value.id));
129
+ record.module_impact = {
130
+ modules: [...moduleIds],
131
+ models: review.proposedSpec.collections.flatMap(collection => collection.fields.map(field => field.type.startsWith('ref ') ? field.type.slice(4) : '').filter(value => value.includes('.') && moduleIds.has(value.split('.')[0]))),
132
+ relationships: review.proposedSpec.collections.flatMap(collection => collection.fields.filter(field => field.type.startsWith('ref ')).map(field => `${collection.name}.${field.name} -> ${field.type.slice(4)}`)),
133
+ events: review.proposedSpec.triggers.map(value => value.event).filter(value => moduleIds.has(value.split('.')[0])),
134
+ workflows: review.proposedSpec.workflows.map(value => value.name),
135
+ capabilities: review.proposedContract.manifest.capabilities.filter(value => value.provider && moduleIds.has(value.provider)).map(value => value.name),
136
+ authorization: review.proposedSpec.policies.flatMap(value => value.statements.map(statement => `${value.name}: ${statement}`)),
137
+ configuration: (review.proposedContract.manifest.modules ?? []).flatMap(value => value.configuration.map(item => item.name)),
138
+ secrets: (review.proposedContract.manifest.modules ?? []).flatMap(value => value.secrets.map(item => item.name)),
139
+ ownership: Object.fromEntries((review.proposedContract.manifest.modules ?? []).flatMap(value => value.models.map(model => [`${value.id}.${model.name}`, model.ownership]))),
140
+ state_flow: (review.proposedContract.manifest.modules ?? []).flatMap(value => value.reconciliation.map(item => `${item.event} -> ${item.workflow} -> ${item.writes.join(', ')}`)),
141
+ };
57
142
  return this.move(record, 'validated', actor);
58
143
  }
59
144
  async preview(id, actor) {
@@ -62,8 +147,40 @@ export class FeltDBProposalService {
62
147
  const current = await this.context();
63
148
  const review = await validateFlowProposal({ proposal: { baseContractHash: record.base_contract_hash, baseFlowHash: record.base_flow_hash,
64
149
  proposedFlow: record.proposed_flow, summary: record.summary, changes: [], warnings: record.warnings }, currentFlow: current.source, snapshot: current.snapshot });
150
+ const proposed = createContractSnapshot(review.proposedContract, { environment: record.environment, contractVersion: record.base_contract_version + 1 });
151
+ const readiness = await this.readiness(id);
152
+ const now = Date.now();
153
+ const previewId = `pv_${crypto.randomUUID().replace(/-/g, '')}`;
65
154
  await this.move(record, 'previewed', actor);
66
- return { proposal: record, contract: createContractSnapshot(review.proposedContract, { environment: record.environment, contractVersion: record.base_contract_version + 1 }) };
155
+ record.preview_id = previewId;
156
+ await this.store.replace(FELTDB_PROPOSAL_COLLECTION, record.id, record);
157
+ const impact = record.module_impact;
158
+ const artifact = {
159
+ preview_id: previewId, proposal_id: id, application_id: record.application_id, environment: record.environment,
160
+ proposal_hash: record.base_contract_hash, created_at: new Date(now).toISOString(), expires_at: new Date(now + 60 * 60 * 1000).toISOString(), status: 'ready',
161
+ current: current.snapshot, proposed, current_contract: current.snapshot, proposed_contract: proposed,
162
+ semantic_diff: record.contract_diff, state_flow: impact.state_flow, capabilities: proposed.capabilities, workflows: proposed.workflows,
163
+ authorization: proposed.policies, configuration: impact.configuration, secrets: impact.secrets, modules: impact.modules,
164
+ ownership: impact.ownership, relationships: impact.relationships, events: impact.events,
165
+ seeded_records: proposed.schema.map(collection => ({ collection: collection.name, id: `preview_${collection.name.toLowerCase()}`, preview_data: true })),
166
+ data_classification: 'synthetic_preview', external_side_effects: 'simulated', readiness, proposal: record,
167
+ };
168
+ await this.store.create(FELTDB_PROPOSAL_PREVIEW_COLLECTION, previewId, artifact);
169
+ return artifact;
170
+ }
171
+ async getPreview(id) {
172
+ const artifact = await this.store.get(FELTDB_PROPOSAL_PREVIEW_COLLECTION, id);
173
+ if (!artifact)
174
+ throw new Error('PREVIEW_NOT_FOUND');
175
+ if (Date.parse(artifact.expires_at) <= Date.now())
176
+ throw new Error('PREVIEW_EXPIRED');
177
+ const proposal = await this.get(artifact.proposal_id);
178
+ if (proposal.preview_id !== id)
179
+ throw new Error('PREVIEW_INVALIDATED');
180
+ const readiness = await this.readiness(proposal.id);
181
+ if (readiness.stale)
182
+ throw new Error('PREVIEW_INVALIDATED');
183
+ return artifact;
67
184
  }
68
185
  async transition(id, status, actor, authority, approveAuthorization = false) {
69
186
  const record = await this.get(id);
@@ -72,6 +189,16 @@ export class FeltDBProposalService {
72
189
  throw new Error('PROPOSAL_EXPIRED');
73
190
  if (status === 'applied' && (!this.repositoryAuthority || authority !== this.repositoryAuthority))
74
191
  throw new Error('REPOSITORY_AUTHORITY_REQUIRED');
192
+ if (status === 'approved') {
193
+ if (!record.preview_id)
194
+ throw new Error('PREVIEW_REQUIRED');
195
+ await this.getPreview(record.preview_id);
196
+ const current = await this.context();
197
+ if (record.application_id !== current.snapshot.application.application_id || record.environment !== current.snapshot.application.environment)
198
+ throw new Error('PROPOSAL_SCOPE_MISMATCH');
199
+ if (record.base_contract_hash !== current.snapshot.contract_hash || record.base_flow_hash !== await flowSourceHash(current.source))
200
+ throw new Error('STALE_PROPOSAL');
201
+ }
75
202
  if (status === 'approved' && record.warnings.some(value => value.startsWith('Authorization ')) && !approveAuthorization)
76
203
  throw new Error('AUTHORIZATION_APPROVAL_REQUIRED');
77
204
  if (status === 'approved') {
@@ -9,11 +9,13 @@ export interface StudioAppProps {
9
9
  namespace?: string;
10
10
  deploymentRuntime?: string;
11
11
  applicationUrl?: string;
12
+ applicationId?: string;
13
+ environment?: string;
12
14
  developmentSession?: Record<string, string>;
13
15
  managedPublish?: ManagedPublishConfiguration;
14
16
  sourceSync?: SourceSyncConfiguration;
15
17
  onConnect?: (url: string, token: string) => void;
16
18
  }
17
- export declare function StudioApp({ db, remoteUrl, token, namespace, deploymentRuntime, applicationUrl, developmentSession, managedPublish, sourceSync, onConnect }: StudioAppProps): React.JSX.Element;
19
+ export declare function StudioApp({ db, remoteUrl, token, namespace, deploymentRuntime, applicationUrl, applicationId, environment, developmentSession, managedPublish, sourceSync, onConnect }: StudioAppProps): React.JSX.Element;
18
20
  export default StudioApp;
19
21
  //# sourceMappingURL=app.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAgBnD,OAA4B,EAAE,KAAK,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AACzG,OAAO,EAAa,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAIjF,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,WAAW,CAAC;AAEnB,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,cAAc,CAAC,EAAE,2BAA2B,CAAC;IAC7C,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,EAAE,SAAc,EAAE,KAAU,EAAE,SAAqB,EAAE,iBAA6B,EAAE,cAAmB,EAAE,kBAAkB,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,cAAc,qBA+IjN;AAED,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAgBnD,OAA4B,EAAE,KAAK,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AACzG,OAAO,EAAa,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAMjF,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,WAAW,CAAC;AAEnB,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,cAAc,CAAC,EAAE,2BAA2B,CAAC;IAC7C,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,EAAE,SAAc,EAAE,KAAU,EAAE,SAAqB,EAAE,iBAA6B,EAAE,cAAmB,EAAE,aAAkB,EAAE,WAA0B,EAAE,kBAAkB,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,cAAc,qBAqJjQ;AAED,eAAe,SAAS,CAAC"}
@@ -13,8 +13,9 @@ export interface SourceSyncConfiguration {
13
13
  credentialConfigured: boolean;
14
14
  };
15
15
  }
16
- export declare function AskFeltDB({ configuration, onApplied }: {
16
+ export declare function AskFeltDB({ configuration, onApplied, onProposalCreated }: {
17
17
  configuration?: SourceSyncConfiguration;
18
18
  onApplied?: () => void;
19
+ onProposalCreated?: (proposalId: string) => void;
19
20
  }): React.JSX.Element;
20
21
  //# sourceMappingURL=AskFeltDB.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AskFeltDB.d.ts","sourceRoot":"","sources":["../../src/components/AskFeltDB.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,MAAM,WAAW,uBAAuB;IAAG,OAAO,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,cAAc,GAAG,mBAAmB,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,OAAO,CAAC;QAAC,oBAAoB,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE;AAKtS,wBAAgB,SAAS,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE;IAAE,aAAa,CAAC,EAAE,uBAAuB,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,qBA0E1H"}
1
+ {"version":3,"file":"AskFeltDB.d.ts","sourceRoot":"","sources":["../../src/components/AskFeltDB.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,MAAM,WAAW,uBAAuB;IAAG,OAAO,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,cAAc,GAAG,mBAAmB,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,OAAO,CAAC;QAAC,oBAAoB,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE;AAKtS,wBAAgB,SAAS,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAAE,EAAE;IAAE,aAAa,CAAC,EAAE,uBAAuB,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAAC,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,qBA4E/L"}
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ import { FlowSpec } from '@feltdb/core';
3
+ export declare function ContractInspector({ model, section }: {
4
+ model: FlowSpec | null;
5
+ section: 'schema' | 'policies';
6
+ }): React.JSX.Element;
7
+ //# sourceMappingURL=ContractInspector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContractInspector.d.ts","sourceRoot":"","sources":["../../src/components/ContractInspector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,QAAQ,GAAC,UAAU,CAAA;CAAE,qBAM7G"}
@@ -1 +1 @@
1
- {"version":3,"file":"ManagedInstancePanel.d.ts","sourceRoot":"","sources":["../../src/components/ManagedInstancePanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAuRxC,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"ManagedInstancePanel.d.ts","sourceRoot":"","sources":["../../src/components/ManagedInstancePanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAmRxC,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -106,11 +106,7 @@ var i = () => {
106
106
  if (!u) return;
107
107
  let t = e.generateEnvContent({
108
108
  url: `https://${i}-feltdb.fly.dev`,
109
- token: u.secret,
110
- namespace: u.namespace,
111
- applicationId: i,
112
- revisionId: "v0.5-alpha",
113
- environment: "staging"
109
+ token: u.secret
114
110
  }), n = new Blob([t], { type: "text/plain" }), r = URL.createObjectURL(n), a = document.createElement("a");
115
111
  a.href = r, a.download = ".env.local", document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(r);
116
112
  },
@@ -0,0 +1,6 @@
1
+ import { default as React } from 'react';
2
+ import { FlowSpec } from '@feltdb/core';
3
+ export declare function ModuleExplorer({ model }: {
4
+ model: FlowSpec | null;
5
+ }): React.JSX.Element;
6
+ //# sourceMappingURL=ModuleExplorer.d.ts.map