@noodleseed/one 0.121.0 → 0.122.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 (152) hide show
  1. package/dist/commands/session.d.ts.map +1 -1
  2. package/dist/commands/session.js +5 -2
  3. package/dist/commands/session.js.map +1 -1
  4. package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +1 -1
  5. package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js.map +1 -1
  6. package/node_modules/@noodle-borg/agent-kit/dist/plugin-marketplace-docs.js +4 -4
  7. package/node_modules/@noodle-borg/agent-kit/dist/plugin-submission.js +8 -8
  8. package/node_modules/@noodle-borg/agent-kit/dist/plugin-submission.js.map +1 -1
  9. package/node_modules/@noodle-borg/agent-kit/dist/skill-operations-refs.js +1 -1
  10. package/node_modules/@noodle-borg/agent-kit/dist/skill-operations-refs.js.map +1 -1
  11. package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
  12. package/node_modules/@noodle-borg/assistant-gateway/package.json +1 -1
  13. package/node_modules/@noodle-borg/developer-mcp/dist/contracts.d.ts +30 -9
  14. package/node_modules/@noodle-borg/developer-mcp/dist/contracts.d.ts.map +1 -1
  15. package/node_modules/@noodle-borg/developer-mcp/dist/contracts.js +21 -6
  16. package/node_modules/@noodle-borg/developer-mcp/dist/contracts.js.map +1 -1
  17. package/node_modules/@noodle-borg/developer-mcp/dist/port.d.ts +2 -1
  18. package/node_modules/@noodle-borg/developer-mcp/dist/port.d.ts.map +1 -1
  19. package/node_modules/@noodle-borg/developer-mcp/dist/port.js.map +1 -1
  20. package/node_modules/@noodle-borg/developer-mcp/dist/prompts.js +3 -3
  21. package/node_modules/@noodle-borg/developer-mcp/dist/prompts.js.map +1 -1
  22. package/node_modules/@noodle-borg/developer-mcp/dist/resources.d.ts.map +1 -1
  23. package/node_modules/@noodle-borg/developer-mcp/dist/resources.js +10 -9
  24. package/node_modules/@noodle-borg/developer-mcp/dist/resources.js.map +1 -1
  25. package/node_modules/@noodle-borg/developer-mcp/dist/results.d.ts +4 -3
  26. package/node_modules/@noodle-borg/developer-mcp/dist/results.d.ts.map +1 -1
  27. package/node_modules/@noodle-borg/developer-mcp/dist/results.js +5 -19
  28. package/node_modules/@noodle-borg/developer-mcp/dist/results.js.map +1 -1
  29. package/node_modules/@noodle-borg/developer-mcp/dist/server.js +3 -3
  30. package/node_modules/@noodle-borg/developer-mcp/dist/server.js.map +1 -1
  31. package/node_modules/@noodle-borg/developer-mcp/dist/tools/apps.d.ts.map +1 -1
  32. package/node_modules/@noodle-borg/developer-mcp/dist/tools/apps.js +6 -25
  33. package/node_modules/@noodle-borg/developer-mcp/dist/tools/apps.js.map +1 -1
  34. package/node_modules/@noodle-borg/developer-mcp/dist/tools/context.d.ts +16 -3
  35. package/node_modules/@noodle-borg/developer-mcp/dist/tools/context.d.ts.map +1 -1
  36. package/node_modules/@noodle-borg/developer-mcp/dist/tools/context.js +22 -19
  37. package/node_modules/@noodle-borg/developer-mcp/dist/tools/context.js.map +1 -1
  38. package/node_modules/@noodle-borg/developer-mcp/dist/tools/deployments.d.ts.map +1 -1
  39. package/node_modules/@noodle-borg/developer-mcp/dist/tools/deployments.js +3 -9
  40. package/node_modules/@noodle-borg/developer-mcp/dist/tools/deployments.js.map +1 -1
  41. package/node_modules/@noodle-borg/developer-mcp/dist/tools/diagnose.d.ts.map +1 -1
  42. package/node_modules/@noodle-borg/developer-mcp/dist/tools/diagnose.js +15 -16
  43. package/node_modules/@noodle-borg/developer-mcp/dist/tools/diagnose.js.map +1 -1
  44. package/node_modules/@noodle-borg/developer-mcp/dist/tools/operations.d.ts.map +1 -1
  45. package/node_modules/@noodle-borg/developer-mcp/dist/tools/operations.js +9 -17
  46. package/node_modules/@noodle-borg/developer-mcp/dist/tools/operations.js.map +1 -1
  47. package/node_modules/@noodle-borg/developer-mcp/dist/tools/rollback.d.ts.map +1 -1
  48. package/node_modules/@noodle-borg/developer-mcp/dist/tools/rollback.js +7 -10
  49. package/node_modules/@noodle-borg/developer-mcp/dist/tools/rollback.js.map +1 -1
  50. package/node_modules/@noodle-borg/knowledge/dist/budget.d.ts +41 -17
  51. package/node_modules/@noodle-borg/knowledge/dist/budget.d.ts.map +1 -1
  52. package/node_modules/@noodle-borg/knowledge/dist/budget.js +0 -0
  53. package/node_modules/@noodle-borg/knowledge/dist/budget.js.map +1 -1
  54. package/node_modules/@noodle-borg/knowledge/dist/index.d.ts +1 -0
  55. package/node_modules/@noodle-borg/knowledge/dist/index.d.ts.map +1 -1
  56. package/node_modules/@noodle-borg/knowledge/dist/index.js +1 -0
  57. package/node_modules/@noodle-borg/knowledge/dist/index.js.map +1 -1
  58. package/node_modules/@noodle-borg/knowledge/dist/postgres-budget-store.d.ts +22 -0
  59. package/node_modules/@noodle-borg/knowledge/dist/postgres-budget-store.d.ts.map +1 -0
  60. package/node_modules/@noodle-borg/knowledge/dist/postgres-budget-store.js +102 -0
  61. package/node_modules/@noodle-borg/knowledge/dist/postgres-budget-store.js.map +1 -0
  62. package/node_modules/@noodle-borg/knowledge/dist/postgres-revision-store.d.ts +5 -3
  63. package/node_modules/@noodle-borg/knowledge/dist/postgres-revision-store.d.ts.map +1 -1
  64. package/node_modules/@noodle-borg/knowledge/dist/postgres-revision-store.js +61 -1
  65. package/node_modules/@noodle-borg/knowledge/dist/postgres-revision-store.js.map +1 -1
  66. package/node_modules/@noodle-borg/knowledge/dist/revision-store.d.ts +28 -1
  67. package/node_modules/@noodle-borg/knowledge/dist/revision-store.d.ts.map +1 -1
  68. package/node_modules/@noodle-borg/knowledge/dist/revision-store.js +39 -0
  69. package/node_modules/@noodle-borg/knowledge/dist/revision-store.js.map +1 -1
  70. package/node_modules/@noodle-borg/service/dist/auth/developer-grant-guard.d.ts +6 -4
  71. package/node_modules/@noodle-borg/service/dist/auth/developer-grant-guard.d.ts.map +1 -1
  72. package/node_modules/@noodle-borg/service/dist/auth/developer-grant-guard.js +13 -16
  73. package/node_modules/@noodle-borg/service/dist/auth/developer-grant-guard.js.map +1 -1
  74. package/node_modules/@noodle-borg/service/dist/developer-mcp/control-plane-adapter.d.ts +3 -2
  75. package/node_modules/@noodle-borg/service/dist/developer-mcp/control-plane-adapter.d.ts.map +1 -1
  76. package/node_modules/@noodle-borg/service/dist/developer-mcp/control-plane-adapter.js +66 -47
  77. package/node_modules/@noodle-borg/service/dist/developer-mcp/control-plane-adapter.js.map +1 -1
  78. package/node_modules/@noodle-borg/service/dist/developer-mcp/mount.d.ts.map +1 -1
  79. package/node_modules/@noodle-borg/service/dist/developer-mcp/mount.js +15 -16
  80. package/node_modules/@noodle-borg/service/dist/developer-mcp/mount.js.map +1 -1
  81. package/node_modules/@noodle-borg/service/dist/index.d.ts +2 -2
  82. package/node_modules/@noodle-borg/service/dist/index.d.ts.map +1 -1
  83. package/node_modules/@noodle-borg/service/dist/index.js +1 -1
  84. package/node_modules/@noodle-borg/service/dist/index.js.map +1 -1
  85. package/node_modules/@noodle-borg/service/dist/oauth/consent-claims.d.ts +0 -2
  86. package/node_modules/@noodle-borg/service/dist/oauth/consent-claims.d.ts.map +1 -1
  87. package/node_modules/@noodle-borg/service/dist/oauth/consent-claims.js +0 -16
  88. package/node_modules/@noodle-borg/service/dist/oauth/consent-claims.js.map +1 -1
  89. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-authorizer.d.ts +3 -28
  90. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-authorizer.d.ts.map +1 -1
  91. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-authorizer.js +8 -67
  92. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-authorizer.js.map +1 -1
  93. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-bootstrap.d.ts +0 -4
  94. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-bootstrap.d.ts.map +1 -1
  95. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-bootstrap.js +1 -14
  96. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-bootstrap.js.map +1 -1
  97. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-flow.d.ts +1 -1
  98. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-flow.d.ts.map +1 -1
  99. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-flow.js +45 -36
  100. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-flow.js.map +1 -1
  101. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-page.d.ts +2 -2
  102. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-page.d.ts.map +1 -1
  103. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-page.js +20 -229
  104. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-page.js.map +1 -1
  105. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-store-postgres.d.ts +3 -2
  106. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-store-postgres.d.ts.map +1 -1
  107. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-store-postgres.js +70 -36
  108. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-store-postgres.js.map +1 -1
  109. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant.d.ts +17 -6
  110. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant.d.ts.map +1 -1
  111. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant.js +98 -26
  112. package/node_modules/@noodle-borg/service/dist/oauth/developer-grant.js.map +1 -1
  113. package/node_modules/@noodle-borg/service/dist/oauth/service-bootstrap.d.ts.map +1 -1
  114. package/node_modules/@noodle-borg/service/dist/oauth/service-bootstrap.js +0 -2
  115. package/node_modules/@noodle-borg/service/dist/oauth/service-bootstrap.js.map +1 -1
  116. package/node_modules/@noodle-borg/service/dist/oauth/upstream-consent.js +1 -1
  117. package/node_modules/@noodle-borg/service/dist/oauth/upstream-consent.js.map +1 -1
  118. package/node_modules/@noodle-borg/service/dist/routes/analytics.js +3 -3
  119. package/node_modules/@noodle-borg/service/dist/routes/analytics.js.map +1 -1
  120. package/node_modules/@noodle-borg/service/dist/routes/apps.d.ts.map +1 -1
  121. package/node_modules/@noodle-borg/service/dist/routes/apps.js +6 -27
  122. package/node_modules/@noodle-borg/service/dist/routes/apps.js.map +1 -1
  123. package/node_modules/@noodle-borg/service/dist/routes/config-values.d.ts.map +1 -1
  124. package/node_modules/@noodle-borg/service/dist/routes/config-values.js +5 -8
  125. package/node_modules/@noodle-borg/service/dist/routes/config-values.js.map +1 -1
  126. package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts +7 -6
  127. package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts.map +1 -1
  128. package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +7 -6
  129. package/node_modules/@noodle-borg/service/dist/routes/control-plane.js.map +1 -1
  130. package/node_modules/@noodle-borg/service/dist/routes/deploy-preflight.js +1 -1
  131. package/node_modules/@noodle-borg/service/dist/routes/deploy-preflight.js.map +1 -1
  132. package/node_modules/@noodle-borg/service/dist/routes/deployment-package.d.ts.map +1 -1
  133. package/node_modules/@noodle-borg/service/dist/routes/deployment-package.js +2 -7
  134. package/node_modules/@noodle-borg/service/dist/routes/deployment-package.js.map +1 -1
  135. package/node_modules/@noodle-borg/service/dist/routes/deployments.d.ts.map +1 -1
  136. package/node_modules/@noodle-borg/service/dist/routes/deployments.js +7 -20
  137. package/node_modules/@noodle-borg/service/dist/routes/deployments.js.map +1 -1
  138. package/node_modules/@noodle-borg/service/dist/routes/diagnostics.js +1 -1
  139. package/node_modules/@noodle-borg/service/dist/routes/diagnostics.js.map +1 -1
  140. package/node_modules/@noodle-borg/service/dist/routes/envs.d.ts.map +1 -1
  141. package/node_modules/@noodle-borg/service/dist/routes/envs.js +4 -8
  142. package/node_modules/@noodle-borg/service/dist/routes/envs.js.map +1 -1
  143. package/node_modules/@noodle-borg/service/dist/routes/logs.js +1 -1
  144. package/node_modules/@noodle-borg/service/dist/routes/logs.js.map +1 -1
  145. package/node_modules/@noodle-borg/service/dist/routes/rollback.js +1 -1
  146. package/node_modules/@noodle-borg/service/dist/routes/rollback.js.map +1 -1
  147. package/node_modules/@noodle-borg/service/dist/store/postgres-schema.d.ts.map +1 -1
  148. package/node_modules/@noodle-borg/service/dist/store/postgres-schema.js +21 -0
  149. package/node_modules/@noodle-borg/service/dist/store/postgres-schema.js.map +1 -1
  150. package/node_modules/@noodle-borg/service/package.json +1 -1
  151. package/node_modules/@noodleseed/assistant/package.json +41 -16
  152. package/package.json +2 -2
