@raystack/chronicle 0.7.3 → 0.8.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 (46) hide show
  1. package/dist/cli/index.js +4 -1
  2. package/package.json +2 -1
  3. package/src/components/api/api-code-snippet.module.css +23 -0
  4. package/src/components/api/api-code-snippet.tsx +64 -0
  5. package/src/components/api/api-field-list.module.css +76 -0
  6. package/src/components/api/api-field-list.tsx +91 -0
  7. package/src/components/api/api-overview.module.css +65 -0
  8. package/src/components/api/api-overview.tsx +216 -0
  9. package/src/components/api/api-response-panel.module.css +62 -0
  10. package/src/components/api/api-response-panel.tsx +54 -0
  11. package/src/components/api/index.ts +5 -6
  12. package/src/components/api/json-editor.tsx +8 -8
  13. package/src/components/api/method-badge.tsx +2 -2
  14. package/src/components/api/playground-dialog.module.css +342 -0
  15. package/src/components/api/playground-dialog.tsx +583 -0
  16. package/src/lib/api-routes.ts +37 -8
  17. package/src/lib/openapi.ts +26 -0
  18. package/src/lib/schema.ts +45 -3
  19. package/src/lib/source.ts +57 -23
  20. package/src/lib/use-api-operation.ts +15 -0
  21. package/src/pages/ApiLayout.module.css +1 -0
  22. package/src/pages/ApiPage.tsx +7 -38
  23. package/src/pages/DocsPage.tsx +40 -1
  24. package/src/server/api/apis-proxy.ts +8 -1
  25. package/src/server/entry-server.tsx +2 -2
  26. package/src/server/routes/[...slug].md.ts +1 -0
  27. package/src/server/routes/apis/[...slug].md.ts +181 -0
  28. package/src/server/vite-config.ts +2 -0
  29. package/src/themes/default/Layout.module.css +53 -0
  30. package/src/themes/default/Layout.tsx +162 -11
  31. package/src/themes/paper/Page.module.css +7 -2
  32. package/src/themes/paper/Page.tsx +8 -6
  33. package/src/themes/paper/Skeleton.tsx +9 -0
  34. package/src/types/config.ts +1 -0
  35. package/src/components/api/code-snippets.module.css +0 -7
  36. package/src/components/api/code-snippets.tsx +0 -76
  37. package/src/components/api/endpoint-page.module.css +0 -58
  38. package/src/components/api/endpoint-page.tsx +0 -283
  39. package/src/components/api/field-row.module.css +0 -126
  40. package/src/components/api/field-row.tsx +0 -204
  41. package/src/components/api/field-section.module.css +0 -24
  42. package/src/components/api/field-section.tsx +0 -100
  43. package/src/components/api/key-value-editor.module.css +0 -13
  44. package/src/components/api/key-value-editor.tsx +0 -62
  45. package/src/components/api/response-panel.module.css +0 -8
  46. package/src/components/api/response-panel.tsx +0 -44
