Skip to content

Commit

Permalink
feat(*): expressions routes support [KM-20] (#1329)
Browse files Browse the repository at this point in the history
* feat(*): expressions routes support

* feat(entities-routes): i18n texts and tooltips

* feat(entities-routes): reduce dist size upper limit

* Revert "feat(entities-routes): reduce dist size upper limit"

This reverts commit 1dd5cd8.

* feat(entities-routes): use design tokens in style

* feat(*): tab hash, expr column, tests, slots, and slide-outs

Squashed from:

fix(entities-routes): tabs hash

feat(*): add prop to control expression column

fix(entities-routes): fix i18n and tab hashes

fix(entities-routes): tests

feat(entities-routes): slots

feat(entities-routes): expose more to the slot

feat(entities-routes): add setter func to slot

feat(entities-routes): adjust shape

fix(entities-routes): fix config slide out

* fix(*): remove umd, add tooltips for expr, fix tooltip

* fix(entities-routes): types
  • Loading branch information
sumimakito authored Apr 19, 2024
1 parent e374fa6 commit 55d2929
Show file tree
Hide file tree
Showing 30 changed files with 2,968 additions and 1,316 deletions.
6 changes: 2 additions & 4 deletions packages/core/expressions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "@kong-ui-public/expressions",
"version": "0.1.7",
"type": "module",
"main": "./dist/expressions.umd.js",
"module": "./dist/expressions.es.js",
"types": "dist/types/index.d.ts",
"files": [
Expand All @@ -11,7 +10,6 @@
"exports": {
".": {
"import": "./dist/expressions.es.js",
"require": "./dist/expressions.umd.js",
"types": "./dist/types/index.d.ts"
},
"./package.json": "./package.json",
Expand Down Expand Up @@ -42,7 +40,7 @@
"@kong/atc-router": "1.6.0-rc.1",
"@kong/design-tokens": "1.12.11",
"@kong/kongponents": "9.0.0-alpha.146",
"monaco-editor": "0.47.0",
"monaco-editor": "0.21.3",
"vite-plugin-monaco-editor": "^1.1.0",
"vite-plugin-top-level-await": "^1.4.1",
"vite-plugin-wasm": "^3.3.0",
Expand All @@ -68,7 +66,7 @@
"peerDependencies": {
"@kong/atc-router": "1.6.0-rc.1",
"@kong/kongponents": "9.0.0-alpha.105",
"monaco-editor": "0.47.0",
"monaco-editor": "0.21.3",
"vue": "^3.4.21"
},
"dependencies": {
Expand Down
10 changes: 5 additions & 5 deletions packages/core/expressions/src/components/ExpressionsEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@

<script setup lang="ts">
import { useDebounce } from '@kong-ui-public/core'
import type { ParseResult, Schema } from '@kong/atc-router'
import type { ParseResult, Schema as AtcSchema } from '@kong/atc-router'
import { Parser } from '@kong/atc-router'
import type * as Monaco from 'monaco-editor'
import * as monaco from 'monaco-editor'
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { createSchema, type NamedSchemaDefinition } from '../schema'
import { createSchema, type Schema } from '../schema'
import { registerLanguage, registerTheme, theme } from '../monaco'
let editor: Monaco.editor.IStandaloneCodeEditor | undefined
let editorModel: Monaco.editor.ITextModel
const parse = (expression:string, schema: Schema) => Parser.parse(expression, schema)
const parse = (expression:string, schema: AtcSchema) => Parser.parse(expression, schema)
const { debounce } = useDebounce()
const props = withDefaults(defineProps<{
schema: NamedSchemaDefinition,
schema: Schema,
parseDebounce?: number,
inactiveUntilFocused?: boolean,
}>(), {
Expand All @@ -45,7 +45,7 @@ const editorClass = computed(() => [
{ invalid: isParsingActive.value && parseResult.value?.status !== 'ok' },
])
const registerSchema = (schema: NamedSchemaDefinition) => {
const registerSchema = (schema: Schema) => {
const { languageId } = registerLanguage(schema)
monaco.editor.setModelLanguage(editorModel, languageId)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/expressions/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ExpressionsEditor from './components/ExpressionsEditor.vue'

export * from '@kong/atc-router'
export * as Atc from '@kong/atc-router'
export * from './schema'
export { ExpressionsEditor }

Expand Down
5 changes: 2 additions & 3 deletions packages/core/expressions/src/monaco.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as monaco from 'monaco-editor'
import { type NamedSchemaDefinition, type SchemaDefinition } from './schema'
import { type Schema, type SchemaDefinition } from './schema'

interface MonarchLanguage extends monaco.languages.IMonarchLanguage {
keywords: string[];
Expand Down Expand Up @@ -54,11 +54,10 @@ export const registerTheme = () => {
})
}

export const registerLanguage = (schema: NamedSchemaDefinition) => {
export const registerLanguage = (schema: Schema) => {
const languageId = getLanguageId(schema.name)

if (monaco.languages.getEncodedLanguageId(languageId) !== 0) {
console.warn(`Language "${languageId}" has already been registered`)
return { languageId }
}

Expand Down
27 changes: 14 additions & 13 deletions packages/core/expressions/src/schema.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Schema, type AstType } from '@kong/atc-router'
import { Schema as AtcSchema, type AstType } from '@kong/atc-router'

export type SchemaDefinition = {
[K in AstType]?: string[];
};

export interface NamedSchemaDefinition {
export interface Schema {
name: string;
definition: SchemaDefinition;
}

export const createSchema = (definition: SchemaDefinition) => {
const schema = new Schema()
const schema = new AtcSchema()

for (const [type, fields] of Object.entries(definition)) {
for (const field of fields) {
Expand Down Expand Up @@ -42,15 +42,16 @@ export const STREAM_SCHEMA_DEFINITION: SchemaDefinition = {
IpAddr: ['net.src.ip', 'net.dst.ip'],
}

export const PROTOCOL_TO_SCHEMA_DEFINITION = {
http: HTTP_SCHEMA_DEFINITION,
https: HTTP_SCHEMA_DEFINITION,
grpc: HTTP_SCHEMA_DEFINITION,
grpcs: HTTP_SCHEMA_DEFINITION,
export const PROTOCOL_TO_SCHEMA = (() => {
const s: Record<string, Schema> = {}

tcp: STREAM_SCHEMA_DEFINITION,
udp: STREAM_SCHEMA_DEFINITION,
tls: STREAM_SCHEMA_DEFINITION,
for (const protocol of ['http', 'https', 'grpc', 'grpcs', 'ws', 'wss']) {
s[protocol] = { name: protocol, definition: HTTP_SCHEMA_DEFINITION }
}

tls_passthrough: STREAM_SCHEMA_DEFINITION,
}
for (const protocol of ['tcp', 'udp', 'tls', 'tls_passthrough']) {
s[protocol] = { name: protocol, definition: STREAM_SCHEMA_DEFINITION }
}

return s
})()
3 changes: 2 additions & 1 deletion packages/core/expressions/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ const config = mergeConfig(sharedViteConfig, defineConfig({
promiseExportName: 'asyncInit',
}),
// We don't need this plugin to bundle the library. Only for sandbox previews.
// See: https://github.com/vdesjs/vite-plugin-monaco-editor/issues/21
...process.env.USE_SANDBOX
? [monacoEditorPlugin.default({})]
? [((monacoEditorPlugin as any).default as typeof monacoEditorPlugin)({})]
: [],
],
}))
Expand Down
56 changes: 54 additions & 2 deletions packages/entities/entities-routes/docs/route-form.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,42 @@ Show/hide Service Select field. Should be used in case of manual adding `service

Show tags field under _Advanced Fields_ collapse or in it's default place (before protocols field).

#### `routeFlavors`

- type: `RouteFlavors`
- required: `false`
- default: `{ traditional: true }`
- properties:
- `traditional`:
- type: `boolean`
- required: `false`
- default: `true`
- Whether to show input components for the traditional route.
- `expressions`:
- type: `boolean`
- required: `false`
- default: `false`
- Whether to show input components for the Expressions route.

#### `configTabTooltips`

- type: `Object as PropType<{ traditional?: string; expressions?: string } | undefined>`
- required: `false`
- default: `undefined`
- properties:
- `traditional`:
- type: `string`
- required: `false`
- default: `undefined`
- Text to show in the tooltip of the traditional config tab.

- `expressions`:
- type: `string`
- required: `false`
- default: `undefined`
- Text to show in the tooltip of the Expressions config tab.


### Slots

#### `form-actions`
Expand All @@ -135,6 +171,18 @@ Slot props:
- type: `Function`
- Cancel handler function.

#### `after-expressions-editor`

Content to be displayed after the Expressions editor.

Slot props:
- `expression`
- type: `[string, (value: string) => void]`
- The expression and a function to update the expression. This is useful when slot content is trying to update the expression (e.g., router playground).
- `state`
- type: `ExpressionsEditorState`
- The state of the editor.

### Events

#### error
Expand Down Expand Up @@ -174,10 +222,14 @@ import type {
MethodsFields,
Sources,
Destinations,
RouteStateFields,
BaseRouteStateFields,
TraditionalRouteStateFields,
ExpressionsRouteStateFields,
RouteState,
Headers,
RoutePayload,
BaseRoutePayload,
TraditionalRoutePayload,
ExpressionsRoutePayload,
SelectItem
} from '@kong-ui-public/entities-routes'
```
14 changes: 8 additions & 6 deletions packages/entities/entities-routes/docs/route-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,6 @@ A table component for routes.
- default: `undefined`
- A function that returns the route for editing a route.

- `useExpression`:
- type: `boolean`
- required: `false`
- default: `undefined`
- Whether to use expression flavored routes.

- `serviceId`:
- type: `string`
- required: `false`
Expand Down Expand Up @@ -164,6 +158,14 @@ The table is rendered inside a `KCard`. `title` text is displayed in the upper l

HTML element you want title to be rendered as. Defaults to `h2`.

#### `hasExpressionColumn`

- type: `boolean`
- required: `false`
- default: `false`

Whether to show the "Expression" column. Defaults to `false`.

### Events

#### error
Expand Down
72 changes: 46 additions & 26 deletions packages/entities/entities-routes/fixtures/mockData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,6 @@ export const routes: FetcherRawResponse = {
total: 2,
}

export const routes100: any[] = Array(100)
.fill(null)
.map((_, i) => ({
id: `${i + 1}`,
name: `route-${i + 1}`,
methods: ['GET'],
hosts: [`${i + 1}.example.com`],
}))

export const paginate = (
routes: any[],
size: number,
_offset: number,
): FetcherRawResponse => {
const sliced = routes.slice(_offset, _offset + size)
const offset =
_offset + size < routes.length ? String(_offset + size) : undefined

return {
data: sliced,
total: sliced.length,
offset,
}
}

export const services = [
{
id: '1',
Expand All @@ -59,12 +34,13 @@ export const services = [
},
]

// traditional
export const route = {
service: {
id: services[0].id,
},
id: '1',
name: 'route-1',
name: 'route-trad',
methods: ['GET', 'CASTOM'],
service_id: '',
tags: ['dev', 'test'],
Expand All @@ -77,3 +53,47 @@ export const route = {
paths: ['/foo', '/bar'],
headers: { Header1: ['cropped-jeans', 'expensive-petroleum'] },
}

// expressions
export const routeExpressions = {
service: {
id: services[0].id,
},
id: '1',
name: 'route-expr',
methods: ['GET', 'CASTOM'],
service_id: '',
tags: ['dev', 'test'],
preserve_host: true,
https_redirect_status_code: 426,
protocols: ['http', 'https'],
strip_path: false,
expression: 'http.path == "/kong"',
}

export const routesTraditional100: any[] = Array(100)
.fill(null)
.map((_, i) => ({
id: `${i + 1}`,
name: `route-${i + 1}`,
methods: ['GET'],
hosts: [`${i + 1}.example.com`],
}))

export const routesTraditionalExpressionsMixed = [route, routeExpressions]

export const paginate = (
routes: any[],
size: number,
_offset: number,
): FetcherRawResponse => {
const sliced = routes.slice(_offset, _offset + size)
const offset =
_offset + size < routes.length ? String(_offset + size) : undefined

return {
data: sliced,
total: sliced.length,
offset,
}
}
11 changes: 9 additions & 2 deletions packages/entities/entities-routes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@
"@kong-ui-public/i18n": "workspace:^",
"@kong/kongponents": "^9.0.0-alpha.146",
"axios": "^1.6.8",
"monaco-editor": "0.21.3",
"vue": ">= 3.3.13 < 4",
"vue-router": "^4.3.0"
},
"devDependencies": {
"@kong-ui-public/i18n": "workspace:^",
"@kong/design-tokens": "1.12.11",
"@kong/kongponents": "9.0.0-alpha.146",
"@types/lodash.isequal": "^4.5.8",
"axios": "^1.6.8",
"monaco-editor": "0.21.3",
"vite-plugin-monaco-editor": "^1.1.0",
"vue": "^3.4.21",
"vue-router": "^4.3.0"
},
Expand Down Expand Up @@ -65,9 +69,12 @@
"extends": "../../../package.json"
},
"distSizeChecker": {
"errorLimit": "700KB"
"errorLimit": "5000KB"
},
"dependencies": {
"@kong-ui-public/entities-shared": "workspace:^"
"@kong-ui-public/entities-shared": "workspace:^",
"@kong-ui-public/expressions": "workspace:^",
"@kong/icons": "^1.8.16",
"lodash.isequal": "^4.5.0"
}
}
Loading

0 comments on commit 55d2929

Please sign in to comment.