feat(TemplatePreviewPage): implement a view for previewing template form UIs
Signed-off-by: Phil Kuang <pkuang@factset.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Implement a template preview page (`/create/preview`) to test creating form UIs
|
||||
@@ -79,6 +79,7 @@ import { entityPage } from './components/catalog/EntityPage';
|
||||
import { homePage } from './components/home/HomePage';
|
||||
import { Root } from './components/Root';
|
||||
import { LowerCaseValuePickerFieldExtension } from './components/scaffolder/customScaffolderExtensions';
|
||||
import { defaultPreviewTemplate } from './components/scaffolder/defaultPreviewTemplate';
|
||||
import { searchPage } from './components/search/SearchPage';
|
||||
import { providers } from './identityProviders';
|
||||
import * as plugins from './plugins';
|
||||
@@ -179,6 +180,7 @@ const routes = (
|
||||
path="/create"
|
||||
element={
|
||||
<ScaffolderPage
|
||||
defaultPreviewTemplate={defaultPreviewTemplate}
|
||||
groups={[
|
||||
{
|
||||
title: 'Recommended',
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export const defaultPreviewTemplate = `# Edit the template parameters below to see how they will render in the scaffolder form UI
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
required:
|
||||
- name
|
||||
properties:
|
||||
name:
|
||||
title: Name
|
||||
type: string
|
||||
description: Unique name of the component
|
||||
owner:
|
||||
title: Owner
|
||||
type: string
|
||||
description: Owner of the component
|
||||
ui:field: OwnerPicker
|
||||
ui:options:
|
||||
allowedKinds:
|
||||
- Group
|
||||
- title: Choose a location
|
||||
required:
|
||||
- repoUrl
|
||||
properties:
|
||||
repoUrl:
|
||||
title: Repository Location
|
||||
type: string
|
||||
ui:field: RepoUrlPicker
|
||||
ui:options:
|
||||
allowedHosts:
|
||||
- github.com
|
||||
- title: Custom Fields
|
||||
required:
|
||||
- lowerCaseValue
|
||||
properties:
|
||||
lowerCaseValue:
|
||||
title: Lower Cased Value
|
||||
type: string
|
||||
ui:field: LowerCaseValuePicker
|
||||
`;
|
||||
@@ -200,6 +200,7 @@ export type RouterProps = {
|
||||
titleComponent?: React_2.ReactNode;
|
||||
filter: (entity: Entity) => boolean;
|
||||
}>;
|
||||
defaultPreviewTemplate?: string;
|
||||
};
|
||||
|
||||
// @public
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
"clean": "backstage-cli package clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@backstage/catalog-client": "^0.9.0",
|
||||
"@backstage/catalog-model": "^0.13.0",
|
||||
"@backstage/config": "^0.1.15",
|
||||
@@ -49,11 +48,16 @@
|
||||
"@backstage/plugin-scaffolder-common": "^0.3.0",
|
||||
"@backstage/theme": "^0.2.15",
|
||||
"@backstage/types": "^0.1.3",
|
||||
"@codemirror/legacy-modes": "^0.19.0",
|
||||
"@codemirror/panel": "^0.19.1",
|
||||
"@codemirror/stream-parser": "^0.19.6",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@rjsf/core": "^3.2.1",
|
||||
"@rjsf/material-ui": "^3.2.1",
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@uiw/react-codemirror": "^4.5.1",
|
||||
"classnames": "^2.2.6",
|
||||
"git-url-parse": "^11.6.0",
|
||||
"humanize-duration": "^3.25.1",
|
||||
@@ -66,6 +70,7 @@
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4",
|
||||
"use-immer": "^0.6.0",
|
||||
"yaml": "^1.9.2",
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -51,7 +51,7 @@ type Props = {
|
||||
formData: Record<string, any>;
|
||||
onChange: (e: IChangeEvent) => void;
|
||||
onReset: () => void;
|
||||
onFinish: () => Promise<void>;
|
||||
onFinish?: () => Promise<void>;
|
||||
widgets?: FormProps<any>['widgets'];
|
||||
fields?: FormProps<any>['fields'];
|
||||
};
|
||||
@@ -163,6 +163,10 @@ export const MultistepJsonForm = (props: Props) => {
|
||||
};
|
||||
const handleBack = () => setActiveStep(Math.max(activeStep - 1, 0));
|
||||
const handleCreate = async () => {
|
||||
if (!onFinish) {
|
||||
return;
|
||||
}
|
||||
|
||||
setDisableButtons(true);
|
||||
try {
|
||||
await onFinish();
|
||||
@@ -232,7 +236,7 @@ export const MultistepJsonForm = (props: Props) => {
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleCreate}
|
||||
disabled={disableButtons}
|
||||
disabled={!onFinish || disableButtons}
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
|
||||
@@ -23,6 +23,7 @@ import { TemplatePage } from './TemplatePage';
|
||||
import { TaskPage } from './TaskPage';
|
||||
import { ActionsPage } from './ActionsPage';
|
||||
import { SecretsContextProvider } from './secrets/SecretsContext';
|
||||
import { TemplatePreviewPage } from './TemplatePreviewPage';
|
||||
|
||||
import {
|
||||
FieldExtensionOptions,
|
||||
@@ -48,6 +49,7 @@ export type RouterProps = {
|
||||
titleComponent?: React.ReactNode;
|
||||
filter: (entity: Entity) => boolean;
|
||||
}>;
|
||||
defaultPreviewTemplate?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -56,7 +58,7 @@ export type RouterProps = {
|
||||
* @public
|
||||
*/
|
||||
export const Router = (props: RouterProps) => {
|
||||
const { groups, components = {} } = props;
|
||||
const { groups, components = {}, defaultPreviewTemplate } = props;
|
||||
|
||||
const { TemplateCardComponent, TaskPageComponent } = components;
|
||||
|
||||
@@ -104,6 +106,17 @@ export const Router = (props: RouterProps) => {
|
||||
/>
|
||||
<Route path="/tasks/:taskId" element={<TaskPageElement />} />
|
||||
<Route path="/actions" element={<ActionsPage />} />
|
||||
<Route
|
||||
path="/preview"
|
||||
element={
|
||||
<SecretsContextProvider>
|
||||
<TemplatePreviewPage
|
||||
defaultPreviewTemplate={defaultPreviewTemplate}
|
||||
customFieldExtensions={fieldExtensions}
|
||||
/>
|
||||
</SecretsContextProvider>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,4 +13,4 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { TemplatePage } from './TemplatePage';
|
||||
export { createValidator, TemplatePage } from './TemplatePage';
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import useDebounce from 'react-use/lib/useDebounce';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Content, Header, InfoCard, Page } from '@backstage/core-components';
|
||||
import { alertApiRef, useApi, useApiHolder } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
catalogApiRef,
|
||||
humanizeEntityRef,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';
|
||||
import { showPanel } from '@codemirror/panel';
|
||||
import { StreamLanguage } from '@codemirror/stream-parser';
|
||||
import {
|
||||
FormControl,
|
||||
Grid,
|
||||
InputLabel,
|
||||
LinearProgress,
|
||||
makeStyles,
|
||||
MenuItem,
|
||||
Select,
|
||||
} from '@material-ui/core';
|
||||
import { IChangeEvent } from '@rjsf/core';
|
||||
import CodeMirror from '@uiw/react-codemirror';
|
||||
import yaml from 'yaml';
|
||||
import { FieldExtensionOptions } from '../../extensions';
|
||||
import { TemplateParameterSchema } from '../../types';
|
||||
import { MultistepJsonForm } from '../MultistepJsonForm';
|
||||
import { createValidator } from '../TemplatePage';
|
||||
|
||||
const EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
required:
|
||||
- name
|
||||
properties:
|
||||
name:
|
||||
title: Name
|
||||
type: string
|
||||
description: Unique name of the component
|
||||
owner:
|
||||
title: Owner
|
||||
type: string
|
||||
description: Owner of the component
|
||||
ui:field: OwnerPicker
|
||||
ui:options:
|
||||
allowedKinds:
|
||||
- Group
|
||||
- title: Choose a location
|
||||
required:
|
||||
- repoUrl
|
||||
properties:
|
||||
repoUrl:
|
||||
title: Repository Location
|
||||
type: string
|
||||
ui:field: RepoUrlPicker
|
||||
ui:options:
|
||||
allowedHosts:
|
||||
- github.com
|
||||
`;
|
||||
|
||||
type TemplateOption = {
|
||||
label: string;
|
||||
value: Entity;
|
||||
};
|
||||
|
||||
const useStyles = makeStyles({
|
||||
templateSelect: {
|
||||
marginBottom: '10px',
|
||||
},
|
||||
grid: {
|
||||
height: '100%',
|
||||
},
|
||||
codeMirror: {
|
||||
height: '95%',
|
||||
},
|
||||
});
|
||||
|
||||
export const TemplatePreviewPage = ({
|
||||
defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML,
|
||||
customFieldExtensions = [],
|
||||
}: {
|
||||
defaultPreviewTemplate?: string;
|
||||
customFieldExtensions?: FieldExtensionOptions<any, any>[];
|
||||
}) => {
|
||||
const classes = useStyles();
|
||||
const alertApi = useApi(alertApiRef);
|
||||
const catalogApi = useApi(catalogApiRef);
|
||||
const apiHolder = useApiHolder();
|
||||
const [selectedTemplate, setSelectedTemplate] = useState('');
|
||||
const [schema, setSchema] = useState<TemplateParameterSchema>({
|
||||
title: '',
|
||||
steps: [],
|
||||
});
|
||||
const [templateOptions, setTemplateOptions] = useState<TemplateOption[]>([]);
|
||||
const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate);
|
||||
const [formState, setFormState] = useState({});
|
||||
|
||||
const { loading } = useAsync(
|
||||
() =>
|
||||
catalogApi
|
||||
.getEntities({
|
||||
filter: { kind: 'template' },
|
||||
fields: [
|
||||
'kind',
|
||||
'metadata.namespace',
|
||||
'metadata.name',
|
||||
'metadata.title',
|
||||
'spec.parameters',
|
||||
],
|
||||
})
|
||||
.then(({ items }) =>
|
||||
setTemplateOptions(
|
||||
items.map(template => ({
|
||||
label:
|
||||
template.metadata.title ??
|
||||
humanizeEntityRef(template, { defaultKind: 'template' }),
|
||||
value: template,
|
||||
})),
|
||||
),
|
||||
)
|
||||
.catch(e =>
|
||||
alertApi.post({
|
||||
message: `Error loading exisiting templates: ${e.message}`,
|
||||
severity: 'error',
|
||||
}),
|
||||
),
|
||||
[catalogApi],
|
||||
);
|
||||
|
||||
const errorPanel = document.createElement('div');
|
||||
errorPanel.style.color = 'red';
|
||||
|
||||
useDebounce(
|
||||
() => {
|
||||
try {
|
||||
const parsedTemplate = yaml.parse(templateYaml);
|
||||
|
||||
setSchema({
|
||||
title: 'Preview',
|
||||
steps: parsedTemplate.parameters.map((param: JsonObject) => ({
|
||||
title: param.title,
|
||||
schema: param,
|
||||
})),
|
||||
});
|
||||
setFormState({});
|
||||
} catch (e) {
|
||||
errorPanel.textContent = e.message;
|
||||
}
|
||||
},
|
||||
250,
|
||||
[setFormState, setSchema, templateYaml],
|
||||
);
|
||||
|
||||
const handleSelectChange = useCallback(
|
||||
selected => {
|
||||
setSelectedTemplate(selected);
|
||||
setTemplateYaml(yaml.stringify(selected.spec));
|
||||
},
|
||||
[setTemplateYaml],
|
||||
);
|
||||
|
||||
const handleFormReset = () => setFormState({});
|
||||
const handleFormChange = useCallback(
|
||||
(e: IChangeEvent) => setFormState(e.formData),
|
||||
[setFormState],
|
||||
);
|
||||
|
||||
const handleCodeChange = useCallback(
|
||||
(code: string) => {
|
||||
setTemplateYaml(code);
|
||||
},
|
||||
[setTemplateYaml],
|
||||
);
|
||||
|
||||
const customFieldComponents = Object.fromEntries(
|
||||
customFieldExtensions.map(({ name, component }) => [name, component]),
|
||||
);
|
||||
|
||||
const customFieldValidators = Object.fromEntries(
|
||||
customFieldExtensions.map(({ name, validation }) => [name, validation]),
|
||||
);
|
||||
|
||||
return (
|
||||
<Page themeId="home">
|
||||
<Header
|
||||
title="Template Preview"
|
||||
subtitle="Preview your template parameter UI"
|
||||
/>
|
||||
<Content>
|
||||
{loading && <LinearProgress />}
|
||||
<Grid container className={classes.grid}>
|
||||
<Grid item xs={6}>
|
||||
<FormControl
|
||||
className={classes.templateSelect}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
>
|
||||
<InputLabel id="select-template-label">
|
||||
Load Existing Template
|
||||
</InputLabel>
|
||||
<Select
|
||||
value={selectedTemplate}
|
||||
label="Load Existing Template"
|
||||
labelId="select-template-label"
|
||||
onChange={e => handleSelectChange(e.target.value)}
|
||||
>
|
||||
{templateOptions.map((option, idx) => (
|
||||
<MenuItem key={idx} value={option.value as any}>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<CodeMirror
|
||||
className={classes.codeMirror}
|
||||
value={templateYaml}
|
||||
theme="dark"
|
||||
height="100%"
|
||||
extensions={[
|
||||
StreamLanguage.define(yamlSupport),
|
||||
showPanel.of(() => ({ dom: errorPanel, top: true })),
|
||||
]}
|
||||
onChange={handleCodeChange}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
{schema && (
|
||||
<InfoCard key={JSON.stringify(schema)}>
|
||||
<MultistepJsonForm
|
||||
formData={formState}
|
||||
fields={customFieldComponents}
|
||||
onChange={handleFormChange}
|
||||
onReset={handleFormReset}
|
||||
steps={schema.steps.map(step => {
|
||||
return {
|
||||
...step,
|
||||
validate: createValidator(
|
||||
step.schema,
|
||||
customFieldValidators,
|
||||
{ apiHolder },
|
||||
),
|
||||
};
|
||||
})}
|
||||
/>
|
||||
</InfoCard>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { TemplatePreviewPage } from './TemplatePreviewPage';
|
||||
@@ -1295,10 +1295,10 @@
|
||||
core-js-pure "^3.20.2"
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
||||
version "7.17.2"
|
||||
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941"
|
||||
integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
||||
version "7.17.7"
|
||||
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825"
|
||||
integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
@@ -1568,6 +1568,91 @@
|
||||
exec-sh "^0.3.2"
|
||||
minimist "^1.2.0"
|
||||
|
||||
"@codemirror/autocomplete@^0.19.0":
|
||||
version "0.19.14"
|
||||
resolved "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-0.19.14.tgz#5f61b0fced56e7960791063d03b21d11a63f0ec5"
|
||||
integrity sha512-4PqJG7GGTePc+FQF387RFebDV4ERvKj23gQBmzNtu64ZSHlYEGulwP5EIIfulBiaWEmei9TYVaMFmTdNfofpRQ==
|
||||
dependencies:
|
||||
"@codemirror/language" "^0.19.0"
|
||||
"@codemirror/state" "^0.19.4"
|
||||
"@codemirror/text" "^0.19.2"
|
||||
"@codemirror/tooltip" "^0.19.12"
|
||||
"@codemirror/view" "^0.19.0"
|
||||
"@lezer/common" "^0.15.0"
|
||||
|
||||
"@codemirror/basic-setup@^0.19.1":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.npmjs.org/@codemirror/basic-setup/-/basic-setup-0.19.1.tgz#17b27d02f15c628eb62a85d01e3e1b1958933eb4"
|
||||
integrity sha512-gLjD7YgZU/we6BzS/ecCmD3viw83dsgv5ZUaSydYbYx9X4w4w9RqYnckcJ+0GDyHfNr5Jtfv2Z5ZtFQnBj0UDA==
|
||||
dependencies:
|
||||
"@codemirror/autocomplete" "^0.19.0"
|
||||
"@codemirror/closebrackets" "^0.19.0"
|
||||
"@codemirror/commands" "^0.19.0"
|
||||
"@codemirror/comment" "^0.19.0"
|
||||
"@codemirror/fold" "^0.19.0"
|
||||
"@codemirror/gutter" "^0.19.0"
|
||||
"@codemirror/highlight" "^0.19.0"
|
||||
"@codemirror/history" "^0.19.0"
|
||||
"@codemirror/language" "^0.19.0"
|
||||
"@codemirror/lint" "^0.19.0"
|
||||
"@codemirror/matchbrackets" "^0.19.0"
|
||||
"@codemirror/rectangular-selection" "^0.19.0"
|
||||
"@codemirror/search" "^0.19.0"
|
||||
"@codemirror/state" "^0.19.0"
|
||||
"@codemirror/view" "^0.19.31"
|
||||
|
||||
"@codemirror/closebrackets@^0.19.0":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.npmjs.org/@codemirror/closebrackets/-/closebrackets-0.19.1.tgz#c93219d6800c27a880e569135b468cf4a05d903f"
|
||||
integrity sha512-ZiLXT6u+VuBK5QnfBbt/Vmfd9Pg6449wn1DIOWFZHUOldg5eFn3VGGjYY2XWuHQz5WuK+7dXamV2KE885O1gyA==
|
||||
dependencies:
|
||||
"@codemirror/language" "^0.19.0"
|
||||
"@codemirror/rangeset" "^0.19.0"
|
||||
"@codemirror/state" "^0.19.2"
|
||||
"@codemirror/text" "^0.19.0"
|
||||
"@codemirror/view" "^0.19.44"
|
||||
|
||||
"@codemirror/commands@^0.19.0":
|
||||
version "0.19.8"
|
||||
resolved "https://registry.npmjs.org/@codemirror/commands/-/commands-0.19.8.tgz#1f99c1a8bf200d17c4d6997379099459f3678107"
|
||||
integrity sha512-65LIMSGUGGpY3oH6mzV46YWRrgao6NmfJ+AuC7jNz3K5NPnH6GCV1H5I6SwOFyVbkiygGyd0EFwrWqywTBD1aw==
|
||||
dependencies:
|
||||
"@codemirror/language" "^0.19.0"
|
||||
"@codemirror/matchbrackets" "^0.19.0"
|
||||
"@codemirror/state" "^0.19.2"
|
||||
"@codemirror/text" "^0.19.6"
|
||||
"@codemirror/view" "^0.19.22"
|
||||
"@lezer/common" "^0.15.0"
|
||||
|
||||
"@codemirror/comment@^0.19.0":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.npmjs.org/@codemirror/comment/-/comment-0.19.1.tgz#7def8345eeb9095ef1ef33676fbde1ab4fe33fad"
|
||||
integrity sha512-uGKteBuVWAC6fW+Yt8u27DOnXMT/xV4Ekk2Z5mRsiADCZDqYvryrJd6PLL5+8t64BVyocwQwNfz1UswYS2CtFQ==
|
||||
dependencies:
|
||||
"@codemirror/state" "^0.19.9"
|
||||
"@codemirror/text" "^0.19.0"
|
||||
"@codemirror/view" "^0.19.0"
|
||||
|
||||
"@codemirror/fold@^0.19.0":
|
||||
version "0.19.3"
|
||||
resolved "https://registry.npmjs.org/@codemirror/fold/-/fold-0.19.3.tgz#de55d44a7313f2a8920aefb6ebf9eff34715d8d4"
|
||||
integrity sha512-8hT+Eq2G68mL0yPRvSD2ewhnLQAX6sbUJmtGVKFcj8oAXtfpYCX8LIcfXsuI19Qs7gZkOSpqZvn+KKj8IhZoAw==
|
||||
dependencies:
|
||||
"@codemirror/gutter" "^0.19.0"
|
||||
"@codemirror/language" "^0.19.0"
|
||||
"@codemirror/rangeset" "^0.19.0"
|
||||
"@codemirror/state" "^0.19.0"
|
||||
"@codemirror/view" "^0.19.22"
|
||||
|
||||
"@codemirror/gutter@^0.19.0", "@codemirror/gutter@^0.19.4":
|
||||
version "0.19.9"
|
||||
resolved "https://registry.npmjs.org/@codemirror/gutter/-/gutter-0.19.9.tgz#bbb69f4d49570d9c1b3f3df5d134980c516cd42b"
|
||||
integrity sha512-PFrtmilahin1g6uL27aG5tM/rqR9DZzZYZsIrCXA5Uc2OFTFqx4owuhoU9hqfYxHp5ovfvBwQ+txFzqS4vog6Q==
|
||||
dependencies:
|
||||
"@codemirror/rangeset" "^0.19.0"
|
||||
"@codemirror/state" "^0.19.0"
|
||||
"@codemirror/view" "^0.19.23"
|
||||
|
||||
"@codemirror/highlight@^0.19.0":
|
||||
version "0.19.6"
|
||||
resolved "https://registry.npmjs.org/@codemirror/highlight/-/highlight-0.19.6.tgz#7f2e066f83f5649e8e0748a3abe0aaeaf64b8ac2"
|
||||
@@ -1580,6 +1665,14 @@
|
||||
"@lezer/common" "^0.15.0"
|
||||
style-mod "^4.0.0"
|
||||
|
||||
"@codemirror/history@^0.19.0":
|
||||
version "0.19.2"
|
||||
resolved "https://registry.npmjs.org/@codemirror/history/-/history-0.19.2.tgz#25e3fda755f77ac1223a6ae6e9d7899f5919265e"
|
||||
integrity sha512-unhP4t3N2smzmHoo/Yio6ueWi+il8gm9VKrvi6wlcdGH5fOfVDNkmjHQ495SiR+EdOG35+3iNebSPYww0vN7ow==
|
||||
dependencies:
|
||||
"@codemirror/state" "^0.19.2"
|
||||
"@codemirror/view" "^0.19.0"
|
||||
|
||||
"@codemirror/language@^0.19.0":
|
||||
version "0.19.7"
|
||||
resolved "https://registry.npmjs.org/@codemirror/language/-/language-0.19.7.tgz#9eef8e827692d93a701b18db9d46a42be34ecca6"
|
||||
@@ -1591,24 +1684,83 @@
|
||||
"@lezer/common" "^0.15.5"
|
||||
"@lezer/lr" "^0.15.0"
|
||||
|
||||
"@codemirror/rangeset@^0.19.0":
|
||||
version "0.19.2"
|
||||
resolved "https://registry.npmjs.org/@codemirror/rangeset/-/rangeset-0.19.2.tgz#d7a999e4273c00fecef4aba8535a426073cdcddf"
|
||||
integrity sha512-5d+X8LtmeZtfFtKrSx57bIHRUpKv2HD0b74clp4fGA7qJLLfYehF6FGkJJxJb8lKsqAga1gdjjWr0jiypmIxoQ==
|
||||
"@codemirror/legacy-modes@^0.19.0":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-0.19.1.tgz#7dc3b5df1842060648f75764ab6919fcfce3ea1a"
|
||||
integrity sha512-vYPLsD/ON+3SXhlGj9Qb3fpFNNU3Ya/AtDiv/g3OyqVzhh5vs5rAnOvk8xopGWRwppdhlNPD9VyXjiOmZUQtmQ==
|
||||
dependencies:
|
||||
"@codemirror/stream-parser" "^0.19.0"
|
||||
|
||||
"@codemirror/lint@^0.19.0":
|
||||
version "0.19.6"
|
||||
resolved "https://registry.npmjs.org/@codemirror/lint/-/lint-0.19.6.tgz#0379688da3e16739db4a6304c73db857ca85d7ec"
|
||||
integrity sha512-Pbw1Y5kHVs2J+itQ0uez3dI4qY9ApYVap7eNfV81x1/3/BXgBkKfadaw0gqJ4h4FDG7OnJwb0VbPsjJQllHjaA==
|
||||
dependencies:
|
||||
"@codemirror/gutter" "^0.19.4"
|
||||
"@codemirror/panel" "^0.19.0"
|
||||
"@codemirror/rangeset" "^0.19.1"
|
||||
"@codemirror/state" "^0.19.4"
|
||||
"@codemirror/tooltip" "^0.19.16"
|
||||
"@codemirror/view" "^0.19.22"
|
||||
crelt "^1.0.5"
|
||||
|
||||
"@codemirror/matchbrackets@^0.19.0":
|
||||
version "0.19.4"
|
||||
resolved "https://registry.npmjs.org/@codemirror/matchbrackets/-/matchbrackets-0.19.4.tgz#50b5188eb2d53f32598dca906bf5fd66626a9ebc"
|
||||
integrity sha512-VFkaOKPNudAA5sGP1zikRHCEKU0hjYmkKpr04pybUpQvfTvNJXlReCyP0rvH/1iEwAGPL990ZTT+QrLdu4MeEA==
|
||||
dependencies:
|
||||
"@codemirror/language" "^0.19.0"
|
||||
"@codemirror/state" "^0.19.0"
|
||||
"@codemirror/view" "^0.19.0"
|
||||
"@lezer/common" "^0.15.0"
|
||||
|
||||
"@codemirror/panel@^0.19.0", "@codemirror/panel@^0.19.1":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.npmjs.org/@codemirror/panel/-/panel-0.19.1.tgz#bf77d27b962cf16357139e50864d0eb69d634441"
|
||||
integrity sha512-sYeOCMA3KRYxZYJYn5PNlt9yNsjy3zTNTrbYSfVgjgL9QomIVgOJWPO5hZ2sTN8lufO6lw0vTBsIPL9MSidmBg==
|
||||
dependencies:
|
||||
"@codemirror/state" "^0.19.0"
|
||||
"@codemirror/view" "^0.19.0"
|
||||
|
||||
"@codemirror/rangeset@^0.19.0", "@codemirror/rangeset@^0.19.1", "@codemirror/rangeset@^0.19.5":
|
||||
version "0.19.9"
|
||||
resolved "https://registry.npmjs.org/@codemirror/rangeset/-/rangeset-0.19.9.tgz#e80895de93c39dc7899f5be31d368c9d88aa4efc"
|
||||
integrity sha512-V8YUuOvK+ew87Xem+71nKcqu1SXd5QROMRLMS/ljT5/3MCxtgrRie1Cvild0G/Z2f1fpWxzX78V0U4jjXBorBQ==
|
||||
dependencies:
|
||||
"@codemirror/state" "^0.19.0"
|
||||
|
||||
"@codemirror/state@^0.19.0", "@codemirror/state@^0.19.3":
|
||||
version "0.19.6"
|
||||
resolved "https://registry.npmjs.org/@codemirror/state/-/state-0.19.6.tgz#d631f041d39ce41b7891b099fca26cb1fdb9763e"
|
||||
integrity sha512-sqIQZE9VqwQj7D4c2oz9mfLhlT1ElAzGB5lO1lE33BPyrdNy1cJyCIOecT4cn4VeJOFrnjOeu+IftZ3zqdFETw==
|
||||
"@codemirror/rectangular-selection@^0.19.0":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.npmjs.org/@codemirror/rectangular-selection/-/rectangular-selection-0.19.1.tgz#5a88ece4fb68ce5682539497db8a64fc015aae63"
|
||||
integrity sha512-9ElnqOg3mpZIWe0prPRd1SZ48Q9QB3bR8Aocq8UtjboJSUG8ABhRrbuTZMW/rMqpBPSjVpCe9xkCCkEQMYQVmw==
|
||||
dependencies:
|
||||
"@codemirror/state" "^0.19.0"
|
||||
"@codemirror/text" "^0.19.4"
|
||||
"@codemirror/view" "^0.19.0"
|
||||
|
||||
"@codemirror/search@^0.19.0":
|
||||
version "0.19.9"
|
||||
resolved "https://registry.npmjs.org/@codemirror/search/-/search-0.19.9.tgz#b9548dfeb2028e6d5ecd1965f8f0ee50e2925603"
|
||||
integrity sha512-h3MuwbUbiyOp6Np3IB5r4LH0w4inZvbtLO1Ipmz8RhElcGRiYr11Q6Bim8ocLfe08RmZT6B5EkTj1E8eNlugQQ==
|
||||
dependencies:
|
||||
"@codemirror/panel" "^0.19.0"
|
||||
"@codemirror/rangeset" "^0.19.0"
|
||||
"@codemirror/state" "^0.19.3"
|
||||
"@codemirror/text" "^0.19.0"
|
||||
"@codemirror/view" "^0.19.34"
|
||||
crelt "^1.0.5"
|
||||
|
||||
"@codemirror/state@^0.19.0", "@codemirror/state@^0.19.2", "@codemirror/state@^0.19.3", "@codemirror/state@^0.19.4", "@codemirror/state@^0.19.9":
|
||||
version "0.19.9"
|
||||
resolved "https://registry.npmjs.org/@codemirror/state/-/state-0.19.9.tgz#b797f9fbc204d6dc7975485e231693c09001b0dd"
|
||||
integrity sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==
|
||||
dependencies:
|
||||
"@codemirror/text" "^0.19.0"
|
||||
|
||||
"@codemirror/stream-parser@^0.19.2":
|
||||
version "0.19.2"
|
||||
resolved "https://registry.npmjs.org/@codemirror/stream-parser/-/stream-parser-0.19.2.tgz#793428e55aa7b9daa64cb733973e5d5e3d9a2306"
|
||||
integrity sha512-hBKRQlyu8GUOrY33xZ6/1kAfNZ8ZUm6cX9a7mPx8zAAqnpz/fpksC/qJRrkg1mPMBwxm+JG4fqAwDGJ3gLVniQ==
|
||||
"@codemirror/stream-parser@^0.19.0", "@codemirror/stream-parser@^0.19.2", "@codemirror/stream-parser@^0.19.6":
|
||||
version "0.19.7"
|
||||
resolved "https://registry.npmjs.org/@codemirror/stream-parser/-/stream-parser-0.19.7.tgz#99a9696307b90677f6e3abe29ea6d77c1c0a8db5"
|
||||
integrity sha512-4ExcbKksmU4PIT8s11/dPESgMNLQqlMlbQzRQ1CyMcmygcuQk+58zQ84nv/X17OCUd2ephZ1DKEaHHACifzCiA==
|
||||
dependencies:
|
||||
"@codemirror/highlight" "^0.19.0"
|
||||
"@codemirror/language" "^0.19.0"
|
||||
@@ -1617,17 +1769,34 @@
|
||||
"@lezer/common" "^0.15.0"
|
||||
"@lezer/lr" "^0.15.0"
|
||||
|
||||
"@codemirror/text@^0.19.0":
|
||||
version "0.19.5"
|
||||
resolved "https://registry.npmjs.org/@codemirror/text/-/text-0.19.5.tgz#75033af2476214e79eae22b81ada618815441c18"
|
||||
integrity sha512-Syu5Xc7tZzeUAM/y4fETkT0zgGr48rDG+w4U38bPwSIUr+L9S/7w2wDE1WGNzjaZPz12F6gb1gxWiSTg9ocLow==
|
||||
"@codemirror/text@^0.19.0", "@codemirror/text@^0.19.2", "@codemirror/text@^0.19.4", "@codemirror/text@^0.19.6":
|
||||
version "0.19.6"
|
||||
resolved "https://registry.npmjs.org/@codemirror/text/-/text-0.19.6.tgz#9adcbd8137f69b75518eacd30ddb16fd67bbac45"
|
||||
integrity sha512-T9jnREMIygx+TPC1bOuepz18maGq/92q2a+n4qTqObKwvNMg+8cMTslb8yxeEDEq7S3kpgGWxgO1UWbQRij0dA==
|
||||
|
||||
"@codemirror/view@^0.19.0":
|
||||
version "0.19.27"
|
||||
resolved "https://registry.npmjs.org/@codemirror/view/-/view-0.19.27.tgz#76e5dc19ecb4ce53e9fef1d29245040d7ff64183"
|
||||
integrity sha512-Uz/LecEf7CyvMWaQBlKtbJCYn0hRnEZ2yYvuZVy9YMhmvGmES6ec7FaKw7lDFFOMLwLbBThc9kfw4DCHreHN1w==
|
||||
"@codemirror/theme-one-dark@^0.19.1":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-0.19.1.tgz#648b9cbe37186a2b7bd2a83fb483dc7aa18ce218"
|
||||
integrity sha512-8gc4c2k2o/EhyHoWkghCxp5vyDT96JaFGtRy35PHwIom0LZdx7aU4AbDUnITvwiFB+0+i54VO+WQjBqgTyJvqg==
|
||||
dependencies:
|
||||
"@codemirror/rangeset" "^0.19.0"
|
||||
"@codemirror/highlight" "^0.19.0"
|
||||
"@codemirror/state" "^0.19.0"
|
||||
"@codemirror/view" "^0.19.0"
|
||||
|
||||
"@codemirror/tooltip@^0.19.12", "@codemirror/tooltip@^0.19.16":
|
||||
version "0.19.16"
|
||||
resolved "https://registry.npmjs.org/@codemirror/tooltip/-/tooltip-0.19.16.tgz#6ba2c43f9d8e3d943d9d7bbae22bf800f7726a22"
|
||||
integrity sha512-zxKDHryUV5/RS45AQL+wOeN+i7/l81wK56OMnUPoTSzCWNITfxHn7BToDsjtrRKbzHqUxKYmBnn/4hPjpZ4WJQ==
|
||||
dependencies:
|
||||
"@codemirror/state" "^0.19.0"
|
||||
"@codemirror/view" "^0.19.0"
|
||||
|
||||
"@codemirror/view@^0.19.0", "@codemirror/view@^0.19.22", "@codemirror/view@^0.19.23", "@codemirror/view@^0.19.31", "@codemirror/view@^0.19.34", "@codemirror/view@^0.19.44", "@codemirror/view@^0.19.45":
|
||||
version "0.19.47"
|
||||
resolved "https://registry.npmjs.org/@codemirror/view/-/view-0.19.47.tgz#2163c3016d7680bf50dd695c0e3abdaf80f45363"
|
||||
integrity sha512-SfbagKvJQl5dtt+9wYpo9sa3ZkMgUxTq+/hXDf0KVwIx+zu3cJIqfEm9xSx6yXkq7it7RsPGHaPasApNffF/8g==
|
||||
dependencies:
|
||||
"@codemirror/rangeset" "^0.19.5"
|
||||
"@codemirror/state" "^0.19.3"
|
||||
"@codemirror/text" "^0.19.0"
|
||||
style-mod "^4.0.0"
|
||||
@@ -6757,6 +6926,17 @@
|
||||
"@typescript-eslint/types" "5.9.0"
|
||||
eslint-visitor-keys "^3.0.0"
|
||||
|
||||
"@uiw/react-codemirror@^4.5.1":
|
||||
version "4.5.1"
|
||||
resolved "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.5.1.tgz#f2af4e761f13b729a3ec7c7c858b34432cdf46a7"
|
||||
integrity sha512-90SNE89uJOQgcZwV0fuZjCgDeH7pjagCqwOcYHvDG5Qedp2nKmb4/2mgDCtLBxTGKxb73ktUOkbdu3L05ck1Yg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@codemirror/basic-setup" "^0.19.1"
|
||||
"@codemirror/state" "^0.19.9"
|
||||
"@codemirror/theme-one-dark" "^0.19.1"
|
||||
"@codemirror/view" "^0.19.45"
|
||||
|
||||
"@webassemblyjs/ast@1.11.1":
|
||||
version "1.11.1"
|
||||
resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7"
|
||||
@@ -9658,6 +9838,11 @@ create-require@^1.1.0:
|
||||
resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
|
||||
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
|
||||
|
||||
crelt@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz#57c0d52af8c859e354bace1883eb2e1eb182bb94"
|
||||
integrity sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA==
|
||||
|
||||
cron@^1.8.2:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.npmjs.org/cron/-/cron-1.8.2.tgz#4ac5e3c55ba8c163d84f3407bde94632da8370ce"
|
||||
|
||||
Reference in New Issue
Block a user