@@ -1,100 +0,0 @@
1
- 'use client'
2
-
3
- import { Flex, Text, Tabs, CodeBlock } from '@raystack/apsara'
4
- import type { SchemaField } from '@/lib/schema'
5
- import { FieldRow } from './field-row'
6
- import { JsonEditor } from './json-editor'
7
- import styles from './field-section.module.css'
8
-
9
- interface FieldSectionProps {
10
- title: string
11
- label?: string
12
- fields: SchemaField[]
13
- locations?: Record<string, string>
14
- jsonExample?: string
15
- editableJson?: boolean
16
- onJsonChange?: (value: string) => void
17
- alwaysShow?: boolean
18
- editable?: boolean
19
- values?: Record<string, unknown>
20
- onValuesChange?: (values: Record<string, unknown>) => void
21
- children?: React.ReactNode
22
- }
23
-
24
- export function FieldSection({
25
- title, label, fields, locations, jsonExample,
26
- editableJson, onJsonChange, alwaysShow,
27
- editable, values, onValuesChange, children,
28
- }: FieldSectionProps) {
29
- if (fields.length === 0 && !children && !alwaysShow) return null
30
-
31
- const fieldsContent = fields.length > 0 ? (
32
- <Flex direction="column">
33
- {fields.map((field) => (
34
- <FieldRow
35
- key={field.name}
36
- field={field}
37
- location={locations?.[field.name]}
38
- editable={editable}
39
- value={values?.[field.name]}
40
- onChange={editable ? (name, val) => {
41
- onValuesChange?.({ ...values, [name]: val })
42
- } : undefined}
43
- />
44
- ))}
45
- </Flex>
46
- ) : !children ? (
47
- <Text size={2} className={styles.noFields}>No fields defined</Text>
48
- ) : null
49
-
50
- if (jsonExample !== undefined || alwaysShow) {
51
- return (
52
- <Flex direction="column">
53
- <Flex align="center" justify="between" className={styles.header}>
54
- <Text size={4} weight="medium">{title}</Text>
55
- {label && <Text size={2} className={styles.label}>{label}</Text>}
56
- </Flex>
57
- <div className={styles.separator} />
58
- <Tabs defaultValue="fields" className={styles.tabs}>
59
- <Tabs.List>
60
- <Tabs.Tab value="fields">Fields</Tabs.Tab>
61
- <Tabs.Tab value="json">JSON</Tabs.Tab>
62
- </Tabs.List>
63
- <Tabs.Content value="fields">
64
- {fieldsContent}
65
- {children}
66
- </Tabs.Content>
67
- <Tabs.Content value="json">
68
- {editableJson ? (
69
- <JsonEditor
70
- value={jsonExample ?? '{}'}
71
- onChange={onJsonChange}
72
- />
73
- ) : (
74
- <CodeBlock>
75
- <CodeBlock.Header>
76
- <CodeBlock.CopyButton />
77
- </CodeBlock.Header>
78
- <CodeBlock.Content>
79
- <CodeBlock.Code language="json">{jsonExample ?? '{}'}</CodeBlock.Code>
80
- </CodeBlock.Content>
81
- </CodeBlock>
82
- )}
83
- </Tabs.Content>
84
- </Tabs>
85
- </Flex>
86
- )
87
- }
88
-
89
- return (
90
- <Flex direction="column">
91
- <Flex align="center" justify="between" className={styles.header}>
92
- <Text size={4} weight="medium">{title}</Text>
93
- {label && <Text size={2} className={styles.label}>{label}</Text>}
94
- </Flex>
95
- <div className={styles.separator} />
96
- {fieldsContent}
97
- {children}
98
- </Flex>
99
- )
100
- }
@@ -1,13 +0,0 @@
1
- .editor {
2
- padding: var(--rs-space-3) 0;
3
- }
4
-
5
- .row {
6
- width: 100%;
7
- }
8
-
9
- .input {
10
- flex: 1;
11
- min-width: 0;
12
- }
13
-
@@ -1,62 +0,0 @@
1
- 'use client'
2
-
3
- import { Flex, InputField, IconButton, Button } from '@raystack/apsara'
4
- import { TrashIcon, PlusIcon } from '@heroicons/react/24/outline'
5
- import styles from './key-value-editor.module.css'
6
-
7
- export interface KeyValueEntry {
8
- key: string
9
- value: string
10
- }
11
-
12
- interface KeyValueEditorProps {
13
- entries: KeyValueEntry[]
14
- onChange: (entries: KeyValueEntry[]) => void
15
- }
16
-
17
- export function KeyValueEditor({ entries, onChange }: KeyValueEditorProps) {
18
- const updateEntry = (index: number, field: 'key' | 'value', val: string) => {
19
- const updated = [...entries]
20
- updated[index] = { ...updated[index], [field]: val }
21
- onChange(updated)
22
- }
23
-
24
- const removeEntry = (index: number) => {
25
- onChange(entries.filter((_, i) => i !== index))
26
- }
27
-
28
- const addEntry = () => {
29
- onChange([...entries, { key: '', value: '' }])
30
- }
31
-
32
- return (
33
- <Flex direction="column" gap="small" className={styles.editor}>
34
- {entries.map((entry, i) => (
35
- <Flex key={i} align="center" gap="small" className={styles.row}>
36
- <div className={styles.input}>
37
- <InputField
38
- size="small"
39
- placeholder="Header name"
40
- value={entry.key}
41
- onChange={(e) => updateEntry(i, 'key', e.target.value)}
42
- />
43
- </div>
44
- <div className={styles.input}>
45
- <InputField
46
- size="small"
47
- placeholder="Value"
48
- value={entry.value}
49
- onChange={(e) => updateEntry(i, 'value', e.target.value)}
50
- />
51
- </div>
52
- <IconButton size={1} aria-label={`Delete ${entry.key || 'entry'}`} onClick={() => removeEntry(i)}>
53
- <TrashIcon width={14} height={14} />
54
- </IconButton>
55
- </Flex>
56
- ))}
57
- <Button variant="ghost" size="small" onClick={addEntry}>
58
- <PlusIcon width={14} height={14} /> Add header
59
- </Button>
60
- </Flex>
61
- )
62
- }
@@ -1,8 +0,0 @@
1
- .panel {
2
- width: 100%;
3
- }
4
-
5
- /* stylelint-disable-next-line selector-pseudo-class-no-unknown */
6
- .panel :global([class*="code-block-module_header"]) {
7
- justify-content: space-between;
8
- }
@@ -1,44 +0,0 @@
1
- 'use client'
2
-
3
- import { CodeBlock } from '@raystack/apsara'
4
- import styles from './response-panel.module.css'
5
-
6
- interface ResponsePanelProps {
7
- responses: {
8
- status: string
9
- description?: string
10
- jsonExample?: string
11
- }[]
12
- }
13
-
14
- export function ResponsePanel({ responses }: ResponsePanelProps) {
15
- const withExamples = responses.filter((r) => r.jsonExample)
16
- if (withExamples.length === 0) return null
17
-
18
- const defaultValue = withExamples[0].status
19
-
20
- return (
21
- <CodeBlock defaultValue={defaultValue} className={styles.panel}>
22
- <CodeBlock.Header>
23
- <CodeBlock.LanguageSelect>
24
- <CodeBlock.LanguageSelectTrigger />
25
- <CodeBlock.LanguageSelectContent>
26
- {withExamples.map((resp) => (
27
- <CodeBlock.LanguageSelectItem key={resp.status} value={resp.status}>
28
- {resp.status} {resp.description ?? resp.status}
29
- </CodeBlock.LanguageSelectItem>
30
- ))}
31
- </CodeBlock.LanguageSelectContent>
32
- </CodeBlock.LanguageSelect>
33
- <CodeBlock.CopyButton />
34
- </CodeBlock.Header>
35
- <CodeBlock.Content>
36
- {withExamples.map((resp) => (
37
- <CodeBlock.Code key={resp.status} value={resp.status} language="json">
38
- {resp.jsonExample!}
39
- </CodeBlock.Code>
40
- ))}
41
- </CodeBlock.Content>
42
- </CodeBlock>
43
- )
44
- }