@sanity/runtime-cli 1.3.1 → 1.4.1

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 (59) hide show
  1. package/README.md +11 -14
  2. package/dist/actions/blueprints/logs.d.ts +1 -0
  3. package/dist/actions/blueprints/logs.js +3 -2
  4. package/dist/actions/blueprints/operations.d.ts +1 -0
  5. package/dist/actions/blueprints/operations.js +3 -2
  6. package/dist/actions/blueprints/read-blueprint.d.ts +16 -7
  7. package/dist/actions/blueprints/read-blueprint.js +56 -10
  8. package/dist/actions/blueprints/stacks.d.ts +6 -6
  9. package/dist/actions/blueprints/stacks.js +10 -14
  10. package/dist/actions/blueprints/stash-asset.d.ts +1 -0
  11. package/dist/actions/blueprints/stash-asset.js +2 -5
  12. package/dist/actions/functions/invoke.d.ts +6 -2
  13. package/dist/actions/functions/invoke.js +9 -11
  14. package/dist/actions/functions/logs.d.ts +6 -1
  15. package/dist/actions/functions/logs.js +10 -10
  16. package/dist/commands/blueprints/deploy.js +19 -18
  17. package/dist/commands/blueprints/info.js +18 -38
  18. package/dist/commands/blueprints/logs.d.ts +0 -1
  19. package/dist/commands/blueprints/logs.js +12 -41
  20. package/dist/commands/blueprints/plan.js +14 -4
  21. package/dist/commands/functions/invoke.js +19 -2
  22. package/dist/commands/functions/logs.js +26 -2
  23. package/dist/config.js +6 -5
  24. package/dist/server/static/api.d.ts +10 -0
  25. package/dist/server/static/api.js +38 -43
  26. package/dist/server/static/components/api-base.d.ts +9 -0
  27. package/dist/server/static/components/api-base.js +6 -7
  28. package/dist/server/static/components/function-list.d.ts +1 -0
  29. package/dist/server/static/components/function-list.js +44 -48
  30. package/dist/server/static/components/network-spinner.d.ts +1 -0
  31. package/dist/server/static/components/network-spinner.js +6 -7
  32. package/dist/server/static/components/payload-panel.d.ts +1 -0
  33. package/dist/server/static/components/payload-panel.js +32 -36
  34. package/dist/server/static/components/response-panel.d.ts +1 -0
  35. package/dist/server/static/components/response-panel.js +50 -64
  36. package/dist/server/static/static/api.js +53 -0
  37. package/dist/server/static/static/components/api-base.js +10 -0
  38. package/dist/server/static/static/components/function-list.js +54 -0
  39. package/dist/server/static/static/components/network-spinner.js +71 -0
  40. package/dist/server/static/static/components/payload-panel.js +45 -0
  41. package/dist/server/static/static/components/response-panel.js +83 -0
  42. package/dist/server/static/static/vendor/vendor.bundle.js +26879 -0
  43. package/dist/server/static/vendor/vendor.bundle.d.ts +1815 -0
  44. package/dist/server/static/vendor/vendor.bundle.js +913 -1029
  45. package/dist/utils/child-process-wrapper.d.ts +1 -0
  46. package/dist/utils/display/blueprints-formatting.js +2 -2
  47. package/dist/utils/get-headers.d.ts +8 -0
  48. package/dist/utils/get-headers.js +9 -0
  49. package/dist/utils/get-token.d.ts +3 -1
  50. package/dist/utils/get-token.js +2 -2
  51. package/dist/utils/types.d.ts +44 -30
  52. package/dist/utils/types.js +8 -1
  53. package/dist/utils/vendor/parser-validator.d.ts +8 -0
  54. package/dist/utils/vendor/parser-validator.js +514 -0
  55. package/oclif.manifest.json +1 -11
  56. package/package.json +11 -12
  57. /package/dist/server/static/{components → static/components}/app.css +0 -0
  58. /package/dist/server/static/{index.html → static/index.html} +0 -0
  59. /package/dist/server/static/{sanity-logo-sm.svg → static/sanity-logo-sm.svg} +0 -0
