@sanity/runtime-cli 12.0.1 → 12.2.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 (67) hide show
  1. package/README.md +25 -24
  2. package/dist/actions/blueprints/blueprint.d.ts +5 -4
  3. package/dist/actions/blueprints/config.d.ts +7 -6
  4. package/dist/actions/blueprints/config.js +8 -6
  5. package/dist/actions/blueprints/stacks.d.ts +8 -4
  6. package/dist/actions/blueprints/stacks.js +6 -32
  7. package/dist/commands/blueprints/destroy.js +2 -0
  8. package/dist/commands/blueprints/doctor.d.ts +1 -0
  9. package/dist/commands/blueprints/doctor.js +4 -0
  10. package/dist/commands/blueprints/info.js +1 -1
  11. package/dist/commands/blueprints/init.js +1 -1
  12. package/dist/commands/blueprints/stacks.js +1 -1
  13. package/dist/commands/functions/dev.d.ts +2 -2
  14. package/dist/commands/functions/dev.js +3 -2
  15. package/dist/config.js +12 -2
  16. package/dist/constants.d.ts +7 -0
  17. package/dist/constants.js +7 -0
  18. package/dist/cores/blueprints/config.js +36 -39
  19. package/dist/cores/blueprints/doctor.d.ts +1 -0
  20. package/dist/cores/blueprints/doctor.js +36 -5
  21. package/dist/cores/blueprints/info.js +2 -2
  22. package/dist/cores/blueprints/init.d.ts +2 -0
  23. package/dist/cores/blueprints/init.js +38 -14
  24. package/dist/cores/functions/env/add.js +2 -2
  25. package/dist/cores/functions/env/list.js +2 -2
  26. package/dist/cores/functions/env/remove.js +2 -2
  27. package/dist/cores/functions/logs.js +2 -2
  28. package/dist/cores/functions/test.js +31 -23
  29. package/dist/server/app.js +32 -21
  30. package/dist/server/handlers/invoke.d.ts +2 -2
  31. package/dist/server/handlers/invoke.js +2 -2
  32. package/dist/server/static/components/api-base.js +3 -0
  33. package/dist/server/static/components/app.css +120 -95
  34. package/dist/server/static/components/clear-button.js +1 -1
  35. package/dist/server/static/components/console-panel.js +6 -6
  36. package/dist/server/static/components/fetch-button.js +1 -1
  37. package/dist/server/static/components/filter-api-version.js +3 -3
  38. package/dist/server/static/components/filter-document-id.js +5 -5
  39. package/dist/server/static/components/filter-with-token.js +4 -4
  40. package/dist/server/static/components/filters.js +2 -2
  41. package/dist/server/static/components/function-list.js +14 -5
  42. package/dist/server/static/components/help-button.js +4 -1
  43. package/dist/server/static/components/payload-panel.js +9 -9
  44. package/dist/server/static/components/response-panel.js +8 -8
  45. package/dist/server/static/components/rule-panel.js +4 -4
  46. package/dist/server/static/components/run-panel.js +4 -4
  47. package/dist/server/static/components/select-dropdown.js +5 -25
  48. package/dist/server/static/index.html +9 -9
  49. package/dist/server/static/vendor/m-.css +1 -0
  50. package/dist/server/static/vendor/m-.woff2 +0 -0
  51. package/dist/utils/display/blueprints-formatting.d.ts +3 -2
  52. package/dist/utils/display/blueprints-formatting.js +102 -50
  53. package/dist/utils/display/presenters.d.ts +1 -0
  54. package/dist/utils/display/presenters.js +3 -0
  55. package/dist/utils/display/prompt.js +10 -9
  56. package/dist/utils/display/resources-formatting.d.ts +6 -2
  57. package/dist/utils/display/resources-formatting.js +71 -17
  58. package/dist/utils/find-function.d.ts +2 -2
  59. package/dist/utils/find-function.js +9 -2
  60. package/dist/utils/invoke-local.d.ts +2 -2
  61. package/dist/utils/invoke-local.js +27 -16
  62. package/dist/utils/types.d.ts +46 -22
  63. package/dist/utils/types.js +25 -2
  64. package/dist/utils/validate/resource.js +144 -23
  65. package/dist/utils/validated-token.js +1 -1
  66. package/oclif.manifest.json +23 -4
  67. package/package.json +7 -4
@@ -2,38 +2,18 @@
2
2
  import {ApiBaseElement} from './api-base.js'
3
3
 