@@ -1,246 +1,37 @@
1
1
  import { renderOAuthPage } from './branding.js';
2
2
  const CAPABILITY_COPY = {
3
3
  'cloud:read': 'Read cloud apps, deployments, logs, analytics, and diagnostics',
4
- 'deployments:write': 'Build and deploy apps to the selected environments',
5
- 'deployments:rollback': 'Roll back deployments',
6
- 'config:write': 'Set and remove variables and secrets on the selected environments (never read a secret back)',
4
+ 'deployments:write': 'Build and deploy apps',
5
+ 'deployments:rollback': 'Roll back deployments when you are an organization owner',
6
+ 'config:write': 'Set and remove variables and secrets (never read a secret back)',
7
7
  };
8
- const ENVIRONMENT_PRIORITY = {
9
- dev: 0,
10
- staging: 1,
11
- prod: 3,
12
- };
13
- const DEVELOPER_GRANT_STYLES = `
14
- .ns-card{width:min(100%,46rem)}
15
- .ns-title{max-width:38rem;white-space:normal}
16
- .developer-context{grid-template-columns:repeat(3,minmax(0,1fr));gap:.75rem;margin-bottom:1.55rem}
17
- .developer-context>div{min-width:0}
18
- .developer-context .ns-dd{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
19
- .developer-grant{display:grid;gap:1.35rem}
20
- .developer-section{min-width:0;margin:0;padding:0;border:0}
21
- .developer-step{display:flex;align-items:center;gap:.6rem;margin:0 0 .3rem;color:var(--fg);font-size:.94rem;font-weight:650}
22
- .developer-step-number{display:grid;place-items:center;width:1.6rem;height:1.6rem;border:1px solid var(--border);border-radius:999px;color:var(--orange);font-size:.72rem}
23
- .developer-help{margin:0 0 .8rem;color:var(--muted);font-size:.8rem;line-height:1.5}
24
- .developer-org-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.65rem}
25
- .developer-org-choice{position:relative;display:block;min-width:0;cursor:pointer}
26
- .developer-org-choice>input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
27
- .developer-org-card{display:flex;align-items:center;justify-content:space-between;gap:.85rem;min-height:4rem;padding:.85rem .95rem;border:1px solid var(--border);border-radius:.8rem;background:rgba(255,255,255,.025);transition:border-color .16s ease,background .16s ease,box-shadow .16s ease}
28
- .developer-org-choice:hover .developer-org-card{border-color:color-mix(in srgb,var(--border),var(--fg) 20%);background:rgba(255,255,255,.04)}
29
- .developer-org-choice>input:focus-visible+.developer-org-card{outline:2px solid var(--orange);outline-offset:2px}
30
- .developer-org-choice>input:checked+.developer-org-card{border-color:color-mix(in srgb,var(--orange) 70%,transparent);background:linear-gradient(135deg,color-mix(in srgb,var(--orange) 13%,transparent),rgba(255,255,255,.025));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--orange) 12%,transparent)}
31
- .developer-org-name{display:block;overflow:hidden;color:var(--fg);font-size:.88rem;font-weight:650;text-overflow:ellipsis;white-space:nowrap}
32
- .developer-org-access{display:block;margin-top:.18rem;color:var(--muted);font-size:.72rem}
33
- .developer-choice-mark{display:grid;flex:0 0 auto;place-items:center;width:1.1rem;height:1.1rem;border:1px solid var(--border);border-radius:999px;color:transparent;font-size:.65rem}
34
- .developer-org-choice>input:checked+.developer-org-card .developer-choice-mark{border-color:var(--orange);background:var(--orange);color:#130b07}
35
- .developer-environment-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.6rem}
36
- .developer-environment{position:relative;display:block;min-width:0;cursor:pointer}
37
- .developer-environment>input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
38
- .developer-environment-card{display:flex;align-items:flex-start;gap:.65rem;min-height:4.1rem;padding:.8rem;border:1px solid var(--border);border-radius:.75rem;background:rgba(255,255,255,.025);transition:border-color .16s ease,background .16s ease}
39
- .developer-environment:hover .developer-environment-card{border-color:color-mix(in srgb,var(--border),var(--fg) 20%);background:rgba(255,255,255,.04)}
40
- .developer-environment>input:focus-visible+.developer-environment-card{outline:2px solid var(--orange);outline-offset:2px}
41
- .developer-environment>input:checked+.developer-environment-card{border-color:color-mix(in srgb,var(--orange) 70%,transparent);background:color-mix(in srgb,var(--orange) 10%,transparent)}
42
- .developer-checkbox{display:grid;flex:0 0 auto;place-items:center;width:1rem;height:1rem;margin-top:.08rem;border:1px solid var(--border);border-radius:.25rem;color:transparent;font-size:.68rem}
43
- .developer-environment>input:checked+.developer-environment-card .developer-checkbox{border-color:var(--orange);background:var(--orange);color:#130b07}
44
- .developer-environment-name{display:block;color:var(--fg);font-size:.84rem;font-weight:650}
45
- .developer-environment-note{display:block;margin-top:.2rem;color:var(--muted);font-size:.68rem;line-height:1.35}
46
- .developer-environment-note.is-production{color:#f1a273}
47
- .developer-capabilities{margin:.75rem 0 0;padding:.7rem .8rem;border:1px solid var(--border);border-radius:.7rem;background:rgba(0,0,0,.12);color:var(--muted);font-size:.75rem}
48
- .developer-capabilities summary{cursor:pointer;color:var(--fg);font-weight:600}
49
- .developer-capabilities ul{display:grid;gap:.35rem;margin:.6rem 0 0;padding-left:1.15rem;line-height:1.45}
50
- .developer-summary{padding:.85rem .95rem;border:1px solid var(--border);border-radius:.75rem;background:rgba(255,255,255,.025)}
51
- .developer-summary-label{margin:0 0 .24rem;color:var(--muted);font-size:.65rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase}
52
- .developer-summary-copy{margin:0;color:var(--fg);font-size:.8rem;line-height:1.5}
53
- .developer-selection-error{margin:.45rem 0 0;color:#f1a273;font-size:.75rem}
54
- .developer-grant .ns-row{margin-top:0}
55
- .developer-grant .btn-primary:disabled{cursor:not-allowed;filter:none;opacity:.45}
56
- @media(max-width:680px){
57
- .ns-card{padding:1.35rem}
58
- .developer-context,.developer-org-list,.developer-environment-grid{grid-template-columns:1fr}
59
- .developer-context{gap:.55rem}
60
- }
61
- `;
62
- const DEVELOPER_GRANT_SCRIPT = `<script>
63
- (function(){
64
- var form=document.querySelector('[data-developer-grant]');
65
- if(!form)return;
66
- var choices=Array.from(form.querySelectorAll('[data-org-choice]'));
67
- var panels=Array.from(form.querySelectorAll('[data-org-panel]'));
68
- var authorize=form.querySelector('[data-authorize]');
69
- var summary=form.querySelector('[data-selection-summary]');
70
- var error=form.querySelector('[data-selection-error]');
71
- var clientName=form.getAttribute('data-client-name')||'The developer plugin';
72
- function activeIndex(){
73
- var selected=choices.find(function(choice){return choice.checked;});
74
- return selected ? Number(selected.getAttribute('data-org-choice')) : -1;
75
- }
76
- function activeEnvironments(){
77
- var panel=panels[activeIndex()];
78
- return panel ? Array.from(panel.querySelectorAll('input[name="environment"]:checked')).map(function(input){return input.value;}) : [];
79
- }
80
- function naturalList(values){
81
- if(values.length<2)return values[0]||'';
82
- if(values.length===2)return values[0]+' and '+values[1];
83
- return values.slice(0,-1).join(', ')+', and '+values[values.length-1];
84
- }
85
- function update(){
86
- var panel=panels[activeIndex()];
87
- var environments=activeEnvironments();
88
- var valid=panel!==undefined&&environments.length>0;
89
- authorize.disabled=!valid;
90
- error.hidden=valid;
91
- if(valid){
92
- summary.textContent=clientName+' can '+panel.getAttribute('data-capability-summary')+' in '+panel.getAttribute('data-org-name')+' for '+naturalList(environments)+'.';
93
- }else{
94
- summary.textContent='Select at least one environment to continue.';
95
- }
96
- }
97
- choices.forEach(function(choice){
98
- choice.addEventListener('change',function(){
99
- var next=activeIndex();
100
- panels.forEach(function(panel,index){
101
- var active=index===next;
102
- panel.hidden=!active;
103
- var environments=Array.from(panel.querySelectorAll('input[name="environment"]'));
104
- environments.forEach(function(environment){environment.checked=false;environment.disabled=!active;});
105
- if(active){
106
- var preferred=environments.find(function(environment){return environment.value==='dev';});
107
- if(preferred)preferred.checked=true;
108
- }
109
- });
110
- update();
111
- });
112
- });
113
- form.addEventListener('change',function(event){
114
- if(event.target&&event.target.matches('input[name="environment"]'))update();
115
- });
116
- form.addEventListener('submit',function(event){
117
- var submitter=event.submitter;
118
- if(submitter&&submitter.value==='deny')return;
119
- if(activeEnvironments().length===0){event.preventDefault();update();}
120
- });
121
- update();
122
- })();
123
- </script>`;
124
8
  export function renderDeveloperGrantPage(input) {
125
- const controls = input.choices.length === 0
126
- ? '<div class="ns-alert"><p class="ns-note">No organizations are available for this account.</p></div>'
127
- : renderControls(input);
128
- const contentHtml = `<p class="ns-lede">Review and choose the exact access for <strong>${escapeHtml(input.clientName)}</strong>. You can select more than one environment.</p>
129
- <dl class="ns-dl developer-context">
130
- <div><dt class="ns-dt">Signed in as</dt><dd class="ns-dd" title="${escapeHtml(input.userEmail)}">${escapeHtml(input.userEmail)}</dd></div>
131
- <div><dt class="ns-dt">Noodle Cloud</dt><dd class="ns-dd" title="${escapeHtml(input.resourceHost)}">${escapeHtml(input.resourceHost)}</dd></div>
132
- <div><dt class="ns-dt">Redirects to</dt><dd class="ns-dd" title="${escapeHtml(input.redirectHost)}">${escapeHtml(input.redirectHost)}</dd></div>
9
+ const capabilities = input.capabilities
10
+ .map((capability) => `<li>${escapeHtml(CAPABILITY_COPY[capability])}</li>`)
11
+ .join('');
12
+ const contentHtml = `<p class="ns-lede"><strong>${escapeHtml(input.clientName)}</strong> wants to use your Noodle Seed developer access.</p>
13
+ <dl class="ns-dl">
14
+ <div><dt class="ns-dt">Signed in as</dt><dd class="ns-dd">${escapeHtml(input.userEmail)}</dd></div>
15
+ <div><dt class="ns-dt">Noodle Cloud</dt><dd class="ns-dd">${escapeHtml(input.resourceHost)}</dd></div>
16
+ <div><dt class="ns-dt">Redirects to</dt><dd class="ns-dd">${escapeHtml(input.redirectHost)}</dd></div>
133
17
  </dl>
134
- <form method="post" action="${escapeHtml(input.grantAction)}" class="developer-grant" data-developer-grant data-client-name="${escapeHtml(input.clientName)}">
18
+ <p class="ns-note">This connection can operate in the organizations and environments you can currently access. Your access updates automatically when your membership or role changes.</p>
19
+ <ul>${capabilities}</ul>
20
+ <p class="ns-note">Only authorize if you recognize this application.</p>
21
+ <form method="post" action="${escapeHtml(input.grantAction)}">
135
22
  <input type="hidden" name="grant_token" value="${escapeHtml(input.grantToken)}" />
136
- ${controls}
23
+ <div class="ns-row">
24
+ <button type="submit" name="decision" value="deny" class="btn btn-ghost">Deny</button>
25
+ <span class="btn-glow"><button type="submit" name="decision" value="approve" class="btn btn-primary">Authorize</button></span>
26
+ </div>
137
27
  </form>`;
138
28
  return renderOAuthPage({
139
29
  title: 'Authorize developer access — Noodle Seed',
140
30
  kicker: 'Developer access',
141
- heading: 'Choose where this developer plugin can operate',
31
+ heading: 'Authorize Noodle Seed developer access',
142
32
  contentHtml,
143
- additionalStyles: DEVELOPER_GRANT_STYLES,
144
- ...(input.choices.length === 0 ? {} : { scriptHtml: DEVELOPER_GRANT_SCRIPT }),
145
- });
146
- }
147
- function renderControls(input) {
148
- const organizations = input.choices.map(renderOrganizationChoice).join('');
149
- const panels = input.choices.map(renderEnvironmentPanel).join('');
150
- const first = input.choices[0];
151
- const initialEnvironment = first?.environments.includes('dev') ? 'dev' : first?.environments[0];
152
- const initialSummary = first !== undefined && initialEnvironment !== undefined
153
- ? `${input.clientName} can ${capabilitySummary(first.capabilities)} in ${first.displayName ?? first.org} for ${initialEnvironment}.`
154
- : 'Select at least one environment to continue.';
155
- return `<fieldset class="developer-section">
156
- <legend class="developer-step"><span class="developer-step-number">1</span>Choose organization</legend>
157
- <p class="developer-help">Only one organization can be authorized in this connection.</p>
158
- <div class="developer-org-list">${organizations}</div>
159
- </fieldset>
160
- <div>${panels}</div>
161
- <div class="developer-summary" aria-live="polite">
162
- <p class="developer-summary-label">Access summary</p>
163
- <p class="developer-summary-copy" data-selection-summary>${escapeHtml(initialSummary)}</p>
164
- <p class="developer-selection-error" data-selection-error hidden>Select at least one environment to continue.</p>
165
- </div>
166
- <div class="ns-row">
167
- <button type="submit" name="decision" value="deny" class="btn btn-ghost">Deny</button>
168
- <span class="btn-glow"><button type="submit" name="decision" value="approve" class="btn btn-primary" data-authorize>Authorize access</button></span>
169
- </div>`;
170
- }
171
- function renderOrganizationChoice(choice, index) {
172
- const label = choice.displayName ?? choice.org;
173
- const access = choice.capabilities.includes('deployments:rollback')
174
- ? 'Owner access'
175
- : 'Developer access';
176
- return `<label class="developer-org-choice">
177
- <input type="radio" name="org" value="${escapeHtml(choice.org)}" data-org-choice="${index}"${index === 0 ? ' checked' : ''} />
178
- <span class="developer-org-card">
179
- <span><span class="developer-org-name">${escapeHtml(label)}</span><span class="developer-org-access">${access}</span></span>
180
- <span class="developer-choice-mark" aria-hidden="true">✓</span>
181
- </span>
182
- </label>`;
183
- }
184
- function renderEnvironmentPanel(choice, choiceIndex) {
185
- const environments = orderedEnvironments(choice.environments)
186
- .map((environment, environmentIndex) => renderEnvironment(environment, choiceIndex, environmentIndex, choiceIndex === 0))
187
- .join('');
188
- const capabilities = choice.capabilities
189
- .map((capability) => `<li>${escapeHtml(CAPABILITY_COPY[capability])}</li>`)
190
- .join('');
191
- const label = choice.displayName ?? choice.org;
192
- return `<section class="developer-section" data-org-panel="${choiceIndex}" data-org-name="${escapeHtml(label)}" data-capability-summary="${escapeHtml(capabilitySummary(choice.capabilities))}"${choiceIndex === 0 ? '' : ' hidden'}>
193
- <h2 class="developer-step"><span class="developer-step-number">2</span>Choose environments</h2>
194
- <p class="developer-help">Select every environment this plugin should be able to operate. Development is selected for you.</p>
195
- <div class="developer-environment-grid">${environments}</div>
196
- <details class="developer-capabilities">
197
- <summary>What the plugin can do</summary>
198
- <ul>${capabilities}</ul>
199
- </details>
200
- </section>`;
201
- }
202
- function renderEnvironment(environment, choiceIndex, environmentIndex, active) {
203
- const id = `developer-environment-${choiceIndex}-${environmentIndex}`;
204
- const selected = active && environment === 'dev';
205
- const note = environmentNote(environment);
206
- return `<label class="developer-environment" for="${id}">
207
- <input id="${id}" type="checkbox" name="environment" value="${escapeHtml(environment)}"${selected ? ' checked' : ''}${active ? '' : ' disabled'} />
208
- <span class="developer-environment-card">
209
- <span class="developer-checkbox" aria-hidden="true">✓</span>
210
- <span><span class="developer-environment-name">${escapeHtml(environment)}</span><span class="developer-environment-note${environment === 'prod' ? ' is-production' : ''}">${note}</span></span>
211
- </span>
212
- </label>`;
213
- }
214
- function orderedEnvironments(environments) {
215
- return [...new Set(environments)].sort((left, right) => {
216
- const leftPriority = ENVIRONMENT_PRIORITY[left] ?? 2;
217
- const rightPriority = ENVIRONMENT_PRIORITY[right] ?? 2;
218
- return leftPriority - rightPriority || left.localeCompare(right);
219
33
  });
220
34
  }
221
- function environmentNote(environment) {
222
- if (environment === 'dev')
223
- return 'Recommended';
224
- if (environment === 'prod')
225
- return 'Can affect live users';
226
- return 'Optional';
227
- }
228
- function capabilitySummary(capabilities) {
229
- const actions = [];
230
- if (capabilities.includes('cloud:read'))
231
- actions.push('read cloud state');
232
- if (capabilities.includes('deployments:write'))
233
- actions.push('build and deploy apps');
234
- if (capabilities.includes('config:write'))
235
- actions.push('set variables and secrets');
236
- if (capabilities.includes('deployments:rollback'))
237
- actions.push('roll back deployments');
238
- if (actions.length === 0)
239
- return 'use its assigned capabilities';
240
- if (actions.length === 1)
241
- return actions[0] ?? 'use its assigned capabilities';
242
- return `${actions.slice(0, -1).join(', ')} and ${actions.at(-1)}`;
243
- }
244
35
  function escapeHtml(value) {
245
36
  return value
246
37
  .replace(/&/g, '&amp;')
@@ -1 +1 @@
1
- {"version":3,"file":"developer-grant-page.js","sourceRoot":"","sources":["../../src/oauth/developer-grant-page.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"developer-grant-page.js","sourceRoot":"","sources":["../../src/oauth/developer-grant-page.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAYhD,MAAM,eAAe,GAAkD;IACrE,YAAY,EAAE,gEAAgE;IAC9E,mBAAmB,EAAE,uBAAuB;IAC5C,sBAAsB,EAAE,0DAA0D;IAClF,cAAc,EAAE,iEAAiE;CAClF,CAAC;AAEF,MAAM,UAAU,wBAAwB,CAAC,KAA8B;IACrE,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY;SACpC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,OAAO,UAAU,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC;SAC1E,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,MAAM,WAAW,GAAG,8BAA8B,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC;;kEAEd,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC;kEAC3B,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC;kEAC9B,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC;;;UAGtF,YAAY;;kCAEY,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC;uDACR,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC;;;;;YAKvE,CAAC;IACX,OAAO,eAAe,CAAC;QACrB,KAAK,EAAE,0CAA0C;QACjD,MAAM,EAAE,kBAAkB;QAC1B,OAAO,EAAE,wCAAwC;QACjD,WAAW;KACZ,CAAC,CAAC;AACL,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC"}
@@ -1,10 +1,11 @@
1
1
  import type { Pool } from 'pg';
2
- import { type CreateDeveloperAccessGrant, type DeveloperAccessGrant, type DeveloperGrantFactoryOptions, type DeveloperGrantStore } from './developer-grant.js';
2
+ import { type ActiveDeveloperGrantLookup, type CreateDeveloperAccessGrant, type DeveloperAccessGrant, type DeveloperGrantFactoryOptions, type DeveloperGrantStore } from './developer-grant.js';
3
3
  export declare class PostgresDeveloperGrantStore implements DeveloperGrantStore {
4
4
  #private;
5
5
  constructor(pool: Pool, options?: DeveloperGrantFactoryOptions);
6
6
  initialize(): Promise<void>;
7
- create(input: CreateDeveloperAccessGrant): Promise<DeveloperAccessGrant>;
7
+ getOrCreateActive(input: CreateDeveloperAccessGrant): Promise<DeveloperAccessGrant>;
8
+ getActive(input: ActiveDeveloperGrantLookup): Promise<DeveloperAccessGrant | undefined>;
8
9
  get(id: string): Promise<DeveloperAccessGrant | undefined>;
9
10
  revoke(id: string, at: string): Promise<DeveloperAccessGrant | undefined>;
10
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"developer-grant-store-postgres.d.ts","sourceRoot":"","sources":["../../src/oauth/developer-grant-store-postgres.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAI/B,OAAO,EACL,KAAK,0BAA0B,EAE/B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EAGzB,MAAM,sBAAsB,CAAC;AAe9B,qBAAa,2BAA4B,YAAW,mBAAmB;;gBAIzD,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,4BAAiC;IAK5D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,MAAM,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA+BxE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAO1D,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;CAYhF"}
1
+ {"version":3,"file":"developer-grant-store-postgres.d.ts","sourceRoot":"","sources":["../../src/oauth/developer-grant-store-postgres.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAI/B,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,EAE/B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EAGzB,MAAM,sBAAsB,CAAC;AAgB9B,qBAAa,2BAA4B,YAAW,mBAAmB;;gBAIzD,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,4BAAiC;IAK5D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,iBAAiB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAyDnF,SAAS,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAqBvF,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAS1D,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;CAYhF"}
@@ -3,11 +3,12 @@ import { z } from 'zod';
3
3
  import { ensureDeveloperGrantSchema } from '../store/postgres-schema.js';
4
4
  import { createDeveloperAccessGrantRecord, normalizeDeveloperAccessGrant, normalizeDeveloperGrantTimestamp, } from './developer-grant.js';
5
5
  const developerGrantRowSchema = z.object({
6
+ grant_version: z.literal(2),
6
7
  id: z.string(),
7
8
  client_id: z.string(),
8
9
  subject: z.string(),
9
- org_slug: z.string(),
10
- environments: z.array(z.string()),
10
+ resource: z.string(),
11
+ access_model: z.literal('live_user'),
11
12
  capabilities: z.array(z.enum(DEVELOPER_CAPABILITIES)),
12
13
  created_at: z.coerce.date(),
13
14
  updated_at: z.coerce.date(),
@@ -24,38 +25,73 @@ export class PostgresDeveloperGrantStore {
24
25
  async initialize() {
25
26
  await ensureDeveloperGrantSchema(this.#pool);
26
27
  }
27
- async create(input) {
28
+ async getOrCreateActive(input) {
28
29
  const grant = createDeveloperAccessGrantRecord(input, this.#options);
29
- try {
30
- const { rows } = await this.#pool.query(`INSERT INTO developer_access_grants
31
- (id, client_id, subject, org_slug, environments, capabilities,
32
- created_at, updated_at, expires_at, revoked_at)
33
- VALUES ($1, $2, $3, $4, $5::jsonb, $6::jsonb, $7, $8, $9, $10)
34
- RETURNING *`, [
35
- grant.id,
36
- grant.clientId,
37
- grant.subject,
38
- grant.org,
39
- JSON.stringify(grant.environments),
40
- JSON.stringify(grant.capabilities),
41
- grant.createdAt,
42
- grant.updatedAt,
43
- grant.expiresAt ?? null,
44
- grant.revokedAt ?? null,
45
- ]);
30
+ const existing = await this.getActive({
31
+ clientId: grant.clientId,
32
+ subject: grant.subject,
33
+ resource: grant.resource,
34
+ at: grant.createdAt,
35
+ });
36
+ if (existing !== undefined)
37
+ return existing;
38
+ // The partial uniqueness constraint deliberately treats an unrevoked row as active. Retire an
39
+ // expired tuple before inserting its replacement so persistence matches the in-memory contract.
40
+ await this.#pool.query(`UPDATE developer_access_grants
41
+ SET revoked_at = $4::timestamptz,
42
+ updated_at = $4::timestamptz
43
+ WHERE grant_version = 2
44
+ AND access_model = 'live_user'
45
+ AND client_id = $1
46
+ AND subject = $2
47
+ AND resource = $3
48
+ AND revoked_at IS NULL
49
+ AND expires_at <= $4::timestamptz`, [grant.clientId, grant.subject, grant.resource, grant.createdAt]);
50
+ const { rows } = await this.#pool.query(`INSERT INTO developer_access_grants
51
+ (id, client_id, subject, org_slug, environments, capabilities,
52
+ created_at, updated_at, expires_at, revoked_at,
53
+ grant_version, resource, access_model)
54
+ VALUES ($1, $2, $3, NULL, NULL, $4::jsonb, $5, $6, $7, NULL, 2, $8, 'live_user')
55
+ ON CONFLICT DO NOTHING
56
+ RETURNING *`, [
57
+ grant.id,
58
+ grant.clientId,
59
+ grant.subject,
60
+ JSON.stringify(grant.capabilities),
61
+ grant.createdAt,
62
+ grant.updatedAt,
63
+ grant.expiresAt ?? null,
64
+ grant.resource,
65
+ ]);
66
+ if (rows[0] !== undefined)
46
67
  return grantFromRow(rows[0]);
47
- }
48
- catch (error) {
49
- if (isUniqueViolation(error)) {
50
- throw new Error(`developer grant "${grant.id}" already exists`, { cause: error });
51
- }
52
- throw error;
53
- }
68
+ const raced = await this.getActive({
69
+ clientId: grant.clientId,
70
+ subject: grant.subject,
71
+ resource: grant.resource,
72
+ at: grant.createdAt,
73
+ });
74
+ if (raced !== undefined)
75
+ return raced;
76
+ throw new Error(`developer grant "${grant.id}" already exists`);
77
+ }
78
+ async getActive(input) {
79
+ const at = normalizeDeveloperGrantTimestamp('authorization time', input.at ?? new Date().toISOString());
80
+ const { rows } = await this.#pool.query(`SELECT * FROM developer_access_grants
81
+ WHERE grant_version = 2
82
+ AND access_model = 'live_user'
83
+ AND client_id = $1
84
+ AND subject = $2
85
+ AND resource = $3
86
+ AND revoked_at IS NULL
87
+ AND (expires_at IS NULL OR expires_at > $4::timestamptz)
88
+ ORDER BY created_at DESC
89
+ LIMIT 1`, [input.clientId, input.subject, input.resource, at]);
90
+ return rows[0] === undefined ? undefined : grantFromRow(rows[0]);
54
91
  }
55
92
  async get(id) {
56
- const { rows } = await this.#pool.query('SELECT * FROM developer_access_grants WHERE id = $1', [
57
- id,
58
- ]);
93
+ const { rows } = await this.#pool.query(`SELECT * FROM developer_access_grants
94
+ WHERE id = $1 AND grant_version = 2 AND access_model = 'live_user'`, [id]);
59
95
  return rows[0] === undefined ? undefined : grantFromRow(rows[0]);
60
96
  }
61
97
  async revoke(id, at) {
@@ -63,7 +99,7 @@ export class PostgresDeveloperGrantStore {
63
99
  const { rows } = await this.#pool.query(`UPDATE developer_access_grants
64
100
  SET updated_at = CASE WHEN revoked_at IS NULL THEN $2::timestamptz ELSE updated_at END,
65
101
  revoked_at = COALESCE(revoked_at, $2::timestamptz)
66
- WHERE id = $1
102
+ WHERE id = $1 AND grant_version = 2 AND access_model = 'live_user'
67
103
  RETURNING *`, [id, revokedAt]);
68
104
  return rows[0] === undefined ? undefined : grantFromRow(rows[0]);
69
105
  }
@@ -71,11 +107,12 @@ export class PostgresDeveloperGrantStore {
71
107
  function grantFromRow(value) {
72
108
  const row = developerGrantRowSchema.parse(value);
73
109
  return normalizeDeveloperAccessGrant({
110
+ version: 2,
74
111
  id: row.id,
75
112
  clientId: row.client_id,
76
113
  subject: row.subject,
77
- org: row.org_slug,
78
- environments: row.environments,
114
+ resource: row.resource,
115
+ accessModel: row.access_model,
79
116
  capabilities: row.capabilities,
80
117
  createdAt: row.created_at.toISOString(),
81
118
  updatedAt: row.updated_at.toISOString(),
@@ -83,7 +120,4 @@ function grantFromRow(value) {
83
120
  ...(row.revoked_at === null ? {} : { revokedAt: row.revoked_at.toISOString() }),
84
121
  });
85
122
  }
86
- function isUniqueViolation(error) {
87
- return typeof error === 'object' && error !== null && 'code' in error && error.code === '23505';
88
- }
89
123
  //# sourceMappingURL=developer-grant-store-postgres.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"developer-grant-store-postgres.js","sourceRoot":"","sources":["../../src/oauth/developer-grant-store-postgres.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"developer-grant-store-postgres.js","sourceRoot":"","sources":["../../src/oauth/developer-grant-store-postgres.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,13 @@
1
1
  import { type DeveloperCapability } from '@noodle-borg/developer-mcp';
2
+ export declare const DEVELOPER_GRANT_VERSION: 2;
3
+ export declare const DEVELOPER_GRANT_ACCESS_MODEL: "live_user";
2
4
  export interface DeveloperAccessGrant {
5
+ readonly version: typeof DEVELOPER_GRANT_VERSION;
3
6
  readonly id: string;
4
7
  readonly clientId: string;
5
8
  readonly subject: string;
6
- readonly org: string;
7
- readonly environments: readonly string[];
9
+ readonly resource: string;
10
+ readonly accessModel: typeof DEVELOPER_GRANT_ACCESS_MODEL;
8
11
  readonly capabilities: readonly DeveloperCapability[];
9
12
  readonly createdAt: string;
10
13
  readonly updatedAt: string;
@@ -14,19 +17,26 @@ export interface DeveloperAccessGrant {
14
17
  export interface CreateDeveloperAccessGrant {
15
18
  readonly clientId: string;
16
19
  readonly subject: string;
17
- readonly org: string;
18
- readonly environments: readonly string[];
20
+ readonly resource: string;
19
21
  readonly capabilities: readonly DeveloperCapability[];
20
22
  readonly expiresAt?: string;
21
23
  }
24
+ export interface ActiveDeveloperGrantLookup {
25
+ readonly clientId: string;
26
+ readonly subject: string;
27
+ readonly resource: string;
28
+ readonly at?: string;
29
+ }
22
30
  export interface DeveloperGrantStore {
23
- create(input: CreateDeveloperAccessGrant): Promise<DeveloperAccessGrant>;
31
+ getOrCreateActive(input: CreateDeveloperAccessGrant): Promise<DeveloperAccessGrant>;
32
+ getActive(input: ActiveDeveloperGrantLookup): Promise<DeveloperAccessGrant | undefined>;
24
33
  get(id: string): Promise<DeveloperAccessGrant | undefined>;
25
34
  revoke(id: string, at: string): Promise<DeveloperAccessGrant | undefined>;
26
35
  }
27
36
  export interface ActiveDeveloperGrantInput {
28
37
  readonly subject: string;
29
38
  readonly clientId: string;
39
+ readonly resource: string;
30
40
  readonly at: string;
31
41
  }
32
42
  export interface DeveloperGrantFactoryOptions {
@@ -37,7 +47,8 @@ export type InMemoryDeveloperGrantStoreOptions = DeveloperGrantFactoryOptions;
37
47
  export declare class InMemoryDeveloperGrantStore implements DeveloperGrantStore {
38
48
  #private;
39
49
  constructor(options?: InMemoryDeveloperGrantStoreOptions);
40
- create(input: CreateDeveloperAccessGrant): Promise<DeveloperAccessGrant>;
50
+ getOrCreateActive(input: CreateDeveloperAccessGrant): Promise<DeveloperAccessGrant>;
51
+ getActive(input: ActiveDeveloperGrantLookup): Promise<DeveloperAccessGrant | undefined>;
41
52
  get(id: string): Promise<DeveloperAccessGrant | undefined>;
42
53
  revoke(id: string, at: string): Promise<DeveloperAccessGrant | undefined>;
43
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"developer-grant.d.ts","sourceRoot":"","sources":["../../src/oauth/developer-grant.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,mBAAmB,EAAyB,MAAM,4BAA4B,CAAC;AAI7F,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACtD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACtD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACzE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAC;IAC3D,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAC;CAC3E;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,kCAAkC,GAAG,4BAA4B,CAAC;AAE9E,qBAAa,2BAA4B,YAAW,mBAAmB;;gBAKzD,OAAO,GAAE,kCAAuC;IAKtD,MAAM,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,oBAAoB,CAAC;IASxE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAK1D,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;CAahF;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAQT;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,0BAA0B,EACjC,OAAO,GAAE,4BAAiC,GACzC,oBAAoB,CAgBtB;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,oBAAoB,GAAG,oBAAoB,CAkC/F;AAUD,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIrF"}
1
+ {"version":3,"file":"developer-grant.d.ts","sourceRoot":"","sources":["../../src/oauth/developer-grant.ts"],"names":[],"mappings":"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"}