@@ -1,51 +1,32 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import readBlueprintOnDisk from '../../actions/blueprints/read-blueprint.js';
3
- import { getStackByName } from '../../actions/blueprints/stacks.js';
4
- import { formatResourceTree, formatStacksList, formatTitle, } from '../../utils/display/blueprints-formatting.js';
3
+ import { formatResourceTree } from '../../utils/display/blueprints-formatting.js';
5
4
  import { bold, green, red, yellow } from '../../utils/display/colors.js';
6
5
  import { formatDate, formatDuration } from '../../utils/display/dates.js';
7
- import Spinner from '../../utils/spinner.js';
8
6
  export default class Info extends Command {
9
7
  static description = 'Show information about a Blueprint';
10
8
  static examples = ['<%= config.bin %> <%= command.id %>'];
11
9
  async run() {
12
- const { document } = readBlueprintOnDisk();
13
- const { displayName, name, projectId } = document;
14
- const s = new Spinner();
15
- if (!projectId) {
16
- this.log(`Cannot determine project for Blueprint "${displayName}"`);
10
+ const { errors, deployedStack } = await readBlueprintOnDisk({ getStack: true });
11
+ if (errors.length > 0) {
12
+ // printErrors(errors)
13
+ this.log('Blueprint parse errors:');
14
+ console.dir(errors, { depth: null });
17
15
  return;
18
16
  }
19
- s.start(`Retrieving info for "${displayName}"`);
17
+ if (!deployedStack)
18
+ this.error('Stack not found'); // returns
20
19
  try {
21
- const { ok, stack, stackId: foundStackId, error, availableStacks, } = await getStackByName({
22
- name,
23
- projectId,
24
- });
25
- if (!ok) {
26
- s.stop(`${red('Failed')} to retrieve stacks`);
27
- this.log(`Error: ${error || 'Unknown error'}`);
28
- return;
20
+ this.log(`Stack name: ${bold(deployedStack.name)}`);
21
+ this.log(`Stack ID: ${yellow(deployedStack.id)}`);
22
+ if (deployedStack.createdAt) {
23
+ this.log(`Created: ${formatDate(deployedStack.createdAt)}`);
29
24
  }
30
- if (!foundStackId || !stack) {
31
- s.stop(`${red('Failed')} to find Stack for ${formatTitle('Blueprint', displayName)}`);
32
- if (availableStacks && availableStacks.length > 0) {
33
- this.log(formatStacksList(availableStacks));
34
- }
35
- return;
36
- }
37
- const foundStack = { id: foundStackId };
38
- s.stop(`${formatTitle('Blueprint', displayName)} Info\n`);
39
- this.log(`Stack name: ${bold(stack.name)}`);
40
- this.log(`Stack ID: ${yellow(foundStack.id)}`);
41
- if (stack.createdAt) {
42
- this.log(`Created: ${formatDate(stack.createdAt)}`);
43
- }
44
- if (stack.updatedAt) {
45
- this.log(`Updated: ${formatDate(stack.updatedAt)}`);
25
+ if (deployedStack.updatedAt) {
26
+ this.log(`Updated: ${formatDate(deployedStack.updatedAt)}`);
46
27
  }
47
- if (stack.recentOperation) {
48
- const operation = stack.recentOperation;
28
+ if (deployedStack.recentOperation) {
29
+ const operation = deployedStack.recentOperation;
49
30
  if (operation.id) {
50
31
  this.log(`Recent Operation <${yellow(operation.id)}>:`);
51
32
  }
@@ -63,12 +44,11 @@ export default class Info extends Command {
63
44
  }
64
45
  }
65
46
  this.log('');
66
- if (stack?.resources) {
67
- formatResourceTree(stack.resources, this.log.bind(this));
47
+ if (deployedStack.resources) {
48
+ formatResourceTree(deployedStack.resources, this.log.bind(this));
68
49
  }
69
50
  }
70
51
  catch (err) {
71
- s.stop('Failed to parse Stack info');
72
52
  if (err instanceof Error) {
73
53
  this.log(`Error: ${err.message}`);
74
54
  }
@@ -3,7 +3,6 @@ export default class Logs extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- 'stack-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
6
  watch: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
7
  };
9
8
  run(): Promise<void>;
@@ -1,24 +1,17 @@
1
1
  import { Command, Flags } from '@oclif/core';
2
2
  import { getLogs, streamLogs } from '../../actions/blueprints/logs.js';
3
3
  import readBlueprintOnDisk from '../../actions/blueprints/read-blueprint.js';
4
- import { getStackByName } from '../../actions/blueprints/stacks.js';
5
4
  import config from '../../config.js';
6
- import { formatStacksList, formatTitle } from '../../utils/display/blueprints-formatting.js';
5
+ import { formatTitle } from '../../utils/display/blueprints-formatting.js';
7
6
  import { blue, bold, green, red, yellow } from '../../utils/display/colors.js';
8
7
  import Spinner from '../../utils/spinner.js';
9
8
  export default class Logs extends Command {
10
9
  static description = 'Display logs for a Blueprint stack';
11
10
  static examples = [
12
11
  '<%= config.bin %> <%= command.id %>',
13
- '<%= config.bin %> <%= command.id %> --stack-id <stack-id>',
14
12
  '<%= config.bin %> <%= command.id %> --watch',
15
13
  ];
16
14
  static flags = {
17
- 'stack-id': Flags.string({
18
- char: 's',
19
- description: 'Stack ID to fetch logs for (optional if running in a blueprint directory)',
20
- required: false,
21
- }),
22
15
  watch: Flags.boolean({
23
16
  char: 'w',
24
17
  description: 'Watch for new logs (streaming mode)',
@@ -28,41 +21,19 @@ export default class Logs extends Command {
28
21
  };
29
22
  async run() {
30
23
  const { flags } = await this.parse(Logs);
31
- const s = new Spinner();
32
24
  const watchMode = flags.watch;
25
+ const s = new Spinner();
33
26
  try {
34
- const { document } = readBlueprintOnDisk();
35
- const { name, displayName, projectId } = document;
36
- if (!projectId) {
37
- this.log('Cannot determine project ID for this Blueprint');
38
- return;
39
- }
40
- let stackId = flags['stack-id'];
41
- if (!stackId) {
42
- s.start(`Finding stack for blueprint "${displayName}"`);
43
- const { ok, stackId: foundStackId, error, availableStacks, } = await getStackByName({
44
- name,
45
- projectId,
46
- });
47
- if (!ok) {
48
- s.stop(`${red('Failed')} to retrieve stacks`);
49
- this.log(`Error: ${error || 'Unknown error'}`);
50
- return;
51
- }
52
- if (!foundStackId) {
53
- s.stop(`${red('Failed')} to find Stack for ${formatTitle('Blueprint', displayName)}`);
54
- if (availableStacks && availableStacks.length > 0) {
55
- this.log(formatStacksList(availableStacks));
56
- }
57
- return;
58
- }
59
- stackId = foundStackId;
60
- s.stop(`Found stack ${stackId} for blueprint "${displayName}"`);
61
- }
62
- if (!stackId) {
63
- s.stop(`${red('Failed')} to determine stack ID`);
27
+ const { errors, deployedStack } = await readBlueprintOnDisk({ getStack: true });
28
+ if (errors.length > 0) {
29
+ // printErrors(errors)
30
+ this.log('Blueprint parse errors:');
31
+ console.dir(errors, { depth: null });
64
32
  return;
65
33
  }
34
+ if (!deployedStack)
35
+ this.error('Stack not found'); // returns
36
+ const { id: stackId, projectId, name } = deployedStack;
66
37
  if (watchMode) {
67
38
  // recent logs
68
39
  s.start(`Fetching recent logs for stack ${stackId}`);
@@ -72,7 +43,7 @@ export default class Logs extends Command {
72
43
  this.log(`Error: ${error || 'Unknown error'}`);
73
44
  return;
74
45
  }
75
- s.stop(`${formatTitle('Blueprint', displayName)} ${bold('Live')} Logs`);
46
+ s.stop(`${formatTitle('Blueprint', name)} ${bold('Live')} Logs`);
76
47
  if (logs.length > 0) {
77
48
  this.log('\nMost recent logs:');
78
49
  const sortedLogs = [...logs].sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
@@ -128,7 +99,7 @@ export default class Logs extends Command {
128
99
  s.stop(`No logs found for stack ${stackId}`);
129
100
  return;
130
101
  }
131
- s.stop(`${formatTitle('Blueprint', displayName)} Logs`);
102
+ s.stop(`${formatTitle('Blueprint', name)} Logs`);
132
103
  this.log(`Found ${bold(logs.length.toString())} log entries for stack ${yellow(stackId)}\n`);
133
104
  const logsByDay = new Map();
134
105
  for (const log of logs) {
@@ -5,10 +5,20 @@ export default class Plan extends Command {
5
5
  static description = 'Enumerate resources to be deployed - will not modify any resources';
6
6
  static examples = ['<%= config.bin %> <%= command.id %>'];
7
7
  async run() {
8
- const { document, fileName } = readBlueprintOnDisk();
9
- const { displayName, name, resources } = document;
10
- this.log(`${formatTitle('Blueprint', displayName)} Plan\n`);
11
- this.log(`Blueprint document: "${name}" (${fileName})`);
8
+ const { errors, projectResource, stackResource, parsedBlueprint: { resources }, fileInfo, } = await readBlueprintOnDisk();
9
+ if (errors.length > 0) {
10
+ // printErrors(errors)
11
+ this.log('Blueprint parse errors:');
12
+ console.dir(errors, { depth: null });
13
+ return;
14
+ }
15
+ if (!projectResource)
16
+ this.log('Blueprint must contain a project resource');
17
+ if (!stackResource)
18
+ this.log('Blueprint must contain a stack resource');
19
+ const name = stackResource?.name || 'Unknown';
20
+ this.log(`${formatTitle('Blueprint', name)} Plan\n`);
21
+ this.log(`Blueprint document: "${name}" (${fileInfo.fileName})`);
12
22
  this.log('');
13
23
  formatResourceTree(resources, this.log.bind(this));
14
24
  if (resources.length > 0) {
@@ -1,5 +1,9 @@
1
1
  import { Args, Command, Flags } from '@oclif/core';
2
+ import readBlueprintOnDisk from '../../actions/blueprints/read-blueprint.js';
2
3
  import { invoke } from '../../actions/functions/invoke.js';
4
+ import config from '../../config.js';
5
+ import { red } from '../../utils/display/colors.js';
6
+ import Spinner from '../../utils/spinner.js';
3
7
  export default class Invoke extends Command {
4
8
  static args = {
5
9
  id: Args.string({ description: 'The ID of the function to invoke', required: true }),
@@ -19,7 +23,20 @@ export default class Invoke extends Command {
19
23
  };
20
24
  async run() {
21
25
  const { args, flags } = await this.parse(Invoke);
22
- const result = await invoke(args.id, { data: flags.data, file: flags.file });
23
- this.log(JSON.stringify(result, null, 2));
26
+ const s = new Spinner();
27
+ const { deployedStack } = await readBlueprintOnDisk({ getStack: true });
28
+ if (!deployedStack)
29
+ this.error('Stack not found'); // returns
30
+ const { projectId } = deployedStack;
31
+ s.start(`Invoking function "${args.id}"`);
32
+ const result = await invoke(args.id, { data: flags.data, file: flags.file }, { token: config.token, projectId });
33
+ if (result.ok) {
34
+ s.stop(`Invocation of ${args.id} succeeded`);
35
+ this.log(JSON.stringify(result.json, null, 2));
36
+ }
37
+ else {
38
+ s.stop(`${red('Failed')} to invoke function`);
39
+ this.log(`Error: ${result.error || 'Unknown error'}`);
40
+ }
24
41
  }
25
42
  }
@@ -1,6 +1,9 @@
1
1
  import { Args, Command } from '@oclif/core';
2
+ import readBlueprintOnDisk from '../../actions/blueprints/read-blueprint.js';
2
3
  import { logs } from '../../actions/functions/logs.js';
3
4
  import config from '../../config.js';
5
+ import { bold, red, yellow } from '../../utils/display/colors.js';
6
+ import Spinner from '../../utils/spinner.js';
4
7
  export default class Logs extends Command {
5
8
  static args = {
6
9
  id: Args.string({ description: 'The ID of the function to retrieve logs for', required: true }),
@@ -9,7 +12,28 @@ export default class Logs extends Command {
9
12
  static examples = ['<%= config.bin %> <%= command.id %> <ID>'];
10
13
  async run() {
11
14
  const { args } = await this.parse(Logs);
12
- const result = await logs(args.id, config.token);
13
- this.log(JSON.stringify(result, null, 2));
15
+ const s = new Spinner();
16
+ const { deployedStack } = await readBlueprintOnDisk({ getStack: true });
17
+ if (!deployedStack)
18
+ this.error('Stack not found'); // returns
19
+ s.start(`Finding logs for function "${args.id}"`);
20
+ const { name, projectId } = deployedStack;
21
+ const result = await logs(args.id, { token: config.token, projectId });
22
+ console.log(JSON.stringify(result, null, 2));
23
+ if (result.ok) {
24
+ s.stop(`Found logs ${args.id} for blueprint "${name}"`);
25
+ for (const logGroup of result.logs) {
26
+ for (const log of logGroup.events) {
27
+ const date = new Date(log.timestamp);
28
+ const time = date.toLocaleTimeString();
29
+ const day = date.toLocaleDateString();
30
+ this.log(` ${bold(day)} ${yellow(time)} ${log.message}`);
31
+ }
32
+ }
33
+ }
34
+ else {
35
+ s.stop(`${red('Failed')} to retrieve logs`);
36
+ this.log(`Error: ${result.error || 'Unknown error'}`);
37
+ }
14
38
  }
15
39
  }
package/dist/config.js CHANGED
@@ -1,22 +1,23 @@
1
1
  import { env } from 'node:process';
2
2
  import getToken from './utils/get-token.js';
3
3
  const nodeEnv = env.NODE_ENV ?? 'development';
4
+ const isTest = nodeEnv === 'test';
4
5
  const isDev = nodeEnv === 'development';
5
- const isProd = nodeEnv === 'production';
6
+ const useProd = nodeEnv === 'production';
6
7
  const functionsUrls = {
7
8
  production: 'https://api.sanity.io/',
8
9
  staging: 'https://api.sanity.work/',
9
10
  default: 'http://localhost:4567',
10
11
  };
11
12
  const blueprintsUrls = {
12
- production: 'https://api.sanity.io',
13
- staging: 'https://api.sanity.work',
14
- default: 'http://localhost:4567',
13
+ production: 'https://api.sanity.io/',
14
+ staging: 'https://api.sanity.work/',
15
+ default: 'http://blueprints/',
15
16
  };
16
17
  const functionsUrl = new URL(functionsUrls[nodeEnv] ?? functionsUrls.default);
17
18
  const blueprintsUrl = new URL(blueprintsUrls[nodeEnv] ?? blueprintsUrls.default);
18
19
  export default {
19
- token: isDev ? 'token' : getToken(isProd),
20
+ token: isDev || isTest ? 'token' : getToken({ prod: useProd }),
20
21
  server: {
21
22
  functions: functionsUrl,
22
23
  blueprints: blueprintsUrl,
@@ -0,0 +1,10 @@
1
+ export default function API(): {
2
+ blueprint: typeof blueprint;
3
+ invoke: typeof invoke;
4
+ store: any;
5
+ subscribe: any;
6
+ unsubscribe: any;
7
+ };
8
+ declare function blueprint(): void;
9
+ declare function invoke(payloadText?: string): void;
10
+ export {};
@@ -1,53 +1,48 @@
1
1
  /* eslint-disable n/no-unsupported-features/node-builtins */
2
- import {Store} from './vendor/vendor.bundle.js'
3
-
2
+ import { Store } from './vendor/vendor.bundle.js';
4
3
  // eslint-disable-next-line new-cap
5
- const store = Store()
6
-
4
+ const store = Store();
7
5
  export default function API() {
8
- return {
9
- blueprint,
10
- invoke,
11
- store,
12
- subscribe: store.subscribe,
13
- unsubscribe: store.unsubscribe,
14
- }
6
+ return {
7
+ blueprint,
8
+ invoke,
9
+ store,
10
+ subscribe: store.subscribe,
11
+ unsubscribe: store.unsubscribe,
12
+ };
15
13
  }
16
-
17
14
  function invoke(payloadText = '{}') {
18
- store.inprogress = true
19
- const start = Date.now()
20
- const payload = {
21
- data: payloadText,
22
- func: store.selectedIndex,
23
- }
24
- fetch('/invoke', {
25
- body: JSON.stringify(payload),
26
- headers: {
27
- 'Content-Type': 'application/json',
28
- },
29
- method: 'POST',
30
- })
31
- .then((response) => response.json())
32
- .then((data) => {
33
- store.inprogress = false
34
- store.result = {
35
- ...data,
36
- time: Date.now() - start,
37
- }
15
+ store.inprogress = true;
16
+ const start = Date.now();
17
+ const payload = {
18
+ data: payloadText,
19
+ func: store.selectedIndex,
20
+ };
21
+ fetch('/invoke', {
22
+ body: JSON.stringify(payload),
23
+ headers: {
24
+ 'Content-Type': 'application/json',
25
+ },
26
+ method: 'POST',
38
27
  })
28
+ .then((response) => response.json())
29
+ .then((data) => {
30
+ store.inprogress = false;
31
+ store.result = {
32
+ ...data,
33
+ time: Date.now() - start,
34
+ };
35
+ });
39
36
  }
40
-
41
37
  function blueprint() {
42
- fetch('/blueprint')
43
- .then((response) => response.json())
44
- .then((json) => {
45
- const functions = json?.document?.resources.filter((resource) => resource.kind === 'function')
46
-
47
- store.functions = functions
48
- store.selectedIndex = functions[0].src
49
- })
50
- .catch(() => {
51
- store.functions = []
38
+ fetch('/blueprint')
39
+ .then((response) => response.json())
40
+ .then((json) => {
41
+ const functions = json?.document?.resources.filter((resource) => resource.kind === 'function');
42
+ store.functions = functions;
43
+ store.selectedIndex = functions[0].src;
52
44
  })
45
+ .catch(() => {
46
+ store.functions = [];
47
+ });
53
48
  }
@@ -0,0 +1,9 @@
1
+ export class ApiBaseElement extends HTMLElement {
2
+ api: {
3
+ blueprint: () => void;
4
+ invoke: (payloadText?: string) => void;
5
+ store: any;
6
+ subscribe: any;
7
+ unsubscribe: any;
8
+ };
9
+ }
@@ -1,10 +1,9 @@
1
1
  /* globals HTMLElement */
2
- import apiConstructor from '../api.js'
3
- const api = apiConstructor()
4
-
2
+ import apiConstructor from '../api.js';
3
+ const api = apiConstructor();
5
4
  export class ApiBaseElement extends HTMLElement {
6
- constructor() {
7
- super()
8
- this.api = api
9
- }
5
+ constructor() {
6
+ super();
7
+ this.api = api;
8
+ }
10
9
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,54 +1,50 @@
1
1
  /* globals customElements */
2
- import {ApiBaseElement} from './api-base.js'
3
-
2
+ import { ApiBaseElement } from './api-base.js';
4
3
  const template = `<ol class="hidden-lg" type="content"></ol>
5
4
  <fieldset class="pad-sm hidden block-lg"><select></select></fieldset>
6
- `
7
-
5
+ `;
8
6
  class FunctionList extends ApiBaseElement {
9
- functionClicked = (event) => {
10
- // eslint-disable-next-line unicorn/prefer-dom-node-text-content
11
- const target = this.api.store.functions.find((func) => func.name === event.srcElement.innerText)
12
- this.api.store.selectedIndex = target.src
13
- }
14
- functionSelected = (event) => {
15
- this.api.store.selectedIndex = event.srcElement.value
16
- }
17
- renderFunctions = () => {
18
- if (this.api.store.functions.length > 0) {
19
- this.list.innerHTML = this.api.store.functions
20
- .map((func) => {
21
- const selected = this.api.store.selectedIndex === func.src ? 'selected' : ''
22
- return `<li class="pad-sm ${selected}">${func.name}</li>`
23
- })
24
- .join('')
25
- this.select.innerHTML = this.api.store.functions
26
- .map((func) => {
27
- const selected = this.api.store.selectedIndex === func.src ? 'selected' : ''
28
- return `<option value="${func.src}" ${selected}>${func.name}</option>`
29
- })
30
- .join('')
31
- } else {
32
- this.list.innerHTML = '<option class="pad-sm">No blueprint.json file found</li>'
33
- this.select.innerHTML = '<option>No blueprint.json file found</option>'
7
+ functionClicked = (event) => {
8
+ // eslint-disable-next-line unicorn/prefer-dom-node-text-content
9
+ const target = this.api.store.functions.find((func) => func.name === event.srcElement.innerText);
10
+ this.api.store.selectedIndex = target.src;
11
+ };
12
+ functionSelected = (event) => {
13
+ this.api.store.selectedIndex = event.srcElement.value;
14
+ };
15
+ renderFunctions = () => {
16
+ if (this.api.store.functions.length > 0) {
17
+ this.list.innerHTML = this.api.store.functions
18
+ .map((func) => {
19
+ const selected = this.api.store.selectedIndex === func.src ? 'selected' : '';
20
+ return `<li class="pad-sm ${selected}">${func.name}</li>`;
21
+ })
22
+ .join('');
23
+ this.select.innerHTML = this.api.store.functions
24
+ .map((func) => {
25
+ const selected = this.api.store.selectedIndex === func.src ? 'selected' : '';
26
+ return `<option value="${func.src}" ${selected}>${func.name}</option>`;
27
+ })
28
+ .join('');
29
+ }
30
+ else {
31
+ this.list.innerHTML = '<option class="pad-sm">No blueprint.json file found</li>';
32
+ this.select.innerHTML = '<option>No blueprint.json file found</option>';
33
+ }
34
+ };
35
+ connectedCallback() {
36
+ this.innerHTML = template;
37
+ this.list = this.querySelector('ol');
38
+ this.select = this.querySelector('select');
39
+ this.list.addEventListener('click', this.functionClicked);
40
+ this.select.addEventListener('change', this.functionSelected);
41
+ this.api.subscribe(this.renderFunctions, ['functions', 'selectedIndex']);
42
+ this.api.blueprint();
43
+ }
44
+ disconnectedCallback() {
45
+ this.list.removeEventListener('click', this.functionClicked);
46
+ this.select.removeEventListener('change', this.functionSelected);
47
+ this.api.unsubscribe(this.renderFunctions);
34
48
  }
35
- }
36
-
37
- connectedCallback() {
38
- this.innerHTML = template
39
- this.list = this.querySelector('ol')
40
- this.select = this.querySelector('select')
41
- this.list.addEventListener('click', this.functionClicked)
42
- this.select.addEventListener('change', this.functionSelected)
43
- this.api.subscribe(this.renderFunctions, ['functions', 'selectedIndex'])
44
- this.api.blueprint()
45
- }
46
-
47
- disconnectedCallback() {
48
- this.list.removeEventListener('click', this.functionClicked)
49
- this.select.removeEventListener('change', this.functionSelected)
50
- this.api.unsubscribe(this.renderFunctions)
51
- }
52
49
  }
53
-
54
- customElements.define('function-list', FunctionList)
50
+ customElements.define('function-list', FunctionList);
@@ -0,0 +1 @@
1
+ export {};
@@ -60,12 +60,11 @@ const template = `<style>
60
60
  <svg part="base" class="spinner" role="progressbar" aria-label="loading">
61
61
  <circle class="spinner__track"></circle>
62
62
  <circle class="spinner__indicator"></circle>
63
- </svg>`
64
-
63
+ </svg>`;
65
64
  class NetworkSpinner extends HTMLElement {
66
- connectedCallback() {
67
- this.innerHTML = template
68
- }
65
+ connectedCallback() {
66
+ this.innerHTML = template;
67
+ }
69
68
  }
70
-
71
- customElements.define('network-spinner', NetworkSpinner)
69
+ customElements.define('network-spinner', NetworkSpinner);
70
+ export {};
@@ -0,0 +1 @@
1
+ export {};