4
4
  const dropdownTemplate = ({label}) => `
5
- <fieldset class="mar-t-sm">
5
+ <fieldset class="mar-t-2">
6
6
  <label class="slab-text">
7
- <span style="display: block; margin-bottom: var(--space-1);">${label}</span>
8
- <div data-ui="Select" style="position: relative; display: inline-block; width: 100%;">
7
+ <span class="block mar-b-1">${label}</span>
8
+ <div data-ui="Select" class="relative inline-block w-100">
9
9
  <select
10
10
  data-ui="Select"
11
- style="
12
- width: 100%;
13
- appearance: none;
14
- -webkit-appearance: none;
15
- -moz-appearance: none;
16
- background: transparent;
17
- color: light-dark(var(--gray-950), var(--gray-300));
18
- padding-right: 2rem;
19
- border: 1px solid var(--gray-400);
20
- border-radius: var(--radius-2);
21
- height: var(--input-height, 2.5rem);
22
- "
11
+ class="w-100 appearance-none transparent component-color dropdown-template"
23
12
  ></select>
24
13
  <div
25
14
  data-as="div"
26
15
  data-ui="Box"
27
- style="
28
- position: absolute;
29
- top: 50%;
30
- right: 0.4rem;
31
- transform: translateY(-50%);
32
- pointer-events: none;
33
- display: flex;
34
- align-items: center;
35
- height: 100%;
36
- "
16
+ class="flex items-center h-100 dropdown-template-div"
37
17
  >
38
18
  <svg
39
19
  data-sanity-icon="chevron-down"
@@ -3,8 +3,8 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <title>Sanity Functions</title>
6
- <link href="https://unpkg.com/m-@3.2.0/dist/m-.woff2" rel="preload" as="font" crossorigin>
7
- <link href="https://unpkg.com/m-@3.2.0/dist/m-.css" rel="stylesheet">
6
+ <link href="./vendor/m-.woff2" rel="preload" as="font" crossorigin>
7
+ <link href="./vendor/m-.css" rel="stylesheet">
8
8
  <link href="./components/app.css" rel="stylesheet">
9
9
  <link rel="icon" type="image/svg+xml" href="favicon.svg" media="(prefers-color-scheme: light)">
10
10
  <link rel="icon" type="image/svg+xml" href="favicon-dark.svg" media="(prefers-color-scheme: dark)">
@@ -12,7 +12,7 @@
12
12
  </head>
13
13
  <body>
14
14
  <header data-slot="header">
15
- <div class="logo pad-sm">
15
+ <div class="flex items-center gap-25 pad-2">
16
16
  <div class="logo-image">
17
17
  <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 400 400" fill="none">
18
18
  <rect width="400" height="400" fill="light-dark(#0B0B0B, #FFFFFF)"/>
@@ -26,17 +26,17 @@
26
26
  </defs>
27
27
  </svg>
28
28
  </div>
29
- <span class="logo-text pad-xs">Functions</span>
29
+ <span class="logo-text pad-1">Functions</span>
30
30
  </div>
31
31
  </header>
32
32
  <filters-component></filters-component>
33
- <input type="checkbox" id="nav-toggle" style="display: none;">
34
- <nav id="sidebar" style="padding-top: var(--size-5); border-right: 1px solid var(--card-border-color);max-height: 100%; overflow-y: scroll; overflow: auto; min-width: 200px; position: relative;">
35
- <label for="nav-toggle" id="nav-toggle-label" title="Toggle Functions list" style="position: absolute; top: var(--space-2); right: var(--space-3); cursor: pointer; padding: 4px; border-radius: 2px; background: var(--color-surface-subtle); border: 1px solid var(--color-border-default); z-index: 10;"></label>
36
- <h4 class="config-label mar-t-0" style="padding-left: var(--space-3); margin-bottom:var(--space-3);">Functions</h4>
33
+ <input type="checkbox" id="nav-toggle" class="hidden">
34
+ <nav id="sidebar" class="relative y-scroll max-h-100 pad-t-5 border-right overflow-auto nav-min-width">
35
+ <label for="nav-toggle" id="nav-toggle-label" title="Toggle Functions list" class="z-10 nav-label"></label>
36
+ <h4 class="config-label mar-t-0 mar-b-3 pad-l-3">Functions</h4>
37
37
  <function-list></function-list>
38
38
  </nav>
39
- <main id="main-content" style='max-height: 100%; overflow: hidden;'>
39
+ <main id="main-content" class="max-h-100 overflow-hidden">
40
40
  <payload-panel></payload-panel>
41
41
  <div>
42
42
  <rule-panel></rule-panel>
@@ -0,0 +1 @@
1
+ :root{--m-color-gray-1:#f8f8f8;--m-color-gray-2:#ededed;--m-color-gray-3:#ccc;--m-color-gray-4:#9c9c9c;--m-color-gray-5:#838383;--m-color-gray-6:#6e6e6e;--m-color-gray-7:#404040;--m-color-gray-8:#333;--m-color-gray-9:#282828;--m-color-blue-1:#d8ebfe;--m-color-blue-2:#6990ee;--m-color-blue-3:#494eaa;--m-color-red-1:#fce2de;--m-color-red-2:#eb6176;--m-color-red-3:#a2204f;--m-color-green-1:#ccf3ca;--m-color-green-2:#26a573;--m-color-green-3:#146146;--m-color-orange-1:#f6e5bb;--m-color-orange-2:#e36f4f;--m-color-orange-3:#963712;--m-color-disabled-fg:var(--m-color-gray-4);--m-color-disabled-bg:var(--m-color-gray-1);--m-color-focus:var(--m-color-blue-1);--m-color-primary-action:#1a73e8;--m-color-primary-bg:white;--m-color-border:var(--m-color-gray-2);--m-border-radius-1:2px;--m-border-radius-2:4px;--m-border-radius-3:6px;--m-border-radius-4:8px;--m-border-radius-full:9999px;--m-max-content-width:1320px;--m-input-min-height:34px;--m-target-size:var(--m-space-9);--m-target-min-size:var(--m-space-6);--m-space-1:4px;--m-space-2:8px;--m-space-3:12px;--m-space-4:16px;--m-space-5:20px;--m-space-6:24px;--m-space-7:28px;--m-space-8:32px;--m-space-9:36px;--m-space-10:40px;--m-space-11:44px;--m-space-12:48px;--m-space-13:52px;--m-space-14:56px;--m-breakpoint-sm:440px;--m-breakpoint-md:900px;--m-breakpoint-lg:901px;--m-font-size-min:13px;--m-font-size-default:16px;--m-font-size-md:18px;--m-font-size-lg:24px;--m-font-size-xl:32px;--m-shadow-color:0,0,0;--m-shadow-1:0 0 2px rgba(var(--m-shadow-color),.1);--m-shadow-2:0 0 4px rgba(var(--m-shadow-color),.2)}*{box-sizing:border-box}[hidden]{display:none!important}h1{font-size:2em}body{color:var(--m-color-gray-8);height:100vh;margin:0;font-family:Untitled Sans,-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif}:is(button,a[role=button]){&[ord]{justify-content:center;align-items:center;gap:var(--m-space-2);border-radius:var(--m-border-radius-3);cursor:pointer;font-size:var(--m-font-size-md);height:var(--m-target-size);padding:var(--m-space-2)var(--m-space-3);background:0 0;border:2px solid;line-height:1.4;display:inline-flex;&[disabled]{cursor:not-allowed;border-color:var(--m-color-gray-3);color:var(--m-color-disabled-fg);background-color:var(--m-color-disabled-bg)}&[controlsize=sm]{height:var(--m-target-min-size);font-size:var(--m-font-size-min);padding:var(--m-space-2);font-weight:500}&[controlsize=lg]{height:var(--m-space-12);font-size:var(--m-font-size-lg)}& m-icon{font-size:140%}}&[ord=primary]{border-color:var(--m-color-primary-action);background-color:var(--m-color-primary-action);color:#fff}&[ord=secondary]{border-color:var(--m-color-primary-action);color:var(--m-color-primary-action);&[aria-pressed=true],&[aria-pressed=mixed]{background-color:var(--m-color-blue-1)}}&[ord=tertiary]{border-color:var(--m-color-gray-7);color:var(--m-color-gray-7);&[aria-pressed=true],&[aria-pressed=mixed]{background-color:var(--m-color-gray-3)}}&:focus-visible{outline:3px solid var(--m-color-focus)}}a[role=button][ord]{&:hover{text-decoration:none}}[role=group]:has(:is(button,a[role=button])){grid-auto-flow:column;display:inline-grid;@media (width<=600px){&{grid-auto-flow:row;display:grid}}& button,& a[role=button]{&:not(:only-child){border-radius:0;@media (width>=601px){&{border-left-width:1px;border-right-width:1px}&:first-of-type{border-radius:var(--m-border-radius-3)0 0 var(--m-border-radius-3);border-left-width:2px}&:last-of-type{border-radius:0 var(--m-border-radius-3)var(--m-border-radius-3)0;border-right-width:2px}}@media (width<=600px){&{border-top-width:1px;border-bottom-width:1px}&:first-of-type{border-radius:var(--m-border-radius-3)var(--m-border-radius-3)0 0;border-top-width:2px}&:last-of-type{border-radius:0 0 var(--m-border-radius-3)var(--m-border-radius-3);border-bottom-width:2px}}}}}code,pre{border-radius:var(--m-border-radius-4);color:var(--m-color-red-3)}code{background-color:var(--m-color-gray-2);padding:1px 3px}pre{margin:var(--m-space-3)0;background-color:#fff;& code{background-color:inherit;display:block;overflow:auto;padding:var(--m-space-3)!important}}fieldset{border:none;margin:0;padding:0;position:relative;&+:is(&,button[ord],a[role=button]){margin-top:var(--m-space-4)}& input:not([type=radio]):not([type=checkbox]),& :is(label,select){display:block}& input+label{display:inline}& :is(label,legend){padding:0;font-weight:500}& :is(input[type=radio],input[type=checkbox])+label{font-weight:400}& input:not([type=radio],[type=checkbox],[type=range]),& :is(select,textarea){min-height:var(--m-input-min-height);color:var(--m-color-gray-8);background-color:#fff;border-radius:0;width:100%;padding:6px;font-size:16px}& :is(input:not([role=switch]),select,textarea){border:1px solid var(--m-color-gray-3)}& select:not([multiple]){-webkit-appearance:none;appearance:none;padding-right:var(--m-space-7);background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' height='10px' width='22px'%3E%3Ctext x='0' y='10' fill='gray'%3E%E2%96%BE%3C/text%3E%3C/svg%3E");background-position:100%;background-repeat:no-repeat}& textarea{resize:vertical;font-family:inherit}& input[type=range]{-webkit-appearance:none;appearance:none;margin:var(--m-space-3)0;height:var(--m-space-1);background-color:var(--m-color-gray-3);border-radius:var(--m-border-radius-full);outline:0;width:100%;&::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:var(--m-space-5);height:var(--m-space-5);border:1px solid var(--m-color-gray-4);border-radius:var(--m-border-radius-full);background-color:#fff;&:focus-visible{outline:2px solid var(--m-color-focus)}}}& :is(label,legend)+:is(input,select,textarea){margin-top:var(--m-space-1)}& :is(input,select,textarea,small){&+&{margin-top:var(--m-space-2)}}& input:not([type=range]):not([role=switch]),& :is(select,textarea){&:focus{outline:3px solid var(--m-color-focus);outline-offset:0;border:1px solid var(--m-color-primary-action)}}& :is(input,select,textarea){&:user-invalid{border-color:var(--m-color-red-3);&~small{color:var(--m-color-red-3)}}&~small{color:var(--m-color-gray-6)}}}kbd{font-family:system-ui;&:not(:has(kbd)),& kbd{box-shadow:0 1px 2px 0 var(--m-color-gray-5);background:#fff;border-radius:3px;padding:0 4px}}a,span[role=link]{color:var(--m-color-primary-action);cursor:pointer;text-decoration:none;&:hover,&:focus-visible{outline:0;text-decoration:underline}&[disabled]{color:var(--m-color-disabled-fg);pointer-events:none}}ul,ol,dl{margin:0}ul,ol{padding-left:var(--m-space-5)}ul[type=none]{padding-left:0;list-style:none}dd{margin-inline-start:0}dl{&>dt{margin-top:var(--m-space-3);text-transform:uppercase;font-size:var(--m-font-size-min);font-weight:700;&:first-of-type{margin-top:0}}}:is(ul,ol)[type=content]{padding-left:0;list-style:none;&>li:not(:last-of-type){border-bottom:1px solid var(--m-color-border)}}table{border-collapse:collapse;width:100%;& caption{&:not([side=end]){margin-bottom:var(--m-space-2)}&[side=end]{margin-top:var(--m-space-2);caption-side:bottom}}& thead{&>tr{border-top:2px solid var(--m-color-gray-3)}& th{text-align:left;&[aria-sort] button{all:unset;cursor:pointer;align-items:center;display:inline-flex;&:after{padding-left:var(--m-space-1);font-size:.8em}}&[aria-sort=ascending] button:after{content:"↑"}&[aria-sort=descending] button:after{content:"↓"}}}& th,& td{padding:var(--m-space-2);vertical-align:top}& tbody>tr{border-bottom:1px solid var(--m-color-gray-3);&:first-of-type{border-top:1px solid var(--m-color-gray-3)}}&[layout=fixed]{table-layout:fixed}&[striped]>tbody tr:nth-of-type(odd){background-color:var(--m-color-gray-2)}}meter{height:var(--m-space-3);width:100%;display:block}m-accordion{--icon:"expand_more";display:block;&[icon]{--icon:attr(icon)}&>details{border-top:3px solid var(--m-color-gray-2);&:last-child{border-bottom:3px solid var(--m-color-gray-2)}&[open]>summary:after{transition:transform .25s;transform:rotate(180deg)}&>summary{padding:var(--m-space-3)var(--m-space-12)var(--m-space-3)var(--m-space-3);position:relative;&:focus-visible{outline:2px solid var(--m-color-focus)}&:after{content:var(--icon);top:var(--m-space-3);right:var(--m-space-3);font-family:m-icons;font-size:20px;line-height:1;transition:transform .25s;position:absolute;transform:rotate(0)}}}}m-alert{--color:var(--m-color-gray-7);--bg-color:var(--m-color-gray-2);padding:var(--m-space-5);color:var(--color);background-color:var(--bg-color);border-radius:var(--m-border-radius-3);align-items:center;min-height:60px;display:flex;&+&{margin-top:var(--m-space-2)}&[icon]:before{content:attr(icon);font-family:m-icons;font-size:var(--m-font-size-lg);margin-right:var(--m-space-3);line-height:1}& button[slot=close]{all:unset;box-sizing:border-box;cursor:pointer;font-size:var(--m-font-size-default);border-radius:var(--m-border-radius-full);padding:var(--m-space-2);width:var(--m-target-min-size);height:var(--m-target-min-size);place-content:center;margin-left:auto;line-height:1;display:inline-grid;&:before{content:"✕"}&:hover{background-color:rgb(from var(--color)r g b/.1)}}&[type=info]{--color:var(--m-color-blue-3);--bg-color:var(--m-color-blue-1)}&[type=success]{--color:var(--m-color-green-3);--bg-color:var(--m-color-green-1)}&[type=warn]{--color:var(--m-color-orange-3);--bg-color:var(--m-color-orange-1)}&[type=error]{--color:var(--m-color-red-3);--bg-color:var(--m-color-red-1)}}m-badge{color:#fff;background-color:var(--m-color-primary-action);font-size:var(--m-font-size-min);border-radius:.625rem;place-items:center;min-width:1.25rem;height:1.25rem;line-height:1.05rem;display:none;&:not([count]){padding:0 var(--m-space-2)}&[count]:before{content:attr(count);padding:0 var(--m-space-2)}&:not(:empty),&[count]:not([count=""]):not([count="0"]){display:inline-grid}}m-card{border-radius:var(--m-border-radius-2);padding:var(--m-space-5);border:1px solid var(--m-color-border);background-color:#fff;display:block;overflow:hidden;&[ord=secondary]{background-color:var(--m-color-gray-1);box-shadow:var(--m-shadow-1);border:none}&+&{margin-top:var(--m-space-3)}}@media only screen and (width<=600px){m-card{padding:var(--m-space-3)}}m-breadcrumb,m-breadcrumb>nav{display:flex}m-breadcrumb>nav>:is(a,m-crumb,span):not(:first-child):before{content:"/";margin:0 var(--m-space-3);color:var(--m-color-gray-4);display:inline-block}details{&>summary{cursor:pointer;list-style:none;&:focus{outline:none}&::-webkit-details-marker{display:none}}}dialog{padding:var(--m-space-7);box-shadow:0 12px 18px -3px rgb(from var(--m-color-gray-7)r g b/.1);background-color:#f5f3f7;border:none;& button[slot=close]{all:unset;top:var(--m-space-1);right:var(--m-space-1);width:var(--m-target-min-size);height:var(--m-target-min-size);cursor:pointer;border-radius:var(--m-border-radius-full);place-content:center;display:inline-grid;position:absolute;&:before{content:"✕"}&:hover{background-color:rgb(from var(--m-color-gray-7)r g b/.1)}}}m-dot{align-items:center;display:inline-flex;&:before{content:"";margin:var(--m-space-1);border-radius:var(--m-border-radius-full);background-color:var(--m-color-gray-4);width:8px;height:8px}&[type=info]:before{background-color:var(--m-color-blue-2)}&[type=success]:before{background-color:var(--m-color-green-2)}&[type=warn]:before{background-color:var(--m-color-orange-2)}&[type=error]:before{background-color:var(--m-color-red-2)}}m-container{max-width:var(--m-max-content-width);padding:var(--m-space-5)var(--m-space-7);margin:auto;display:block;&[maxwidth=md]{max-width:924px}&[maxwidth=sm]{max-width:375px}&[maxwidth=none]{max-width:none}}@media only screen and (width<=600px){m-container{padding:var(--m-space-3)}}@font-face{font-family:m-icons;font-style:normal;font-weight:400;src:url(./m-.woff2)format("woff2")}m-icon{display:inline-flex;&:before{content:attr(name);-webkit-font-smoothing:antialiased;font-family:m-icons}&[fill]:before{font-variation-settings:"FILL" 1}}m-menu{display:inline-block;position:relative;&>[slot=trigger]{cursor:pointer}&>[slot=items]{transform:translateY(var(--m-space-1));border:1px solid var(--m-color-gray-4);border-radius:var(--m-border-radius-2);z-index:3000;background-color:#fff;width:max-content;display:none;position:absolute;&>a{padding:var(--m-space-2)var(--m-space-3);display:block}}&[open]>[slot=items]{display:block}}m-tabs{align-items:flex-start;display:flex;&[scrollable]{scrollbar-width:none;overflow-x:scroll;&::-webkit-scrollbar{display:none}}&>:is(a,button){all:unset;color:var(--m-color-gray-7);text-align:center;white-space:nowrap;padding:var(--m-space-2)var(--m-space-6);cursor:pointer;font-weight:700;display:inline-flex;&:focus-visible{outline:2px solid var(--m-color-focus)}&:not([disabled]):not([aria-selected=true]):hover{border-bottom:2px solid var(--m-color-gray-3);text-decoration:none}&[aria-selected=true]{border-bottom:2px solid var(--m-color-primary-action)}&[disabled]{color:var(--m-color-disabled-fg);cursor:default}}}m-tag{--color:#585858;vertical-align:top;align-items:center;gap:var(--m-space-1);color:var(--color);background-color:oklch(from var(--color)calc(l*2)c h);padding:var(--m-space-1)var(--m-space-2);font-size:var(--m-font-size-min);border-radius:var(--m-border-radius-2);display:inline-flex;position:relative;&+&{margin-left:var(--m-space-1)}&:has(button[slot=close]){padding-right:var(--m-space-7)}& button[slot=close]{all:unset;right:var(--m-space-1);cursor:pointer;font-size:var(--m-font-size-min);border-radius:var(--m-border-radius-full);width:var(--m-space-4);height:var(--m-space-4);place-content:center;padding:1px;line-height:1;display:inline-grid;position:absolute;&:before{content:"✕"}&:hover{background-color:rgb(from var(--color)r g b/.1)}}}progress:indeterminate{-webkit-appearance:none;appearance:none;place-items:center;width:auto;display:inline-flex;&:before{content:"autorenew";-webkit-font-smoothing:antialiased;font-family:m-icons;animation:1.2s linear infinite m-loader}}@keyframes m-loader{0%{transform:rotate(0)}to{transform:rotate(360deg)}}hr{background-color:var(--m-color-gray-3);border:none;height:1px;margin:0;&[aria-orientation=vertical]{width:1.5px;height:auto}}input[type=checkbox][role=switch]{width:var(--m-space-10);-webkit-appearance:none;appearance:none;border-radius:var(--m-border-radius-full);cursor:pointer;background-color:var(--m-color-gray-3);height:22px;margin:0;transition:background-color .12s ease-in;position:relative;&:before{content:"";width:var(--m-space-4);height:var(--m-space-4);border-radius:var(--m-border-radius-full);background-color:#fff;transition:all .12s ease-in;position:absolute;top:3px;left:3px}&:focus-visible{outline:2px solid var(--m-color-focus);outline-offset:0}&:checked{background-color:var(--m-color-primary-action)}&:checked:before{left:20px}&:disabled{cursor:not-allowed;background-color:var(--m-color-disabled-bg)}}h1,h2,h3,h4,h5,h6,p{margin:0}blockquote{color:var(--m-color-gray-6);font-style:italic}.all-unset{all:unset}.pad-0{padding:0}.pad-1{padding:var(--m-space-1)}.pad-2{padding:var(--m-space-2)}.pad-3{padding:var(--m-space-3)}.pad-4{padding:var(--m-space-4)}.pad-5{padding:var(--m-space-5)}.pad-6{padding:var(--m-space-6)}.pad-7{padding:var(--m-space-7)}.pad-8{padding:var(--m-space-8)}.pad-9{padding:var(--m-space-9)}.pad-10{padding:var(--m-space-10)}.pad-11{padding:var(--m-space-11)}.pad-12{padding:var(--m-space-12)}.pad-13{padding:var(--m-space-13)}.pad-14{padding:var(--m-space-14)}.pad-t-0{padding-top:0}.pad-t-1{padding-top:var(--m-space-1)}.pad-t-2{padding-top:var(--m-space-2)}.pad-t-3{padding-top:var(--m-space-3)}.pad-t-4{padding-top:var(--m-space-4)}.pad-t-5{padding-top:var(--m-space-5)}.pad-t-6{padding-top:var(--m-space-6)}.pad-t-7{padding-top:var(--m-space-7)}.pad-t-8{padding-top:var(--m-space-8)}.pad-t-9{padding-top:var(--m-space-9)}.pad-t-10{padding-top:var(--m-space-10)}.pad-t-11{padding-top:var(--m-space-11)}.pad-t-12{padding-top:var(--m-space-12)}.pad-t-13{padding-top:var(--m-space-13)}.pad-t-14{padding-top:var(--m-space-14)}.pad-r-0{padding-right:0}.pad-r-1{padding-right:var(--m-space-1)}.pad-r-2{padding-right:var(--m-space-2)}.pad-r-3{padding-right:var(--m-space-3)}.pad-r-4{padding-right:var(--m-space-4)}.pad-r-6{padding-right:var(--m-space-6)}.pad-r-8{padding-right:var(--m-space-8)}.pad-r-10{padding-right:var(--m-space-10)}.pad-r-12{padding-right:var(--m-space-12)}.pad-r-14{padding-right:var(--m-space-14)}.pad-b-0{padding-bottom:0}.pad-b-1{padding-bottom:var(--m-space-1)}.pad-b-2{padding-bottom:var(--m-space-2)}.pad-b-3{padding-bottom:var(--m-space-3)}.pad-b-4{padding-bottom:var(--m-space-4)}.pad-b-6{padding-bottom:var(--m-space-6)}.pad-b-7{padding-bottom:var(--m-space-7)}.pad-b-8{padding-bottom:var(--m-space-8)}.pad-b-10{padding-bottom:var(--m-space-10)}.pad-b-12{padding-bottom:var(--m-space-12)}.pad-b-14{padding-bottom:var(--m-space-14)}.pad-l-0{padding-left:0}.pad-l-1{padding-left:var(--m-space-1)}.pad-l-2{padding-left:var(--m-space-2)}.pad-l-3{padding-left:var(--m-space-3)}.pad-l-4{padding-left:var(--m-space-4)}.pad-l-5{padding-left:var(--m-space-5)}.pad-l-6{padding-left:var(--m-space-6)}.pad-l-7{padding-left:var(--m-space-7)}.pad-l-8{padding-left:var(--m-space-8)}.pad-l-10{padding-left:var(--m-space-10)}.pad-l-12{padding-left:var(--m-space-12)}.pad-l-14{padding-left:var(--m-space-14)}.mar-auto{margin:auto}.mar-t-auto{margin-top:auto}.mar-r-auto{margin-right:auto}.mar-b-auto{margin-bottom:auto}.mar-l-auto{margin-left:auto}.mar-0{margin:0}.mar-1{margin:var(--m-space-1)}.mar-2{margin:var(--m-space-2)}.mar-3{margin:var(--m-space-3)}.mar-4{margin:var(--m-space-4)}.mar-6{margin:var(--m-space-6)}.mar-8{margin:var(--m-space-8)}.mar-10{margin:var(--m-space-10)}.mar-12{margin:var(--m-space-12)}.mar-14{margin:var(--m-space-14)}.mar-t-0{margin-top:0}.mar-t-1{margin-top:var(--m-space-1)}.mar-t-2{margin-top:var(--m-space-2)}.mar-t-3{margin-top:var(--m-space-3)}.mar-t-4{margin-top:var(--m-space-4)}.mar-t-6{margin-top:var(--m-space-6)}.mar-t-8{margin-top:var(--m-space-8)}.mar-t-10{margin-top:var(--m-space-10)}.mar-t-12{margin-top:var(--m-space-12)}.mar-t-14{margin-top:var(--m-space-14)}.mar-r-0{margin-right:0}.mar-r-1{margin-right:var(--m-space-1)}.mar-r-2{margin-right:var(--m-space-2)}.mar-r-3{margin-right:var(--m-space-3)}.mar-r-4{margin-right:var(--m-space-4)}.mar-r-6{margin-right:var(--m-space-6)}.mar-r-8{margin-right:var(--m-space-8)}.mar-r-10{margin-right:var(--m-space-10)}.mar-r-12{margin-right:var(--m-space-12)}.mar-r-14{margin-right:var(--m-space-14)}.mar-b-0{margin-bottom:0}.mar-b-1{margin-bottom:var(--m-space-1)}.mar-b-2{margin-bottom:var(--m-space-2)}.mar-b-3{margin-bottom:var(--m-space-3)}.mar-b-4{margin-bottom:var(--m-space-4)}.mar-b-5{margin-bottom:var(--m-space-5)}.mar-b-6{margin-bottom:var(--m-space-6)}.mar-b-8{margin-bottom:var(--m-space-8)}.mar-b-10{margin-bottom:var(--m-space-10)}.mar-b-12{margin-bottom:var(--m-space-12)}.mar-b-14{margin-bottom:var(--m-space-14)}.mar-l-0{margin-left:0}.mar-l-1{margin-left:var(--m-space-1)}.mar-l-2{margin-left:var(--m-space-2)}.mar-l-3{margin-left:var(--m-space-3)}.mar-l-4{margin-left:var(--m-space-4)}.mar-l-6{margin-left:var(--m-space-6)}.mar-l-8{margin-left:var(--m-space-8)}.mar-l-10{margin-left:var(--m-space-10)}.mar-l-12{margin-left:var(--m-space-12)}.mar-l-14{margin-left:var(--m-space-14)}.gap-0{gap:0}.gap-1{gap:var(--m-space-1)}.gap-2{gap:var(--m-space-2)}.gap-3{gap:var(--m-space-3)}.gap-4{gap:var(--m-space-4)}.gap-6{gap:var(--m-space-6)}.gap-8{gap:var(--m-space-8)}.gap-10{gap:var(--m-space-10)}.gap-12{gap:var(--m-space-12)}.gap-14{gap:var(--m-space-14)}.font-bold{font-weight:700}.font-med{font-weight:500}.font-reg{font-weight:400}.font-light{font-weight:300}.font-normal{font-style:normal}.font-italic{font-style:italic}.font-mono{font-family:monospace}.txt-left{text-align:left}.txt-right{text-align:right}.txt-center{text-align:center}.txt-justify{text-align:justify}.txt-lower{text-transform:lowercase}.txt-upper{text-transform:uppercase}.txt-caps{text-transform:capitalize}.txt-space{letter-spacing:2px}.txt-truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.txt-nowrap{white-space:nowrap}.txt-break-all{word-break:break-all}.txt-break-word{word-break:break-word}.txt-maxlength{max-width:75ch}.txt-noselect{-webkit-user-select:none;user-select:none;cursor:default}.txt-xs{font-size:var(--m-font-size-min)}.txt-sm{font-size:var(--m-font-size-default)}.txt-md{font-size:var(--m-font-size-md)}.txt-lg{font-size:var(--m-font-size-lg)}.txt-xl{font-size:var(--m-font-size-xl)}.txt-xxl{font-size:100px}.txt-white{color:#fff}.txt-gray-1{color:var(--m-color-gray-1)}.txt-gray-2{color:var(--m-color-gray-2)}.txt-gray-3{color:var(--m-color-gray-3)}.txt-gray-4{color:var(--m-color-gray-4)}.txt-gray-5{color:var(--m-color-gray-5)}.txt-gray-6{color:var(--m-color-gray-6)}.txt-gray-7{color:var(--m-color-gray-7)}.txt-gray-8{color:var(--m-color-gray-8)}.txt-gray-9{color:var(--m-color-gray-9)}.txt-blue-1{color:var(--m-color-blue-1)}.txt-blue-2{color:var(--m-color-blue-2)}.txt-blue-3{color:var(--m-color-blue-3)}.txt-red-1{color:var(--m-color-red-1)}.txt-red-2{color:var(--m-color-red-2)}.txt-red-3{color:var(--m-color-red-3)}.txt-green-1{color:var(--m-color-green-1)}.txt-green-2{color:var(--m-color-green-2)}.txt-green-3{color:var(--m-color-green-3)}.txt-orange-1{color:var(--m-color-orange-1)}.txt-orange-2{color:var(--m-color-orange-2)}.txt-orange-3{color:var(--m-color-orange-3)}.txt-info{color:var(--m-color-blue-2)}.txt-success{color:var(--m-color-green-2)}.txt-warn{color:var(--m-color-orange-2)}.txt-error{color:var(--m-color-red-2)}.grid{display:grid}.inline-grid{display:inline-grid}.flex{display:flex}.inline-flex{display:inline-flex}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.hidden,.hide{display:none}@media (width<=576px){.sm\:hide{display:none}}@media (width>=576px){.sm\:hide{display:none}}@media (width>=992px){.lg\:hide{display:none}}.flex-110{&,&>*{flex:1 1 0}}.flex-grow-0{flex-grow:0}.flex-grow-1{flex-grow:1}.flex-shrink-0{flex-shrink:0}.flex-shrink-1{flex-shrink:1}.flex-basis-content{flex-basis:content}.flex-wrap{flex-wrap:wrap}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.justify-content-start{justify-content:flex-start}.justify-content-center{justify-content:center}.justify-content-end{justify-content:flex-end}.justify-content-between{justify-content:space-between}.justify-content-evenly{justify-content:space-evenly}.justify-content-around{justify-content:space-around}.align-items-start{align-items:flex-start}.align-items-center{align-items:center}.align-items-end{align-items:flex-end}.align-items-baseline{align-items:baseline}.align-self-stretch{align-self:stretch}.align-self-start{align-self:start}.align-self-center{align-self:center}.align-self-end{align-self:flex-end}.align-self-baseline{align-self:baseline}.place-content-center{place-content:center}.place-items-center{place-items:center}.grid-template-cols-fit{grid-template-columns:repeat(auto-fit,minmax(min(375px,100%),1fr))}.grid-template-cols-fill{grid-template-columns:repeat(auto-fill,minmax(min(400px,100%),1fr))}.grid-template-cols-subgrid{grid-template-columns:subgrid}.grid-flow-col{grid-auto-flow:column}.grid-flow-row{grid-auto-flow:row}.grid-flow-dense{grid-auto-flow:dense}.grid-auto-cols-max{grid-auto-columns:max-content}.grid-auto-cols-min{grid-auto-columns:min-content}.grid-auto-cols-fr{grid-auto-columns:minmax(0,1fr)}.left{float:left}.right{float:right}.clear{clear:both}.pos-absolute{position:absolute}.pos-fixed{position:fixed}.pos-relative{position:relative}.pos-static{position:static}.pos-sticky{position:sticky}.pos-t-0{top:0}.pos-r-0{right:0}.pos-b-0{bottom:0}.pos-l-0{left:0}.brd-none{border:none}.brd{border:1px solid var(--m-color-border)}.brd-t{border-top:1px solid var(--m-color-border)}.brd-r{border-right:1px solid var(--m-color-border)}.brd-b{border-bottom:1px solid var(--m-color-border)}.brd-l{border-left:1px solid var(--m-color-border)}.brd-radius-1{border-radius:var(--m-border-radius-1)}.brd-radius-2{border-radius:var(--m-border-radius-2)}.brd-radius-3{border-radius:var(--m-border-radius-3)}.brd-radius-4{border-radius:var(--m-border-radius-4)}.brd-radius-full{border-radius:var(--m-border-radius-full)}.brd-dashed{border-style:dashed}.brd-sm{border-width:1px}.brd-md{border-width:2px}.bg-clip-text{color:#0000;-webkit-background-clip:text;background-clip:text}.bg-cover{background-size:cover}.bg-contain{background-size:contain}.bg-white{background:#fff}.bg-gray-1{background:var(--m-color-gray-1)}.bg-gray-2{background:var(--m-color-gray-2)}.bg-gray-3{background:var(--m-color-gray-3)}.bg-gray-4{background:var(--m-color-gray-4)}.bg-gray-5{background:var(--m-color-gray-5)}.bg-gray-6{background:var(--m-color-gray-6)}.bg-gray-7{background:var(--m-color-gray-7)}.bg-gray-8{background:var(--m-color-gray-8)}.bg-gray-9{background:var(--m-color-gray-9)}.bg-blue-1{background:var(--m-color-blue-1)}.bg-blue-2{background:var(--m-color-blue-2)}.bg-blue-3{background:var(--m-color-blue-3)}.bg-red-1{background:var(--m-color-red-1)}.bg-red-2{background:var(--m-color-red-2)}.bg-red-3{background:var(--m-color-red-3)}.bg-green-1{background:var(--m-color-green-1)}.bg-green-2{background:var(--m-color-green-2)}.bg-green-3{background:var(--m-color-green-3)}.bg-orange-1{background:var(--m-color-orange-1)}.bg-orange-2{background:var(--m-color-orange-2)}.bg-orange-3{background:var(--m-color-orange-3)}.bg-info{background:var(--m-color-blue-2)}.bg-success{background:var(--m-color-green-2)}.bg-warn{background:var(--m-color-orange-2)}.bg-error{background:var(--m-color-red-2)}.width-full{width:100%}.width-half{width:50%}.width-min-0{min-width:0}.width-max{width:max-content}.width-min{width:min-content}.width-fit{width:fit-content}.height-full{height:100%}.height-half{height:50%}.height-min-0{min-height:0}.height-max{height:max-content}.height-min{height:min-content}.height-fit{height:fit-content}.obj-fit-cover{-o-object-fit:cover;object-fit:cover}.obj-fit-fill{-o-object-fit:fill;object-fit:fill}.obj-fit-contain{-o-object-fit:contain;object-fit:contain}.obj-fit-scale-down{-o-object-fit:scale-down;object-fit:scale-down}.pointer{cursor:pointer}.shadow{box-shadow:0 1px 4px #0000004d}.vis-hidden{visibility:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-clip{overflow:clip}.box-sizing-border{box-sizing:border-box}.box-sizing-content{box-sizing:content-box}.content-vis-auto{content-visibility:auto}
@@ -1,6 +1,7 @@
1
- import type { Blueprint } from '@sanity/blueprints-parser';
2
- import { type Resource, type Stack } from '../types.js';
1
+ import type { Blueprint, Resource } from '@sanity/blueprints-parser';
2
+ import { type DeployedResource, type Stack } from '../types.js';
3
3
  export declare function formatTitle(title: string, name: string): string;
4
+ export declare function formatDeployedResourceTree(resources: DeployedResource[] | undefined): string;
4
5
  export declare function formatResourceTree(resources: Resource[] | undefined): string;
5
6
  export declare function formatStackInfo(stack: Stack | Blueprint, isCurrentStack?: boolean): string;
6
7
  export declare function formatStacksListing(stacks: Stack[], currentStackId?: string): string;
@@ -1,71 +1,111 @@
1
1
  import { treeify } from 'array-treeify';
2
2
  import chalk from 'chalk';
3
- import { isLocalFunctionResource } from '../types.js';
3
+ import { SANITY_ACCESS_ROLE, SANITY_FUNCTION_DOCUMENT, SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_SCHEDULE, SANITY_PROJECT_CORS, SANITY_PROJECT_DATASET, SANITY_PROJECT_WEBHOOK, } from '../../constants.js';
4
+ import { isCorsOriginResource, isDatasetResource, isRoleResource, isWebhookResource, } from '../types.js';
4
5
  import { formatDate, formatDuration } from './dates.js';
5
6
  import { niceId } from './presenters.js';
6
- import { arraifyCors, arrayifyFunction } from './resources-formatting.js';
7
- export function formatTitle(title, name) {
8
- return `${chalk.bold.blue(title)} ${chalk.bold(`"${name}"`)}`;
9
- }
10
- export function formatResourceTree(resources) {
11
- if (!resources || resources.length === 0)
12
- return ' Zero resources';
13
- const output = [`${chalk.bold.underline('Resources')} [${resources.length}]`];
14
- const RESOURCE_CATEGORIES = [
15
- {
16
- label: 'Functions',
17
- match: isLocalFunctionResource,
18
- name: (res) => {
19
- const name = chalk.bold.green(res.displayName || res.name || 'unnamed');
20
- const ids = [
21
- 'id' in res && res.id ? `${niceId(res.id)}` : '',
22
- 'externalId' in res && res.externalId ? `<${niceId(res.externalId)}>` : '',
23
- ].join(' ');
24
- return `${name} ${ids}`;
25
- },
26
- formatDetails: arrayifyFunction,
7
+ import { arrayifyCors, arrayifyDataset, arrayifyFunction, arrayifyRole, arrayifyWebhook, } from './resources-formatting.js';
8
+ const functionCategory = {
9
+ label: 'Functions',
10
+ displayNameAttribute: 'displayName',
11
+ formatDetails: arrayifyFunction,
12
+ };
13
+ const RESOURCE_CATEGORIES = {
14
+ [SANITY_ACCESS_ROLE]: {
15
+ label: 'Roles',
16
+ displayNameAttribute: 'title',
17
+ formatDetails(res) {
18
+ return isRoleResource(res) ? arrayifyRole(res) : [];
27
19
  },
28
- {
29
- label: 'CORS Origins',
30
- match: (r) => r.type === 'sanity.project.cors',
31
- name: (res) => {
32
- const name = chalk.bold.yellow(res.displayName || res.name || 'unnamed');
33
- const ids = [
34
- 'id' in res && res.id ? `${niceId(res.id)}` : '',
35
- 'externalId' in res && res.externalId ? `<${niceId(res.externalId)}>` : '',
36
- ].join(' ');
37
- return `${name} ${ids}`;
38
- },
39
- formatDetails: arraifyCors,
20
+ },
21
+ [SANITY_FUNCTION_DOCUMENT]: functionCategory,
22
+ [SANITY_FUNCTION_MEDIA_LIBRARY_ASSET]: functionCategory,
23
+ [SANITY_FUNCTION_SCHEDULE]: functionCategory,
24
+ [SANITY_PROJECT_CORS]: {
25
+ label: 'CORS Origins',
26
+ formatDetails(res) {
27
+ return isCorsOriginResource(res) ? arrayifyCors(res) : [];
40
28
  },
29
+ },
30
+ [SANITY_PROJECT_DATASET]: {
31
+ label: 'Datasets',
32
+ displayNameAttribute: 'datasetName',
33
+ formatDetails(res) {
34
+ return isDatasetResource(res) ? arrayifyDataset(res) : [];
35
+ },
36
+ },
37
+ [SANITY_PROJECT_WEBHOOK]: {
38
+ label: 'Webhooks',
39
+ displayNameAttribute: 'displayName',
40
+ formatDetails(res) {
41
+ return isWebhookResource(res) ? arrayifyWebhook(res) : [];
42
+ },
43
+ },
44
+ };
45
+ const categoryByLabel = Object.values(RESOURCE_CATEGORIES).reduce((acc, curr) => {
46
+ acc[curr.label] = curr;
47
+ return acc;
48
+ }, {});
49
+ function resourceName(res, displayNameAttribute) {
50
+ const displayName = displayNameAttribute &&
51
+ displayNameAttribute in res &&
52
+ typeof res[displayNameAttribute] === 'string' &&
53
+ res[displayNameAttribute];
54
+ const name = displayName || res.name || 'unnamed';
55
+ return chalk.bold.green(name);
56
+ }
57
+ function deployedResourceName(res, displayNameAttribute) {
58
+ const displayName = displayNameAttribute &&
59
+ typeof res.parameters[displayNameAttribute] === 'string' &&
60
+ res.parameters[displayNameAttribute];
61
+ const name = displayName || res.name || 'unnamed';
62
+ const ids = idList(res).join(' ');
63
+ return `${chalk.bold.green(name)} ${ids}`;
64
+ }
65
+ function idList(res) {
66
+ return [
67
+ 'id' in res && typeof res.id === 'string' && res.id ? `${niceId(res.id)}` : '',
68
+ 'externalId' in res && typeof res.externalId === 'string' && res.externalId
69
+ ? `<${niceId(res.externalId)}>`
70
+ : '',
41
71
  ];
72
+ }
73
+ export function formatTitle(title, name) {
74
+ return `${chalk.bold.blue(title)} ${chalk.bold(`"${name}"`)}`;
75
+ }
76
+ function categorizeResources(resources) {
42
77
  const categorized = {};
43
- const matchedIndices = new Set();
44
- for (const [i, resource] of resources.entries()) {
45
- for (const cat of RESOURCE_CATEGORIES) {
46
- if (cat.match(resource)) {
47
- if (!categorized[cat.label])
48
- categorized[cat.label] = [];
49
- categorized[cat.label].push(resource);
50
- matchedIndices.add(i);
51
- break;
52
- }
78
+ const otherResources = [];
79
+ for (const resource of resources) {
80
+ const cat = RESOURCE_CATEGORIES[resource.type];
81
+ if (cat) {
82
+ if (!categorized[cat.label])
83
+ categorized[cat.label] = [];
84
+ categorized[cat.label].push(resource);
85
+ }
86
+ else {
87
+ otherResources.push(resource);
53
88
  }
54
89
  }
55
90
  // unmatched resources are 'Other Resources'
56
- const otherResources = resources.filter((_, i) => !matchedIndices.has(i));
57
91
  if (otherResources.length > 0) {
58
92
  categorized['Other Resources'] = otherResources;
59
93
  }
60
- for (const category of RESOURCE_CATEGORIES) {
94
+ return categorized;
95
+ }
96
+ function buildOutputTree(resources, name, mapToResource) {
97
+ const output = [`${chalk.bold.underline('Resources')} [${resources.length}]`];
98
+ const categorized = categorizeResources(resources);
99
+ for (const category of Object.values(categoryByLabel)) {
61
100
  const catResources = categorized[category.label];
62
101
  if (catResources && catResources.length > 0) {
63
102
  const catOutput = [`${chalk.bold(category.label)} [${catResources.length}]`];
64
103
  const details = [];
65
104
  for (const res of catResources) {
66
- details.push(category.name(res));
67
- if (category.formatDetails)
68
- details.push(category.formatDetails(res));
105
+ details.push(name(category, res));
106
+ if (category.formatDetails) {
107
+ details.push(category.formatDetails(mapToResource(res)));
108
+ }
69
109
  }
70
110
  catOutput.push(details);
71
111
  output.push(catOutput);
@@ -76,11 +116,23 @@ export function formatResourceTree(resources) {
76
116
  `${chalk.bold('Other Resources')} [${categorized['Other Resources'].length}]`,
77
117
  ];
78
118
  const otherResourcesOutput = categorized['Other Resources'].map((other) => {
79
- return `${chalk.yellow(other.displayName ?? other.name ?? 'unnamed')}`;
119
+ return `${chalk.yellow(other.name ?? 'unnamed')} ${chalk.dim(other.type)}`;
80
120
  });
81
121
  otherOutput.push(otherResourcesOutput);
82
122
  output.push(otherOutput);
83
123
  }
124
+ return output;
125
+ }
126
+ export function formatDeployedResourceTree(resources) {
127
+ if (!resources || resources.length === 0)
128
+ return ' Zero deployed resources';
129
+ const output = buildOutputTree(resources, (category, res) => deployedResourceName(res, category.displayNameAttribute), (res) => ({ name: res.name, type: res.type, ...res.parameters }));
130
+ return `${treeify(output)}\n`;
131
+ }
132
+ export function formatResourceTree(resources) {
133
+ if (!resources || resources.length === 0)
134
+ return ' Zero resources';
135
+ const output = buildOutputTree(resources, (category, res) => resourceName(res, category.displayNameAttribute), (res) => res);
84
136
  return `${treeify(output)}\n`;
85
137
  }
86
138
  export function formatStackInfo(stack, isCurrentStack = false) {
@@ -7,3 +7,4 @@ export declare function niceId(id: string | undefined): string;
7
7
  export declare function indent(str: string, spaces?: number): string;
8
8
  export declare function capitalize(str: string): string;
9
9
  export declare function filePathRelativeToCwd(filePath: string): string;
10
+ export declare function labeledId(label: string | undefined, id: string | undefined): string;
@@ -33,3 +33,6 @@ export function capitalize(str) {
33
33
  export function filePathRelativeToCwd(filePath) {
34
34
  return filePath.replace(cwd(), '.');
35
35
  }
36
+ export function labeledId(label, id) {
37
+ return `${chalk.blue(capitalize(label || 'unknown'))} ${niceId(id || 'unknown')}`;
38
+ }
@@ -84,24 +84,25 @@ export async function promptForStack({ projectId, token, }) {
84
84
  throw new Error(stacksErr || 'Failed to list Stacks');
85
85
  }
86
86
  const newStackValue = { id: 'new', name: 'new' };
87
- const stackChoices = [];
88
- stackChoices.push(new Separator(chalk.underline('Create a new Stack:')));
89
- stackChoices.push({ name: chalk.bold('New Stack ✨'), value: newStackValue });
87
+ let pickedStackId = newStackValue;
90
88
  if (stacks.length > 0) {
89
+ const stackChoices = [];
90
+ stackChoices.push(new Separator(chalk.underline('Create a new Stack:')));
91
+ stackChoices.push({ name: chalk.bold('New Stack ✨'), value: newStackValue });
91
92
  stackChoices.push(new Separator(chalk.underline('Use an existing Stack:')));
92
93
  stackChoices.push(...stacks.map((s) => ({
93
94
  name: `"${s.name}" ${niceId(s.id)} ${chalk.dim(`(${s.resources.length} res)`)}`,
94
95
  value: { id: s.id, name: s.name },
95
96
  })));
97
+ pickedStackId = await select({
98
+ message: 'Select a deployment Stack:',
99
+ choices: stackChoices,
100
+ default: newStackValue,
101
+ });
96
102
  }
97
- const pickedStackId = await select({
98
- message: 'Select an existing deployment or create a new one:',
99
- choices: stackChoices,
100
- default: newStackValue,
101
- });
102
103
  if (pickedStackId.id === 'new') {
103
104
  const stackName = await input({
104
- message: 'Enter a name for your Stack:',
105
+ message: 'Enter a name for your new Stack:',
105
106
  validate: (input) => input.length > 0 || 'Stack name is required',
106
107
  });
107
108
  const stack = await createEmptyStack({
@@ -1,4 +1,8 @@
1
+ import type { BlueprintCorsOriginResource, BlueprintDatasetResource, BlueprintDocumentWebhookResource, BlueprintRoleResource } from '@sanity/blueprints';
1
2
  import type { TreeInput } from 'array-treeify';
2
- import type { CorsResource, FunctionResourceBase } from '../../utils/types.js';
3
+ import { type FunctionResourceBase } from '../../utils/types.js';
3
4
  export declare function arrayifyFunction(fn: FunctionResourceBase): TreeInput;
4
- export declare function arraifyCors(resource: CorsResource): TreeInput;
5
+ export declare function arrayifyCors(resource: BlueprintCorsOriginResource): TreeInput;
6
+ export declare function arrayifyRole(resource: BlueprintRoleResource): TreeInput;
7
+ export declare function arrayifyDataset(resource: BlueprintDatasetResource): TreeInput;
8
+ export declare function arrayifyWebhook(resource: BlueprintDocumentWebhookResource): TreeInput;
@@ -1,40 +1,94 @@
1
1
  import chalk from 'chalk';
2
- function formatMemory(memory) {
3
- return `${chalk.dim('memory:')} ${memory}`;
2
+ import { isScheduleEvent, } from '../../utils/types.js';
3
+ function formatLabel(label) {
4
+ return chalk.dim(`${label}:`);
4
5
  }
5
- function formatTimeout(timeout) {
6
- return `${chalk.dim('timeout:')} ${timeout}`;
6
+ function formatLabeledValue(label, value) {
7
+ return `${chalk.dim(`${label}:`)} ${value}`;
7
8
  }
8
9
  function arrayifyEvent(event) {
9
10
  if (!event)
10
11
  return undefined;
11
12
  const details = [];
12
- if (event.on) {
13
- details.push(`${chalk.dim('on:')} ${event.on.map((o) => `"${o}"`).join(', ')}`);
14
- }
15
- if (event.filter) {
16
- details.push(`${chalk.dim('filter:')} ${event.filter}`);
13
+ if (isScheduleEvent(event)) {
14
+ if ('expression' in event) {
15
+ details.push(formatLabeledValue('expression', event.expression));
16
+ }
17
+ else {
18
+ details.push(formatLabeledValue('expression', `${event.minute} ${event.hour} ${event.dayOfWeek} ${event.month} ${event.dayOfMonth}`));
19
+ }
17
20
  }
18
- if (event.projection) {
19
- details.push(`${chalk.dim('projection:')} ${event.projection}`);
21
+ else {
22
+ if (event.on) {
23
+ details.push(formatLabeledValue('on', event.on.map((o) => `"${o}"`).join(', ')));
24
+ }
25
+ if (event.filter) {
26
+ details.push(formatLabeledValue('filter', event.filter));
27
+ }
28
+ if (event.projection) {
29
+ details.push(formatLabeledValue('projection', event.projection));
30
+ }
20
31
  }
21
32
  return details;
22
33
  }
23
34
  export function arrayifyFunction(fn) {
24
- const details = [`${chalk.dim('type:')} "${fn.type}"`];
35
+ const details = [formatLabeledValue('type', fn.type)];
25
36
  if (fn.memory)
26
- details.push(formatMemory(fn.memory));
37
+ details.push(formatLabeledValue('memory', fn.memory));
27
38
  if (fn.timeout)
28
- details.push(formatTimeout(fn.timeout));
39
+ details.push(formatLabeledValue('timeout', fn.timeout));
29
40
  if (fn.event) {
30
41
  const eventDetails = arrayifyEvent(fn.event);
31
42
  if (eventDetails) {
32
- details.push(`${chalk.dim('event:')}`);
43
+ details.push(formatLabel('event'));
33
44
  details.push(eventDetails);
34
45
  }
35
46
  }
36
47
  return details;
37
48
  }
38
- export function arraifyCors(resource) {
39
- return [`${chalk.dim('origin:')} "${resource.origin}"`];
49
+ export function arrayifyCors(resource) {
50
+ return [formatLabeledValue('origin', resource.origin)];
51
+ }
52
+ export function arrayifyRole(resource) {
53
+ const details = [];
54
+ if (resource.description)
55
+ details.push(formatLabeledValue('description', resource.description));
56
+ if (resource.permissions.length > 0) {
57
+ details.push(formatLabel('permissions'));
58
+ const permissions = [];
59
+ const permissionsMap = {};
60
+ resource.permissions.forEach((p) => {
61
+ if (!permissionsMap[p.name])
62
+ permissionsMap[p.name] = [];
63
+ permissionsMap[p.name].push(p.action);
64
+ });
65
+ Object.keys(permissionsMap).forEach((name) => void permissions.push(formatLabeledValue(name, permissionsMap[name].join(', '))));
66
+ details.push(permissions);
67
+ }
68
+ return details;
69
+ }
70
+ export function arrayifyDataset(resource) {
71
+ const details = [];
72
+ if (resource.aclMode)
73
+ details.push(formatLabeledValue('aclMode', resource.aclMode));
74
+ return details;
75
+ }
76
+ export function arrayifyWebhook(resource) {
77
+ const details = [];
78
+ if (resource.description)
79
+ details.push(formatLabeledValue('description', resource.description));
80
+ details.push(formatLabeledValue('url', resource.url));
81
+ details.push(formatLabeledValue('on', resource.on.join(', ')));
82
+ if (resource.filter)
83
+ details.push(formatLabeledValue('filter', resource.filter));
84
+ if (resource.projection)
85
+ details.push(formatLabeledValue('projection', resource.projection));
86
+ if (resource.status)
87
+ details.push(formatLabeledValue('status', resource.status));
88
+ if (resource.httpMethod)
89
+ details.push(formatLabeledValue('httpMethod', resource.httpMethod));
90
+ if (resource.dataset)
91
+ details.push(formatLabeledValue('dataset', resource.dataset));
92
+ // not included: headers, includeDrafts, includeAllVersions, secret, apiVersion
93
+ return details;
40
94
  }
@@ -1,4 +1,4 @@
1
1
  import type { Blueprint } from '@sanity/blueprints-parser';
2
2
  import type { DeployedResource, FunctionResource, Stack } from './types.js';
3
- export declare function findFunctionByName(blueprintOrStack: Blueprint, name: string): FunctionResource;
4
- export declare function findFunctionByName(blueprintOrStack: Stack, name: string): FunctionResource & DeployedResource;
3
+ export declare function findFunctionInBlueprint(blueprint: Blueprint, name: string): FunctionResource;
4
+ export declare function findFunctionInStack(stack: Stack, name: string): DeployedResource;
@@ -1,6 +1,13 @@
1
- export function findFunctionByName(blueprintOrStack, name) {
2
- const func = blueprintOrStack?.resources?.find((r) => r?.type?.startsWith('sanity.function.') && r.name === name);
1
+ export function findFunctionInBlueprint(blueprint, name) {
2
+ const func = blueprint?.resources?.find((r) => r?.type?.startsWith('sanity.function.') && r.name === name);
3
3
  if (!func)
4
4
  throw Error(`Unable to find function ${name}`);
5
5
  return func;
6
6
  }
7
+ export function findFunctionInStack(stack, name) {
8
+ const func = stack?.resources?.find((r) => r?.type?.startsWith('sanity.function.') && r.name === name);
9
+ if (!func)
10
+ throw Error(`Unable to find function ${name}`);
11
+ // return the deployed resource
12
+ return func;
13
+ }
@@ -1,4 +1,4 @@
1
- import type { FunctionResource, GroqRuleBase, InvocationResponse, InvokeContextOptions, InvokeExecutionOptions, InvokePayloadOptions } from './types.js';
1
+ import { type FunctionGroqResource, type FunctionResource, type GroqRuleBase, type InvocationResponse, type InvokeContextOptions, type InvokeExecutionOptions, type InvokeGroqPayloadOptions, type InvokePayloadOptions } from './types.js';
2
2
  export declare function sanitizeLogs(logs: string): string;
3
3
  export declare const DEFAULT_GROQ_RULE: {
4
4
  on: string[];
@@ -6,5 +6,5 @@ export declare const DEFAULT_GROQ_RULE: {
6
6
  projection: string;
7
7
  };
8
8
  export declare function isDefaultGROQRule(rule: GroqRuleBase | undefined): boolean;
9
- export declare function applyGroqRule(resource: FunctionResource, data: Record<string, unknown> | null, before: Record<string, unknown> | null, after: Record<string, unknown> | null, projectId: string | undefined, dataset: string | undefined): Promise<any>;
9
+ export declare function applyGroqRule(resource: FunctionGroqResource, payload: InvokeGroqPayloadOptions, projectId: string | undefined, dataset: string | undefined): Promise<any>;
10
10
  export default function invoke(resource: FunctionResource, payload: InvokePayloadOptions, context: InvokeContextOptions, options: InvokeExecutionOptions): Promise<InvocationResponse>;