mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-04 08:38:34 +00:00
Compare commits
16 Commits
06-18-feat
...
v0.23.0-ca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4c20056a0 | ||
|
|
dfe4c22a75 | ||
|
|
ba718b955a | ||
|
|
09c3aa0a92 | ||
|
|
a4d929b19c | ||
|
|
c1691157f9 | ||
|
|
2366c1aba6 | ||
|
|
cdaaa52845 | ||
|
|
0785438cfe | ||
|
|
8f5851e8bf | ||
|
|
1fb68e3933 | ||
|
|
e118db4387 | ||
|
|
c0c813edfd | ||
|
|
4f75111055 | ||
|
|
3335f9bb00 | ||
|
|
566ff7470e |
76
.github/workflows/build-test.yml
vendored
76
.github/workflows/build-test.yml
vendored
@@ -27,26 +27,11 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
optimize_ci:
|
||||
name: Optimize CI
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
skip: ${{ steps.check_skip.outputs.skip }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Graphite CI Optimizer
|
||||
uses: withgraphite/graphite-ci-action@main
|
||||
id: check_skip
|
||||
with:
|
||||
graphite_token: ${{ secrets.GRAPHITE_CI_OPTIMIZER_TOKEN }}
|
||||
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=14384
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
@@ -80,9 +65,6 @@ jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-24.04-arm
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run oxlint
|
||||
@@ -108,8 +90,6 @@ jobs:
|
||||
typecheck:
|
||||
name: Typecheck
|
||||
runs-on: ubuntu-24.04-arm
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=14384
|
||||
steps:
|
||||
@@ -137,8 +117,6 @@ jobs:
|
||||
lint-rust:
|
||||
name: Lint Rust
|
||||
runs-on: ubuntu-latest
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/build-rust
|
||||
@@ -159,9 +137,7 @@ jobs:
|
||||
name: Check Git Status
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-server-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
@@ -197,8 +173,6 @@ jobs:
|
||||
check-yarn-binary:
|
||||
name: Check yarn binary
|
||||
runs-on: ubuntu-latest
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run check
|
||||
@@ -209,8 +183,6 @@ jobs:
|
||||
e2e-blocksuite-test:
|
||||
name: E2E BlockSuite Test
|
||||
runs-on: ubuntu-latest
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -242,8 +214,6 @@ jobs:
|
||||
e2e-blocksuite-cross-browser-test:
|
||||
name: E2E BlockSuite Cross Browser Test
|
||||
runs-on: ubuntu-latest
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -278,8 +248,6 @@ jobs:
|
||||
e2e-test:
|
||||
name: E2E Test
|
||||
runs-on: ubuntu-24.04-arm
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
DISTRIBUTION: web
|
||||
IN_CI_TEST: true
|
||||
@@ -312,8 +280,6 @@ jobs:
|
||||
e2e-mobile-test:
|
||||
name: E2E Mobile Test
|
||||
runs-on: ubuntu-latest
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
DISTRIBUTION: mobile
|
||||
IN_CI_TEST: true
|
||||
@@ -345,9 +311,7 @@ jobs:
|
||||
name: Unit Test
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
DISTRIBUTION: web
|
||||
strategy:
|
||||
@@ -384,8 +348,6 @@ jobs:
|
||||
build-native:
|
||||
name: Build AFFiNE native (${{ matrix.spec.target }})
|
||||
runs-on: ${{ matrix.spec.os }}
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
CARGO_PROFILE_RELEASE_DEBUG: '1'
|
||||
strategy:
|
||||
@@ -428,8 +390,6 @@ jobs:
|
||||
build-windows-native:
|
||||
name: Build AFFiNE native (${{ matrix.spec.target }})
|
||||
runs-on: ${{ matrix.spec.os }}
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
CARGO_PROFILE_RELEASE_DEBUG: '1'
|
||||
strategy:
|
||||
@@ -477,8 +437,6 @@ jobs:
|
||||
build-server-native:
|
||||
name: Build Server native
|
||||
runs-on: ubuntu-latest
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
CARGO_PROFILE_RELEASE_DEBUG: '1'
|
||||
steps:
|
||||
@@ -504,8 +462,6 @@ jobs:
|
||||
build-electron-renderer:
|
||||
name: Build @affine/electron renderer
|
||||
runs-on: ubuntu-latest
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
@@ -531,9 +487,7 @@ jobs:
|
||||
name: Native Unit Test
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
@@ -553,9 +507,7 @@ jobs:
|
||||
name: Server Test
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-server-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -628,9 +580,7 @@ jobs:
|
||||
name: Server Test with Elasticsearch
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-server-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
env:
|
||||
@@ -713,9 +663,7 @@ jobs:
|
||||
name: Server E2E Test
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-server-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
NODE_ENV: test
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
@@ -773,9 +721,6 @@ jobs:
|
||||
miri:
|
||||
name: miri code check
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
RUST_BACKTRACE: full
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -799,9 +744,6 @@ jobs:
|
||||
loom:
|
||||
name: loom thread test
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
RUSTFLAGS: --cfg loom
|
||||
RUST_BACKTRACE: full
|
||||
@@ -823,9 +765,6 @@ jobs:
|
||||
fuzzing:
|
||||
name: fuzzing
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
steps:
|
||||
@@ -872,9 +811,6 @@ jobs:
|
||||
- { target: 'aarch64-apple-darwin', os: 'macos-latest' }
|
||||
- { target: 'x86_64-pc-windows-msvc', os: 'windows-latest' }
|
||||
- { target: 'aarch64-pc-windows-msvc', os: 'windows-11-arm' }
|
||||
needs:
|
||||
- optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
@@ -908,8 +844,6 @@ jobs:
|
||||
rust-test:
|
||||
name: Run native tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
steps:
|
||||
@@ -930,9 +864,7 @@ jobs:
|
||||
name: Server Copilot Api Test
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-server-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
NODE_ENV: test
|
||||
DISTRIBUTION: web
|
||||
@@ -1114,10 +1046,8 @@ jobs:
|
||||
name: ${{ matrix.tests.name }}
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-server-native
|
||||
- build-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
DISTRIBUTION: web
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
@@ -1221,10 +1151,8 @@ jobs:
|
||||
name: Desktop Test (${{ matrix.spec.os }}, ${{ matrix.spec.platform }}, ${{ matrix.spec.arch }}, ${{ matrix.spec.target }}, ${{ matrix.spec.test }})
|
||||
runs-on: ${{ matrix.spec.os }}
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-electron-renderer
|
||||
- build-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -1319,10 +1247,8 @@ jobs:
|
||||
name: Desktop bundle check (${{ matrix.spec.os }}, ${{ matrix.spec.platform }}, ${{ matrix.spec.arch }}, ${{ matrix.spec.target }}, ${{ matrix.spec.test }})
|
||||
runs-on: ${{ matrix.spec.os }}
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-electron-renderer
|
||||
- build-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -1428,8 +1354,6 @@ jobs:
|
||||
|
||||
test-build-mobile-app:
|
||||
uses: ./.github/workflows/release-mobile.yml
|
||||
needs: optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
with:
|
||||
build-type: canary
|
||||
build-target: development
|
||||
|
||||
@@ -62,13 +62,11 @@ const builtinSurfaceToolbarConfig = {
|
||||
if (!rootModel) return;
|
||||
|
||||
const { id: frameId, xywh } = model;
|
||||
let lastNoteId = rootModel.children
|
||||
.filter(
|
||||
note =>
|
||||
matchModels(note, [NoteBlockModel]) &&
|
||||
note.props.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||
)
|
||||
.pop()?.id;
|
||||
let lastNoteId = rootModel.children.findLast(
|
||||
note =>
|
||||
matchModels(note, [NoteBlockModel]) &&
|
||||
note.props.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||
)?.id;
|
||||
|
||||
if (!lastNoteId) {
|
||||
const bounds = Bound.deserialize(xywh);
|
||||
|
||||
@@ -14,6 +14,7 @@ export class EdgelessNoteMask extends SignalWatcher(
|
||||
protected override firstUpdated() {
|
||||
const maskDOM = this.renderRoot!.querySelector('.affine-note-mask');
|
||||
const observer = new ResizeObserver(entries => {
|
||||
if (this.model.store.readonly) return;
|
||||
for (const entry of entries) {
|
||||
if (!this.model.props.edgeless.collapse) {
|
||||
const bound = Bound.deserialize(this.model.xywh);
|
||||
|
||||
@@ -11,6 +11,7 @@ import { property } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { keyed } from 'lit/directives/keyed.js';
|
||||
import type { ClassInfo } from 'lit-html/directives/class-map.js';
|
||||
import { ifDefined } from 'lit-html/directives/if-defined.js';
|
||||
|
||||
import { MenuFocusable } from './focusable.js';
|
||||
import type { Menu } from './menu.js';
|
||||
@@ -21,6 +22,7 @@ export type MenuButtonData = {
|
||||
class: ClassInfo;
|
||||
select: (ele: HTMLElement) => void | false;
|
||||
onHover?: (hover: boolean) => void;
|
||||
testId?: string;
|
||||
};
|
||||
|
||||
export class MenuButton extends MenuFocusable {
|
||||
@@ -97,7 +99,12 @@ export class MenuButton extends MenuFocusable {
|
||||
focused: this.isFocused$.value,
|
||||
...this.data.class,
|
||||
});
|
||||
return html` <div class="${classString}">${this.data.content()}</div>`;
|
||||
return html` <div
|
||||
class="${classString}"
|
||||
data-testid=${ifDefined(this.data.testId)}
|
||||
>
|
||||
${this.data.content()}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
@@ -157,7 +164,12 @@ export class MobileMenuButton extends MenuFocusable {
|
||||
focused: this.isFocused$.value,
|
||||
...this.data.class,
|
||||
});
|
||||
return html` <div class="${classString}">${this.data.content()}</div>`;
|
||||
return html` <div
|
||||
class="${classString}"
|
||||
data-testid=${ifDefined(this.data.testId)}
|
||||
>
|
||||
${this.data.content()}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
@@ -188,6 +200,7 @@ export const menuButtonItems = {
|
||||
onHover?: (hover: boolean) => void;
|
||||
class?: MenuClass;
|
||||
hide?: () => boolean;
|
||||
testId?: string;
|
||||
}) =>
|
||||
menu => {
|
||||
if (config.hide?.() || !menu.search(config.name)) {
|
||||
@@ -209,6 +222,7 @@ export const menuButtonItems = {
|
||||
'selected-item': config.isSelected ?? false,
|
||||
...config.class,
|
||||
},
|
||||
testId: config.testId,
|
||||
};
|
||||
return renderButton(data, menu);
|
||||
},
|
||||
@@ -220,6 +234,7 @@ export const menuButtonItems = {
|
||||
label?: () => TemplateResult;
|
||||
select: (checked: boolean) => boolean;
|
||||
class?: ClassInfo;
|
||||
testId?: string;
|
||||
}) =>
|
||||
menu => {
|
||||
if (!menu.search(config.name)) {
|
||||
@@ -240,6 +255,7 @@ export const menuButtonItems = {
|
||||
return false;
|
||||
},
|
||||
class: config.class ?? {},
|
||||
testId: config.testId,
|
||||
};
|
||||
return html`${keyed(config.name, renderButton(data, menu))}`;
|
||||
},
|
||||
@@ -247,10 +263,12 @@ export const menuButtonItems = {
|
||||
(config: {
|
||||
name: string;
|
||||
on: boolean;
|
||||
prefix?: TemplateResult;
|
||||
postfix?: TemplateResult;
|
||||
label?: () => TemplateResult;
|
||||
onChange: (on: boolean) => void;
|
||||
class?: ClassInfo;
|
||||
testId?: string;
|
||||
}) =>
|
||||
menu => {
|
||||
if (!menu.search(config.name)) {
|
||||
@@ -262,6 +280,7 @@ export const menuButtonItems = {
|
||||
|
||||
const data: MenuButtonData = {
|
||||
content: () => html`
|
||||
${config.prefix}
|
||||
<div class="affine-menu-action-text">
|
||||
${config.label?.() ?? config.name}
|
||||
</div>
|
||||
@@ -276,6 +295,7 @@ export const menuButtonItems = {
|
||||
return false;
|
||||
},
|
||||
class: config.class ?? {},
|
||||
testId: config.testId,
|
||||
};
|
||||
return html`${keyed(config.name, renderButton(data, menu))}`;
|
||||
},
|
||||
|
||||
@@ -23,6 +23,7 @@ export type MenuOptions = {
|
||||
placeholder?: string;
|
||||
};
|
||||
items: MenuConfig[];
|
||||
testId?: string;
|
||||
};
|
||||
|
||||
// Global menu open listener type
|
||||
@@ -72,6 +73,9 @@ export class Menu {
|
||||
? document.createElement('mobile-menu')
|
||||
: document.createElement('affine-menu');
|
||||
this.menuElement.menu = this;
|
||||
if (this.options.testId) {
|
||||
this.menuElement.dataset.testid = this.options.testId;
|
||||
}
|
||||
|
||||
// Call global menu open listeners
|
||||
menuOpenListeners.forEach(listener => {
|
||||
|
||||
@@ -111,6 +111,7 @@ export class FilterableListComponent<Props = unknown> extends WithDisposable(
|
||||
if (ev.isComposing) break;
|
||||
ev.preventDefault();
|
||||
const item = filteredItems[this._curFocusIndex];
|
||||
if (!item) return;
|
||||
this._select(item);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ export const selectPropertyModelConfig = selectPropertyType.modelConfig({
|
||||
const name = oldValue
|
||||
.split(',')
|
||||
.map(v => v.trim())
|
||||
.filter(v => v)[0];
|
||||
.find(v => v);
|
||||
if (!name) {
|
||||
return { value: null, data: data };
|
||||
}
|
||||
|
||||
@@ -40,13 +40,11 @@ export const groupToolbarConfig = {
|
||||
if (!rootModel) return;
|
||||
|
||||
const { id: groupId, xywh } = model;
|
||||
let lastNoteId = rootModel.children
|
||||
.filter(
|
||||
note =>
|
||||
matchModels(note, [NoteBlockModel]) &&
|
||||
note.props.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||
)
|
||||
.pop()?.id;
|
||||
let lastNoteId = rootModel.children.findLast(
|
||||
note =>
|
||||
matchModels(note, [NoteBlockModel]) &&
|
||||
note.props.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||
)?.id;
|
||||
|
||||
if (!lastNoteId) {
|
||||
const bounds = Bound.deserialize(xywh);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { SurfaceSelection } from '@blocksuite/std';
|
||||
import type { GetSelectionCommand } from './types';
|
||||
|
||||
export const getSurfaceSelectionCommand: GetSelectionCommand = (ctx, next) => {
|
||||
const currentSurfaceSelection = ctx.std.selection.filter(SurfaceSelection)[0];
|
||||
const currentSurfaceSelection = ctx.std.selection.find(SurfaceSelection);
|
||||
if (!currentSurfaceSelection) return;
|
||||
|
||||
next({ currentSurfaceSelection });
|
||||
|
||||
@@ -20,3 +20,7 @@
|
||||
|
||||
- [Store](classes/Store.md)
|
||||
- [StoreSlots](interfaces/StoreSlots.md)
|
||||
|
||||
## Other
|
||||
|
||||
- [Schema](classes/Schema.md)
|
||||
|
||||
297
blocksuite/docs/api/@blocksuite/store/classes/Schema.md
Normal file
297
blocksuite/docs/api/@blocksuite/store/classes/Schema.md
Normal file
@@ -0,0 +1,297 @@
|
||||
[**BlockSuite API Documentation**](../../../README.md)
|
||||
|
||||
***
|
||||
|
||||
[BlockSuite API Documentation](../../../README.md) / [@blocksuite/store](../README.md) / Schema
|
||||
|
||||
# Class: Schema
|
||||
|
||||
Represents a schema manager for block flavours and their relationships.
|
||||
Provides methods to register, validate, and query block schemas.
|
||||
|
||||
## Properties
|
||||
|
||||
### flavourSchemaMap
|
||||
|
||||
> `readonly` **flavourSchemaMap**: `Map`\<`string`, \{ `model`: \{ `children?`: `string`[]; `flavour`: `string`; `isFlatData?`: `boolean`; `parent?`: `string`[]; `props?`: (...`args`) => `Record`\<`string`, `any`\>; `role`: `string`; `toModel?`: (...`args`) => `BlockModel`\<`object`\>; \}; `transformer?`: (...`args`) => `BaseBlockTransformer`\<`object`\>; `version`: `number`; \}\>
|
||||
|
||||
A map storing block flavour names to their corresponding schema definitions.
|
||||
|
||||
## Accessors
|
||||
|
||||
### versions
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **versions**(): `object`
|
||||
|
||||
Returns an object mapping each registered flavour to its version number.
|
||||
|
||||
##### Returns
|
||||
|
||||
`object`
|
||||
|
||||
## Methods
|
||||
|
||||
### get()
|
||||
|
||||
> **get**(`flavour`): `undefined` \| \{ `model`: \{ `children?`: `string`[]; `flavour`: `string`; `isFlatData?`: `boolean`; `parent?`: `string`[]; `props?`: (...`args`) => `Record`\<`string`, `any`\>; `role`: `string`; `toModel?`: (...`args`) => `BlockModel`\<`object`\>; \}; `transformer?`: (...`args`) => `BaseBlockTransformer`\<`object`\>; `version`: `number`; \}
|
||||
|
||||
Retrieves the schema for a given block flavour.
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### flavour
|
||||
|
||||
`string`
|
||||
|
||||
The block flavour name.
|
||||
|
||||
#### Returns
|
||||
|
||||
`undefined` \| \{ `model`: \{ `children?`: `string`[]; `flavour`: `string`; `isFlatData?`: `boolean`; `parent?`: `string`[]; `props?`: (...`args`) => `Record`\<`string`, `any`\>; `role`: `string`; `toModel?`: (...`args`) => `BlockModel`\<`object`\>; \}; `transformer?`: (...`args`) => `BaseBlockTransformer`\<`object`\>; `version`: `number`; \}
|
||||
|
||||
The corresponding BlockSchemaType or undefined if not found.
|
||||
|
||||
***
|
||||
|
||||
### isValid()
|
||||
|
||||
> **isValid**(`child`, `parent`): `boolean`
|
||||
|
||||
Checks if the child flavour is valid under the parent flavour.
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### child
|
||||
|
||||
`string`
|
||||
|
||||
The child block flavour name.
|
||||
|
||||
##### parent
|
||||
|
||||
`string`
|
||||
|
||||
The parent block flavour name.
|
||||
|
||||
#### Returns
|
||||
|
||||
`boolean`
|
||||
|
||||
True if the relationship is valid, false otherwise.
|
||||
|
||||
***
|
||||
|
||||
### register()
|
||||
|
||||
> **register**(`blockSchema`): `Schema`
|
||||
|
||||
Registers an array of block schemas into the schema manager.
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### blockSchema
|
||||
|
||||
`object`[]
|
||||
|
||||
An array of block schema definitions to register.
|
||||
|
||||
#### Returns
|
||||
|
||||
`Schema`
|
||||
|
||||
The Schema instance (for chaining).
|
||||
|
||||
***
|
||||
|
||||
### safeValidate()
|
||||
|
||||
> **safeValidate**(`flavour`, `parentFlavour?`, `childFlavours?`): `boolean`
|
||||
|
||||
Safely validates the schema relationship for a given flavour, parent, and children.
|
||||
Returns true if valid, false otherwise (does not throw).
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### flavour
|
||||
|
||||
`string`
|
||||
|
||||
The block flavour to validate.
|
||||
|
||||
##### parentFlavour?
|
||||
|
||||
`string`
|
||||
|
||||
The parent block flavour (optional).
|
||||
|
||||
##### childFlavours?
|
||||
|
||||
`string`[]
|
||||
|
||||
The child block flavours (optional).
|
||||
|
||||
#### Returns
|
||||
|
||||
`boolean`
|
||||
|
||||
True if the schema relationship is valid, false otherwise.
|
||||
|
||||
***
|
||||
|
||||
### toJSON()
|
||||
|
||||
> **toJSON**(): `object`
|
||||
|
||||
Serializes the schema map to a plain object for JSON output.
|
||||
|
||||
#### Returns
|
||||
|
||||
`object`
|
||||
|
||||
An object mapping each flavour to its role, parent, and children.
|
||||
|
||||
***
|
||||
|
||||
### validate()
|
||||
|
||||
> **validate**(`flavour`, `parentFlavour?`, `childFlavours?`): `void`
|
||||
|
||||
Validates the schema relationship for a given flavour, parent, and children.
|
||||
Throws SchemaValidateError if invalid.
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### flavour
|
||||
|
||||
`string`
|
||||
|
||||
The block flavour to validate.
|
||||
|
||||
##### parentFlavour?
|
||||
|
||||
`string`
|
||||
|
||||
The parent block flavour (optional).
|
||||
|
||||
##### childFlavours?
|
||||
|
||||
`string`[]
|
||||
|
||||
The child block flavours (optional).
|
||||
|
||||
#### Returns
|
||||
|
||||
`void`
|
||||
|
||||
#### Throws
|
||||
|
||||
If the schema relationship is invalid.
|
||||
|
||||
***
|
||||
|
||||
### validateSchema()
|
||||
|
||||
> **validateSchema**(`child`, `parent`): `void`
|
||||
|
||||
Validates the relationship between a child and parent schema.
|
||||
Throws if the relationship is invalid.
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### child
|
||||
|
||||
The child block schema.
|
||||
|
||||
###### model
|
||||
|
||||
\{ `children?`: `string`[]; `flavour`: `string`; `isFlatData?`: `boolean`; `parent?`: `string`[]; `props?`: (...`args`) => `Record`\<`string`, `any`\>; `role`: `string`; `toModel?`: (...`args`) => `BlockModel`\<`object`\>; \} = `...`
|
||||
|
||||
###### model.children?
|
||||
|
||||
`string`[] = `ContentSchema`
|
||||
|
||||
###### model.flavour
|
||||
|
||||
`string` = `FlavourSchema`
|
||||
|
||||
###### model.isFlatData?
|
||||
|
||||
`boolean` = `...`
|
||||
|
||||
###### model.parent?
|
||||
|
||||
`string`[] = `ParentSchema`
|
||||
|
||||
###### model.props?
|
||||
|
||||
(...`args`) => `Record`\<`string`, `any`\> = `...`
|
||||
|
||||
###### model.role
|
||||
|
||||
`string` = `RoleSchema`
|
||||
|
||||
###### model.toModel?
|
||||
|
||||
(...`args`) => `BlockModel`\<`object`\> = `...`
|
||||
|
||||
###### transformer?
|
||||
|
||||
(...`args`) => `BaseBlockTransformer`\<`object`\> = `...`
|
||||
|
||||
###### version
|
||||
|
||||
`number` = `...`
|
||||
|
||||
##### parent
|
||||
|
||||
The parent block schema.
|
||||
|
||||
###### model
|
||||
|
||||
\{ `children?`: `string`[]; `flavour`: `string`; `isFlatData?`: `boolean`; `parent?`: `string`[]; `props?`: (...`args`) => `Record`\<`string`, `any`\>; `role`: `string`; `toModel?`: (...`args`) => `BlockModel`\<`object`\>; \} = `...`
|
||||
|
||||
###### model.children?
|
||||
|
||||
`string`[] = `ContentSchema`
|
||||
|
||||
###### model.flavour
|
||||
|
||||
`string` = `FlavourSchema`
|
||||
|
||||
###### model.isFlatData?
|
||||
|
||||
`boolean` = `...`
|
||||
|
||||
###### model.parent?
|
||||
|
||||
`string`[] = `ParentSchema`
|
||||
|
||||
###### model.props?
|
||||
|
||||
(...`args`) => `Record`\<`string`, `any`\> = `...`
|
||||
|
||||
###### model.role
|
||||
|
||||
`string` = `RoleSchema`
|
||||
|
||||
###### model.toModel?
|
||||
|
||||
(...`args`) => `BlockModel`\<`object`\> = `...`
|
||||
|
||||
###### transformer?
|
||||
|
||||
(...`args`) => `BaseBlockTransformer`\<`object`\> = `...`
|
||||
|
||||
###### version
|
||||
|
||||
`number` = `...`
|
||||
|
||||
#### Returns
|
||||
|
||||
`void`
|
||||
|
||||
#### Throws
|
||||
|
||||
If the relationship is invalid.
|
||||
@@ -1035,13 +1035,13 @@ Get the Doc instance for current store.
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **schema**(): `Schema`
|
||||
> **get** **schema**(): [`Schema`](Schema.md)
|
||||
|
||||
Get the Schema instance of the store.
|
||||
Get the [Schema](Schema.md) instance of the store.
|
||||
|
||||
##### Returns
|
||||
|
||||
`Schema`
|
||||
[`Schema`](Schema.md)
|
||||
|
||||
***
|
||||
|
||||
|
||||
@@ -4,9 +4,25 @@ import { SCHEMA_NOT_FOUND_MESSAGE } from '../consts.js';
|
||||
import { BlockSchema, type BlockSchemaType } from '../model/index.js';
|
||||
import { SchemaValidateError } from './error.js';
|
||||
|
||||
/**
|
||||
* Represents a schema manager for block flavours and their relationships.
|
||||
* Provides methods to register, validate, and query block schemas.
|
||||
*/
|
||||
export class Schema {
|
||||
/**
|
||||
* A map storing block flavour names to their corresponding schema definitions.
|
||||
*/
|
||||
readonly flavourSchemaMap = new Map<string, BlockSchemaType>();
|
||||
|
||||
/**
|
||||
* Safely validates the schema relationship for a given flavour, parent, and children.
|
||||
* Returns true if valid, false otherwise (does not throw).
|
||||
*
|
||||
* @param flavour - The block flavour to validate.
|
||||
* @param parentFlavour - The parent block flavour (optional).
|
||||
* @param childFlavours - The child block flavours (optional).
|
||||
* @returns True if the schema relationship is valid, false otherwise.
|
||||
*/
|
||||
safeValidate = (
|
||||
flavour: string,
|
||||
parentFlavour?: string,
|
||||
@@ -20,10 +36,25 @@ export class Schema {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the schema for a given block flavour.
|
||||
*
|
||||
* @param flavour - The block flavour name.
|
||||
* @returns The corresponding BlockSchemaType or undefined if not found.
|
||||
*/
|
||||
get(flavour: string) {
|
||||
return this.flavourSchemaMap.get(flavour);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the schema relationship for a given flavour, parent, and children.
|
||||
* Throws SchemaValidateError if invalid.
|
||||
*
|
||||
* @param flavour - The block flavour to validate.
|
||||
* @param parentFlavour - The parent block flavour (optional).
|
||||
* @param childFlavours - The child block flavours (optional).
|
||||
* @throws {SchemaValidateError} If the schema relationship is invalid.
|
||||
*/
|
||||
validate = (
|
||||
flavour: string,
|
||||
parentFlavour?: string,
|
||||
@@ -71,6 +102,9 @@ export class Schema {
|
||||
validateChildren();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an object mapping each registered flavour to its version number.
|
||||
*/
|
||||
get versions() {
|
||||
return Object.fromEntries(
|
||||
Array.from(this.flavourSchemaMap.values()).map(
|
||||
@@ -79,6 +113,13 @@ export class Schema {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if two flavours match, using minimatch for wildcard support.
|
||||
*
|
||||
* @param childFlavour - The child block flavour.
|
||||
* @param parentFlavour - The parent block flavour.
|
||||
* @returns True if the flavours match, false otherwise.
|
||||
*/
|
||||
private _matchFlavour(childFlavour: string, parentFlavour: string) {
|
||||
return (
|
||||
minimatch(childFlavour, parentFlavour) ||
|
||||
@@ -86,6 +127,15 @@ export class Schema {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if two values match as either flavours or roles, supporting role syntax (e.g., '@role').
|
||||
*
|
||||
* @param childValue - The child value (flavour or role).
|
||||
* @param parentValue - The parent value (flavour or role).
|
||||
* @param childRole - The actual role of the child.
|
||||
* @param parentRole - The actual role of the parent.
|
||||
* @returns True if the values match as flavours or roles, false otherwise.
|
||||
*/
|
||||
private _matchFlavourOrRole(
|
||||
childValue: string,
|
||||
parentValue: string,
|
||||
@@ -112,6 +162,13 @@ export class Schema {
|
||||
return this._matchFlavour(childValue, parentValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates if the parent schema is a valid parent for the child schema.
|
||||
*
|
||||
* @param child - The child block schema.
|
||||
* @param parent - The parent block schema.
|
||||
* @returns True if the parent is valid for the child, false otherwise.
|
||||
*/
|
||||
private _validateParent(
|
||||
child: BlockSchemaType,
|
||||
parent: BlockSchemaType
|
||||
@@ -169,6 +226,14 @@ export class Schema {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the role relationship between child and parent schemas.
|
||||
* Throws if the child is a root block but has a parent.
|
||||
*
|
||||
* @param child - The child block schema.
|
||||
* @param parent - The parent block schema.
|
||||
* @throws {SchemaValidateError} If the child is a root block with a parent.
|
||||
*/
|
||||
private _validateRole(child: BlockSchemaType, parent: BlockSchemaType) {
|
||||
const childRole = child.model.role;
|
||||
const childFlavour = child.model.flavour;
|
||||
@@ -182,6 +247,13 @@ export class Schema {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the child flavour is valid under the parent flavour.
|
||||
*
|
||||
* @param child - The child block flavour name.
|
||||
* @param parent - The parent block flavour name.
|
||||
* @returns True if the relationship is valid, false otherwise.
|
||||
*/
|
||||
isValid(child: string, parent: string) {
|
||||
const childSchema = this.flavourSchemaMap.get(child);
|
||||
const parentSchema = this.flavourSchemaMap.get(parent);
|
||||
@@ -196,6 +268,12 @@ export class Schema {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an array of block schemas into the schema manager.
|
||||
*
|
||||
* @param blockSchema - An array of block schema definitions to register.
|
||||
* @returns The Schema instance (for chaining).
|
||||
*/
|
||||
register(blockSchema: BlockSchemaType[]) {
|
||||
blockSchema.forEach(schema => {
|
||||
BlockSchema.parse(schema);
|
||||
@@ -204,6 +282,11 @@ export class Schema {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the schema map to a plain object for JSON output.
|
||||
*
|
||||
* @returns An object mapping each flavour to its role, parent, and children.
|
||||
*/
|
||||
toJSON() {
|
||||
return Object.fromEntries(
|
||||
Array.from(this.flavourSchemaMap.values()).map(
|
||||
@@ -219,6 +302,14 @@ export class Schema {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the relationship between a child and parent schema.
|
||||
* Throws if the relationship is invalid.
|
||||
*
|
||||
* @param child - The child block schema.
|
||||
* @param parent - The parent block schema.
|
||||
* @throws {SchemaValidateError} If the relationship is invalid.
|
||||
*/
|
||||
validateSchema(child: BlockSchemaType, parent: BlockSchemaType) {
|
||||
this._validateRole(child, parent);
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^16.0.0",
|
||||
"msw": "^2.6.8",
|
||||
"oxlint": "0.16.11",
|
||||
"oxlint": "^1.1.0",
|
||||
"prettier": "^3.4.2",
|
||||
"semver": "^7.6.3",
|
||||
"serve": "^14.2.4",
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
"c8": "^10.1.3",
|
||||
"nodemon": "^3.1.7",
|
||||
"react-email": "4.0.11",
|
||||
"sinon": "^20.0.0",
|
||||
"sinon": "^21.0.0",
|
||||
"supertest": "^7.0.0",
|
||||
"why-is-node-running": "^3.2.2"
|
||||
},
|
||||
|
||||
Binary file not shown.
@@ -12,6 +12,7 @@ export type MockDocSnapshotInput = {
|
||||
docId?: string;
|
||||
blob?: Uint8Array;
|
||||
updatedAt?: Date;
|
||||
snapshotFile?: string;
|
||||
};
|
||||
|
||||
export type MockedDocSnapshot = Snapshot;
|
||||
@@ -23,7 +24,10 @@ export class MockDocSnapshot extends Mocker<
|
||||
override async create(input: MockDocSnapshotInput) {
|
||||
if (!input.blob) {
|
||||
const snapshot = await readFile(
|
||||
path.join(import.meta.dirname, '../__fixtures__/test-doc.snapshot.bin')
|
||||
path.join(
|
||||
import.meta.dirname,
|
||||
`../__fixtures__/${input.snapshotFile ?? 'test-doc.snapshot.bin'}`
|
||||
)
|
||||
);
|
||||
input.blob = snapshot;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ export class SocketIoAdapter extends IoAdapter {
|
||||
const server: Server = super.createIOServer(port, {
|
||||
...config,
|
||||
...options,
|
||||
// Enable CORS for Socket.IO
|
||||
cors: {
|
||||
origin: true, // Allow all origins
|
||||
credentials: true, // Allow credentials (cookies, auth headers)
|
||||
methods: ['GET', 'POST'],
|
||||
},
|
||||
});
|
||||
|
||||
if (config.canActivate) {
|
||||
|
||||
@@ -646,6 +646,93 @@ Generated by [AVA](https://avajs.dev).
|
||||
title: 'Write, Draw, Plan all at Once.',
|
||||
}
|
||||
|
||||
## can read blob filename from doc snapshot
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
{
|
||||
blocks: [
|
||||
{
|
||||
additional: {
|
||||
displayMode: 'edgeless',
|
||||
},
|
||||
blockId: '4YHKIhPzAK',
|
||||
content: 'index file name',
|
||||
docId: 'doc-0',
|
||||
flavour: 'affine:page',
|
||||
yblock: {
|
||||
'prop:title': 'index file name',
|
||||
'sys:children': [
|
||||
'WypcCGdupE',
|
||||
'hZ1-cdLW5e',
|
||||
],
|
||||
'sys:flavour': 'affine:page',
|
||||
'sys:id': '4YHKIhPzAK',
|
||||
'sys:version': 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
additional: {
|
||||
displayMode: 'edgeless',
|
||||
},
|
||||
blockId: 'WypcCGdupE',
|
||||
content: [],
|
||||
docId: 'doc-0',
|
||||
flavour: 'affine:surface',
|
||||
parentBlockId: '4YHKIhPzAK',
|
||||
parentFlavour: 'affine:page',
|
||||
yblock: {
|
||||
'prop:elements': {
|
||||
type: '$blocksuite:internal:native$',
|
||||
value: {},
|
||||
},
|
||||
'sys:children': [],
|
||||
'sys:flavour': 'affine:surface',
|
||||
'sys:id': 'WypcCGdupE',
|
||||
'sys:version': 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
additional: {
|
||||
displayMode: 'page',
|
||||
noteBlockId: 'hZ1-cdLW5e',
|
||||
},
|
||||
blob: [
|
||||
'ldZMrM4PDlsNG4Q4YvCsz623h6TKu4qI9_FpTqIypfw=',
|
||||
],
|
||||
blockId: 'tfz1yFZdnn',
|
||||
content: 'test file name here.txt',
|
||||
docId: 'doc-0',
|
||||
flavour: 'affine:attachment',
|
||||
parentBlockId: 'hZ1-cdLW5e',
|
||||
parentFlavour: 'affine:note',
|
||||
yblock: {
|
||||
'prop:embed': false,
|
||||
'prop:footnoteIdentifier': null,
|
||||
'prop:index': 'a0',
|
||||
'prop:lockedBySelf': false,
|
||||
'prop:meta:createdAt': 1750036953927,
|
||||
'prop:meta:createdBy': '46ce597c-098a-4c61-a106-ce79827ec1de',
|
||||
'prop:meta:updatedAt': 1750036953928,
|
||||
'prop:meta:updatedBy': '46ce597c-098a-4c61-a106-ce79827ec1de',
|
||||
'prop:name': 'test file name here.txt',
|
||||
'prop:rotate': 0,
|
||||
'prop:size': 3,
|
||||
'prop:sourceId': 'ldZMrM4PDlsNG4Q4YvCsz623h6TKu4qI9_FpTqIypfw=',
|
||||
'prop:style': 'horizontalThin',
|
||||
'prop:type': 'text/plain',
|
||||
'prop:xywh': '[0,0,0,0]',
|
||||
'sys:children': [],
|
||||
'sys:flavour': 'affine:attachment',
|
||||
'sys:id': 'tfz1yFZdnn',
|
||||
'sys:version': 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
summary: '',
|
||||
title: 'index file name',
|
||||
}
|
||||
|
||||
## can read all blocks from doc snapshot without workspace snapshot
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
Binary file not shown.
@@ -56,6 +56,23 @@ test('can read all blocks from doc snapshot', async t => {
|
||||
});
|
||||
});
|
||||
|
||||
test('can read blob filename from doc snapshot', async t => {
|
||||
const docSnapshot = await module.create(Mockers.DocSnapshot, {
|
||||
workspaceId: workspace.id,
|
||||
user: owner,
|
||||
snapshotFile: 'test-doc-with-blob.snapshot.bin',
|
||||
});
|
||||
|
||||
const result = await readAllBlocksFromDocSnapshot(
|
||||
workspace.id,
|
||||
'doc-0',
|
||||
docSnapshot.blob
|
||||
);
|
||||
|
||||
// NOTE: avoid snapshot result directly, because it will cause hanging
|
||||
t.snapshot(JSON.parse(JSON.stringify(result)));
|
||||
});
|
||||
|
||||
test('can read all blocks from doc snapshot without workspace snapshot', async t => {
|
||||
const doc = await models.doc.get(workspace.id, docSnapshot.id);
|
||||
t.truthy(doc);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Injectable, OnApplicationBootstrap } from '@nestjs/common';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
|
||||
import {
|
||||
Cache,
|
||||
@@ -15,8 +16,6 @@ import {
|
||||
Models,
|
||||
} from '../../../models';
|
||||
import { type EmbeddingClient, getEmbeddingClient } from '../embedding';
|
||||
import { PromptService } from '../prompt';
|
||||
import { CopilotProviderFactory } from '../providers';
|
||||
import { ContextSession } from './session';
|
||||
|
||||
const CONTEXT_SESSION_KEY = 'context-session';
|
||||
@@ -27,10 +26,9 @@ export class CopilotContextService implements OnApplicationBootstrap {
|
||||
private client: EmbeddingClient | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly moduleRef: ModuleRef,
|
||||
private readonly cache: Cache,
|
||||
private readonly models: Models,
|
||||
private readonly providerFactory: CopilotProviderFactory,
|
||||
private readonly prompt: PromptService
|
||||
private readonly models: Models
|
||||
) {}
|
||||
|
||||
@OnEvent('config.init')
|
||||
@@ -44,7 +42,7 @@ export class CopilotContextService implements OnApplicationBootstrap {
|
||||
}
|
||||
|
||||
private async setup() {
|
||||
this.client = await getEmbeddingClient(this.providerFactory, this.prompt);
|
||||
this.client = await getEmbeddingClient(this.moduleRef);
|
||||
}
|
||||
|
||||
async onApplicationBootstrap() {
|
||||
@@ -165,7 +163,7 @@ export class CopilotContextService implements OnApplicationBootstrap {
|
||||
);
|
||||
if (!fileChunks.length) return [];
|
||||
|
||||
return this.embeddingClient.reRank(content, fileChunks, topK, signal);
|
||||
return await this.embeddingClient.reRank(content, fileChunks, topK, signal);
|
||||
}
|
||||
|
||||
async matchWorkspaceDocs(
|
||||
@@ -188,7 +186,48 @@ export class CopilotContextService implements OnApplicationBootstrap {
|
||||
);
|
||||
if (!workspaceChunks.length) return [];
|
||||
|
||||
return this.embeddingClient.reRank(content, workspaceChunks, topK, signal);
|
||||
return await this.embeddingClient.reRank(
|
||||
content,
|
||||
workspaceChunks,
|
||||
topK,
|
||||
signal
|
||||
);
|
||||
}
|
||||
|
||||
async matchWorkspaceAll(
|
||||
workspaceId: string,
|
||||
content: string,
|
||||
topK: number = 5,
|
||||
signal?: AbortSignal,
|
||||
threshold: number = 0.5
|
||||
) {
|
||||
if (!this.embeddingClient) return [];
|
||||
const embedding = await this.embeddingClient.getEmbedding(content, signal);
|
||||
if (!embedding) return [];
|
||||
|
||||
const [fileChunks, workspaceChunks] = await Promise.all([
|
||||
this.models.copilotWorkspace.matchFileEmbedding(
|
||||
workspaceId,
|
||||
embedding,
|
||||
topK * 2,
|
||||
threshold
|
||||
),
|
||||
this.models.copilotContext.matchWorkspaceEmbedding(
|
||||
embedding,
|
||||
workspaceId,
|
||||
topK * 2,
|
||||
threshold
|
||||
),
|
||||
]);
|
||||
|
||||
if (!fileChunks.length && !workspaceChunks.length) return [];
|
||||
|
||||
return await this.embeddingClient.reRank(
|
||||
content,
|
||||
[...fileChunks, ...workspaceChunks],
|
||||
topK,
|
||||
signal
|
||||
);
|
||||
}
|
||||
|
||||
@OnEvent('workspace.doc.embed.failed')
|
||||
|
||||
@@ -234,6 +234,7 @@ export class CopilotController implements BeforeApplicationShutdown {
|
||||
...session.config.promptConfig,
|
||||
signal: this.getSignal(req),
|
||||
user: user.id,
|
||||
workspace: session.config.workspaceId,
|
||||
reasoning,
|
||||
webSearch,
|
||||
});
|
||||
@@ -304,6 +305,7 @@ export class CopilotController implements BeforeApplicationShutdown {
|
||||
...session.config.promptConfig,
|
||||
signal: this.getSignal(req),
|
||||
user: user.id,
|
||||
workspace: session.config.workspaceId,
|
||||
reasoning,
|
||||
webSearch,
|
||||
})
|
||||
@@ -378,6 +380,7 @@ export class CopilotController implements BeforeApplicationShutdown {
|
||||
...session.config.promptConfig,
|
||||
signal: this.getSignal(req),
|
||||
user: user.id,
|
||||
workspace: session.config.workspaceId,
|
||||
})
|
||||
).pipe(
|
||||
connect(shared$ =>
|
||||
@@ -500,6 +503,7 @@ export class CopilotController implements BeforeApplicationShutdown {
|
||||
seed: this.parseNumber(params.seed),
|
||||
signal: this.getSignal(req),
|
||||
user: user.id,
|
||||
workspace: session.config.workspaceId,
|
||||
}
|
||||
)
|
||||
).pipe(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
import type { ModuleRef } from '@nestjs/core';
|
||||
|
||||
import {
|
||||
CopilotPromptNotFound,
|
||||
@@ -193,12 +194,16 @@ class ProductionEmbeddingClient extends EmbeddingClient {
|
||||
|
||||
let EMBEDDING_CLIENT: EmbeddingClient | undefined;
|
||||
export async function getEmbeddingClient(
|
||||
providerFactory: CopilotProviderFactory,
|
||||
prompt: PromptService
|
||||
moduleRef: ModuleRef
|
||||
): Promise<EmbeddingClient | undefined> {
|
||||
if (EMBEDDING_CLIENT) {
|
||||
return EMBEDDING_CLIENT;
|
||||
}
|
||||
const providerFactory = moduleRef.get(CopilotProviderFactory, {
|
||||
strict: false,
|
||||
});
|
||||
const prompt = moduleRef.get(PromptService, { strict: false });
|
||||
|
||||
const client = new ProductionEmbeddingClient(providerFactory, prompt);
|
||||
if (await client.configured()) {
|
||||
EMBEDDING_CLIENT = client;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
|
||||
import {
|
||||
AFFiNELogger,
|
||||
@@ -14,8 +15,6 @@ import {
|
||||
} from '../../../base';
|
||||
import { DocReader } from '../../../core/doc';
|
||||
import { Models } from '../../../models';
|
||||
import { PromptService } from '../prompt';
|
||||
import { CopilotProviderFactory } from '../providers';
|
||||
import { CopilotStorage } from '../storage';
|
||||
import { readStream } from '../utils';
|
||||
import { getEmbeddingClient } from './client';
|
||||
@@ -31,12 +30,11 @@ export class CopilotEmbeddingJob {
|
||||
private client: EmbeddingClient | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly moduleRef: ModuleRef,
|
||||
private readonly doc: DocReader,
|
||||
private readonly event: EventBus,
|
||||
private readonly logger: AFFiNELogger,
|
||||
private readonly models: Models,
|
||||
private readonly providerFactory: CopilotProviderFactory,
|
||||
private readonly prompt: PromptService,
|
||||
private readonly queue: JobQueue,
|
||||
private readonly storage: CopilotStorage
|
||||
) {
|
||||
@@ -57,7 +55,7 @@ export class CopilotEmbeddingJob {
|
||||
this.supportEmbedding =
|
||||
await this.models.copilotContext.checkEmbeddingAvailable();
|
||||
if (this.supportEmbedding) {
|
||||
this.client = await getEmbeddingClient(this.providerFactory, this.prompt);
|
||||
this.client = await getEmbeddingClient(this.moduleRef);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1791,7 +1791,13 @@ Below is the user's query. Please respond in the user's preferred language witho
|
||||
},
|
||||
],
|
||||
config: {
|
||||
tools: ['webSearch'],
|
||||
tools: [
|
||||
'docRead',
|
||||
'docEdit',
|
||||
'docKeywordSearch',
|
||||
'docSemanticSearch',
|
||||
'webSearch',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
metrics,
|
||||
UserFriendlyError,
|
||||
} from '../../../../base';
|
||||
import { createExaCrawlTool, createExaSearchTool } from '../../tools';
|
||||
import { CopilotProvider } from '../provider';
|
||||
import type {
|
||||
CopilotChatOptions,
|
||||
@@ -68,7 +67,7 @@ export abstract class AnthropicProvider<T> extends CopilotProvider<T> {
|
||||
providerOptions: {
|
||||
anthropic: this.getAnthropicOptions(options, model.id),
|
||||
},
|
||||
tools: this.getTools(),
|
||||
tools: await this.getTools(options, model.id),
|
||||
maxSteps: this.MAX_STEPS,
|
||||
experimental_continueSteps: true,
|
||||
});
|
||||
@@ -103,7 +102,7 @@ export abstract class AnthropicProvider<T> extends CopilotProvider<T> {
|
||||
providerOptions: {
|
||||
anthropic: this.getAnthropicOptions(options, model.id),
|
||||
},
|
||||
tools: this.getTools(),
|
||||
tools: await this.getTools(options, model.id),
|
||||
maxSteps: this.MAX_STEPS,
|
||||
experimental_continueSteps: true,
|
||||
});
|
||||
@@ -123,13 +122,6 @@ export abstract class AnthropicProvider<T> extends CopilotProvider<T> {
|
||||
}
|
||||
}
|
||||
|
||||
private getTools() {
|
||||
return {
|
||||
web_search_exa: createExaSearchTool(this.AFFiNEConfig),
|
||||
web_crawl_exa: createExaCrawlTool(this.AFFiNEConfig),
|
||||
};
|
||||
}
|
||||
|
||||
private getAnthropicOptions(options: CopilotChatOptions, model: string) {
|
||||
const result: AnthropicProviderOptions = {};
|
||||
if (options?.reasoning && this.isReasoningModel(model)) {
|
||||
|
||||
@@ -180,7 +180,7 @@ export class FalProvider extends CopilotProvider<FalConfig> {
|
||||
? v.attachment
|
||||
: undefined
|
||||
)
|
||||
.filter(v => !!v)[0],
|
||||
.find(v => !!v),
|
||||
prompt: content.trim(),
|
||||
loras: lora.length ? lora : undefined,
|
||||
controlnets: controlnets.length ? controlnets : undefined,
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
generateObject,
|
||||
generateText,
|
||||
streamText,
|
||||
ToolSet,
|
||||
Tool,
|
||||
} from 'ai';
|
||||
import { z } from 'zod';
|
||||
|
||||
@@ -21,10 +21,10 @@ import {
|
||||
metrics,
|
||||
UserFriendlyError,
|
||||
} from '../../../base';
|
||||
import { createExaCrawlTool, createExaSearchTool } from '../tools';
|
||||
import { CopilotProvider } from './provider';
|
||||
import type {
|
||||
CopilotChatOptions,
|
||||
CopilotChatTools,
|
||||
CopilotEmbeddingOptions,
|
||||
CopilotImageOptions,
|
||||
CopilotStructuredOptions,
|
||||
@@ -248,25 +248,14 @@ export class OpenAIProvider extends CopilotProvider<OpenAIConfig> {
|
||||
}
|
||||
}
|
||||
|
||||
private getTools(options: CopilotChatOptions, model: string): ToolSet {
|
||||
const tools: ToolSet = {};
|
||||
if (options?.tools?.length) {
|
||||
for (const tool of options.tools) {
|
||||
switch (tool) {
|
||||
case 'webSearch': {
|
||||
if (this.isReasoningModel(model)) {
|
||||
tools.web_search_exa = createExaSearchTool(this.AFFiNEConfig);
|
||||
tools.web_crawl_exa = createExaCrawlTool(this.AFFiNEConfig);
|
||||
} else {
|
||||
tools.web_search_preview = openai.tools.webSearchPreview();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tools;
|
||||
override getProviderSpecificTools(
|
||||
toolName: CopilotChatTools,
|
||||
model: string
|
||||
): [string, Tool] | undefined {
|
||||
if (toolName === 'webSearch' && !this.isReasoningModel(model)) {
|
||||
return ['web_search_preview', openai.tools.webSearchPreview()];
|
||||
}
|
||||
return tools;
|
||||
return;
|
||||
}
|
||||
|
||||
async text(
|
||||
@@ -297,7 +286,7 @@ export class OpenAIProvider extends CopilotProvider<OpenAIConfig> {
|
||||
providerOptions: {
|
||||
openai: this.getOpenAIOptions(options, model.id),
|
||||
},
|
||||
tools: this.getTools(options, model.id),
|
||||
tools: await this.getTools(options, model.id),
|
||||
maxSteps: this.MAX_STEPS,
|
||||
abortSignal: options.signal,
|
||||
});
|
||||
@@ -338,7 +327,7 @@ export class OpenAIProvider extends CopilotProvider<OpenAIConfig> {
|
||||
providerOptions: {
|
||||
openai: this.getOpenAIOptions(options, model.id),
|
||||
},
|
||||
tools: this.getTools(options, model.id),
|
||||
tools: await this.getTools(options, model.id),
|
||||
maxSteps: this.MAX_STEPS,
|
||||
abortSignal: options.signal,
|
||||
});
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
import { Tool, ToolSet } from 'ai';
|
||||
import { z } from 'zod';
|
||||
|
||||
import {
|
||||
@@ -7,9 +9,18 @@ import {
|
||||
CopilotProviderNotSupported,
|
||||
OnEvent,
|
||||
} from '../../../base';
|
||||
import { AccessController } from '../../../core/permission';
|
||||
import { CopilotContextService } from '../context';
|
||||
import {
|
||||
buildDocSearchGetter,
|
||||
createDocSemanticSearchTool,
|
||||
createExaCrawlTool,
|
||||
createExaSearchTool,
|
||||
} from '../tools';
|
||||
import { CopilotProviderFactory } from './factory';
|
||||
import {
|
||||
type CopilotChatOptions,
|
||||
CopilotChatTools,
|
||||
type CopilotEmbeddingOptions,
|
||||
type CopilotImageOptions,
|
||||
CopilotProviderModel,
|
||||
@@ -33,6 +44,7 @@ export abstract class CopilotProvider<C = any> {
|
||||
|
||||
@Inject() protected readonly AFFiNEConfig!: Config;
|
||||
@Inject() protected readonly factory!: CopilotProviderFactory;
|
||||
@Inject() protected readonly moduleRef!: ModuleRef;
|
||||
|
||||
get config(): C {
|
||||
return this.AFFiNEConfig.copilot.providers[this.type] as C;
|
||||
@@ -98,6 +110,50 @@ export abstract class CopilotProvider<C = any> {
|
||||
);
|
||||
}
|
||||
|
||||
protected getProviderSpecificTools(
|
||||
_toolName: CopilotChatTools,
|
||||
_model: string
|
||||
): [string, Tool] | undefined {
|
||||
return;
|
||||
}
|
||||
|
||||
// use for tool use, shared between providers
|
||||
protected async getTools(
|
||||
options: CopilotChatOptions,
|
||||
model: string
|
||||
): Promise<ToolSet> {
|
||||
const tools: ToolSet = {};
|
||||
if (options?.tools?.length) {
|
||||
for (const tool of options.tools) {
|
||||
const toolDef = this.getProviderSpecificTools(tool, model);
|
||||
if (toolDef) {
|
||||
tools[toolDef[0]] = toolDef[1];
|
||||
continue;
|
||||
}
|
||||
switch (tool) {
|
||||
case 'docSemanticSearch': {
|
||||
const ac = this.moduleRef.get(AccessController, { strict: false });
|
||||
const context = this.moduleRef.get(CopilotContextService, {
|
||||
strict: false,
|
||||
});
|
||||
const searchDocs = buildDocSearchGetter(ac, context);
|
||||
tools.doc_semantic_search = createDocSemanticSearchTool(
|
||||
searchDocs.bind(null, options)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'webSearch': {
|
||||
tools.web_search_exa = createExaSearchTool(this.AFFiNEConfig);
|
||||
tools.web_crawl_exa = createExaCrawlTool(this.AFFiNEConfig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tools;
|
||||
}
|
||||
return tools;
|
||||
}
|
||||
|
||||
private handleZodError(ret: z.SafeParseReturnType<any, any>) {
|
||||
if (ret.success) return;
|
||||
const issues = ret.error.issues.map(i => {
|
||||
|
||||
@@ -57,7 +57,21 @@ export const VertexSchema: JSONSchema = {
|
||||
// ========== prompt ==========
|
||||
|
||||
export const PromptConfigStrictSchema = z.object({
|
||||
tools: z.enum(['webSearch']).array().nullable().optional(),
|
||||
tools: z
|
||||
.enum([
|
||||
// work with morph
|
||||
'docEdit',
|
||||
// work with indexer
|
||||
'docRead',
|
||||
'docKeywordSearch',
|
||||
// work with embeddings
|
||||
'docSemanticSearch',
|
||||
// work with exa/model internal tools
|
||||
'webSearch',
|
||||
])
|
||||
.array()
|
||||
.nullable()
|
||||
.optional(),
|
||||
// params requirements
|
||||
requireContent: z.boolean().nullable().optional(),
|
||||
requireAttachment: z.boolean().nullable().optional(),
|
||||
@@ -121,6 +135,7 @@ export type PromptParams = NonNullable<PromptMessage['params']>;
|
||||
const CopilotProviderOptionsSchema = z.object({
|
||||
signal: z.instanceof(AbortSignal).optional(),
|
||||
user: z.string().optional(),
|
||||
workspace: z.string().optional(),
|
||||
});
|
||||
|
||||
export const CopilotChatOptionsSchema = CopilotProviderOptionsSchema.merge(
|
||||
@@ -133,6 +148,9 @@ export const CopilotChatOptionsSchema = CopilotProviderOptionsSchema.merge(
|
||||
.optional();
|
||||
|
||||
export type CopilotChatOptions = z.infer<typeof CopilotChatOptionsSchema>;
|
||||
export type CopilotChatTools = NonNullable<
|
||||
NonNullable<CopilotChatOptions>['tools']
|
||||
>[number];
|
||||
|
||||
export const CopilotStructuredOptionsSchema =
|
||||
CopilotProviderOptionsSchema.merge(PromptConfigStrictSchema).optional();
|
||||
|
||||
@@ -9,7 +9,11 @@ import {
|
||||
} from 'ai';
|
||||
import { ZodType } from 'zod';
|
||||
|
||||
import { createExaCrawlTool, createExaSearchTool } from '../tools';
|
||||
import {
|
||||
createDocSemanticSearchTool,
|
||||
createExaCrawlTool,
|
||||
createExaSearchTool,
|
||||
} from '../tools';
|
||||
import { PromptMessage } from './types';
|
||||
|
||||
type ChatMessage = CoreUserMessage | CoreAssistantMessage;
|
||||
@@ -376,6 +380,7 @@ export class CitationParser {
|
||||
}
|
||||
|
||||
export interface CustomAITools extends ToolSet {
|
||||
doc_semantic_search: ReturnType<typeof createDocSemanticSearchTool>;
|
||||
web_search_exa: ReturnType<typeof createExaSearchTool>;
|
||||
web_crawl_exa: ReturnType<typeof createExaCrawlTool>;
|
||||
}
|
||||
@@ -424,6 +429,12 @@ export class TextStreamParser {
|
||||
case 'tool-result': {
|
||||
result = this.addPrefix(result);
|
||||
switch (chunk.toolName) {
|
||||
case 'doc_semantic_search': {
|
||||
if (Array.isArray(chunk.result)) {
|
||||
result += `\nFound ${chunk.result.length} document${chunk.result.length !== 1 ? 's' : ''} related to “${chunk.args.query}”.\n`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'web_search_exa': {
|
||||
if (Array.isArray(chunk.result)) {
|
||||
result += `\n${this.getWebSearchLinks(chunk.result)}\n`;
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import { tool } from 'ai';
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { AccessController } from '../../../core/permission';
|
||||
import type { ChunkSimilarity } from '../../../models';
|
||||
import type { CopilotContextService } from '../context';
|
||||
import type { CopilotChatOptions } from '../providers';
|
||||
|
||||
export const buildDocSearchGetter = (
|
||||
ac: AccessController,
|
||||
context: CopilotContextService
|
||||
) => {
|
||||
const searchDocs = async (options: CopilotChatOptions, query?: string) => {
|
||||
if (!options || !query?.trim() || !options.user || !options.workspace) {
|
||||
return undefined;
|
||||
}
|
||||
const canAccess = await ac
|
||||
.user(options.user)
|
||||
.workspace(options.workspace)
|
||||
.can('Workspace.Read');
|
||||
if (!canAccess) return undefined;
|
||||
const chunks = await context.matchWorkspaceAll(options.workspace, query);
|
||||
const docChunks = await ac
|
||||
.user(options.user)
|
||||
.workspace(options.workspace)
|
||||
.docs(
|
||||
chunks.filter(c => 'docId' in c),
|
||||
'Doc.Read'
|
||||
);
|
||||
const fileChunks = chunks.filter(c => 'fileId' in c);
|
||||
if (!docChunks.length && !fileChunks.length) return undefined;
|
||||
return [...fileChunks, ...docChunks];
|
||||
};
|
||||
return searchDocs;
|
||||
};
|
||||
|
||||
export const createDocSemanticSearchTool = (
|
||||
searchDocs: (query: string) => Promise<ChunkSimilarity[] | undefined>
|
||||
) => {
|
||||
return tool({
|
||||
description:
|
||||
'Semantic search for relevant documents in the current workspace',
|
||||
parameters: z.object({
|
||||
query: z.string().describe('The query to search for.'),
|
||||
}),
|
||||
execute: async ({ query }) => {
|
||||
try {
|
||||
return await searchDocs(query);
|
||||
} catch {
|
||||
return 'Failed to search documents.';
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -1 +1,2 @@
|
||||
export * from './doc-semantic-search';
|
||||
export * from './web-search';
|
||||
|
||||
@@ -494,3 +494,30 @@ Generated by [AVA](https://avajs.dev).
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
## should search blob names from doc snapshot work
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
Map {
|
||||
'ldZMrM4PDlsNG4Q4YvCsz623h6TKu4qI9_FpTqIypfw=' => 'test file name here.txt',
|
||||
}
|
||||
|
||||
## should search blob names work
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
[
|
||||
[
|
||||
'blob1',
|
||||
'blob1 name.txt',
|
||||
],
|
||||
[
|
||||
'blob2',
|
||||
'blob2 name.md',
|
||||
],
|
||||
[
|
||||
'blob3',
|
||||
'blob3 name.docx',
|
||||
],
|
||||
]
|
||||
|
||||
Binary file not shown.
@@ -2113,3 +2113,103 @@ test('should index doc work', async t => {
|
||||
t.is(module.event.count('doc.indexer.updated'), count + 1);
|
||||
});
|
||||
// #endregion
|
||||
|
||||
// #region searchBlobNames()
|
||||
|
||||
test('should search blob names from doc snapshot work', async t => {
|
||||
const docSnapshot = await module.create(Mockers.DocSnapshot, {
|
||||
workspaceId: workspace.id,
|
||||
user,
|
||||
snapshotFile: 'test-doc-with-blob.snapshot.bin',
|
||||
});
|
||||
|
||||
await indexerService.indexDoc(workspace.id, docSnapshot.id, {
|
||||
refresh: true,
|
||||
});
|
||||
|
||||
const blobNameMap = await indexerService.searchBlobNames(workspace.id, [
|
||||
'ldZMrM4PDlsNG4Q4YvCsz623h6TKu4qI9_FpTqIypfw=',
|
||||
]);
|
||||
|
||||
t.snapshot(blobNameMap);
|
||||
});
|
||||
|
||||
test('should search blob names work', async t => {
|
||||
const workspaceId = randomUUID();
|
||||
const blobId1 = 'blob1';
|
||||
const blobId2 = 'blob2';
|
||||
const blobId3 = 'blob3';
|
||||
const blobId4 = 'blob4';
|
||||
|
||||
await indexerService.write(
|
||||
SearchTable.block,
|
||||
[
|
||||
{
|
||||
workspaceId,
|
||||
blob: blobId1,
|
||||
content: 'blob1 name.txt',
|
||||
flavour: 'affine:attachment',
|
||||
docId: randomUUID(),
|
||||
blockId: randomUUID(),
|
||||
createdByUserId: user.id,
|
||||
updatedByUserId: user.id,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
{
|
||||
workspaceId,
|
||||
blob: blobId2,
|
||||
content: 'blob2 name.md',
|
||||
flavour: 'affine:attachment',
|
||||
docId: randomUUID(),
|
||||
blockId: randomUUID(),
|
||||
createdByUserId: user.id,
|
||||
updatedByUserId: user.id,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
{
|
||||
workspaceId,
|
||||
blob: blobId3,
|
||||
content: 'blob3 name.docx',
|
||||
flavour: 'affine:attachment',
|
||||
docId: randomUUID(),
|
||||
blockId: randomUUID(),
|
||||
createdByUserId: user.id,
|
||||
updatedByUserId: user.id,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
// no attachment
|
||||
{
|
||||
workspaceId,
|
||||
blob: blobId3,
|
||||
content: 'mock blob3 content',
|
||||
flavour: 'affine:page',
|
||||
docId: randomUUID(),
|
||||
blockId: randomUUID(),
|
||||
createdByUserId: user.id,
|
||||
updatedByUserId: user.id,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
],
|
||||
{
|
||||
refresh: true,
|
||||
}
|
||||
);
|
||||
|
||||
const blobNameMap = await indexerService.searchBlobNames(workspaceId, [
|
||||
blobId1,
|
||||
blobId2,
|
||||
blobId3,
|
||||
blobId4,
|
||||
]);
|
||||
|
||||
t.is(blobNameMap.size, 3);
|
||||
t.snapshot(
|
||||
Array.from(blobNameMap.entries()).sort((a, b) => a[0].localeCompare(b[0]))
|
||||
);
|
||||
});
|
||||
|
||||
// #endregion
|
||||
|
||||
@@ -387,6 +387,52 @@ export class IndexerService {
|
||||
await searchProvider.deleteByQuery(table, dsl, options);
|
||||
}
|
||||
|
||||
async searchBlobNames(workspaceId: string, blobIds: string[]) {
|
||||
const result = await this.search({
|
||||
table: SearchTable.block,
|
||||
query: {
|
||||
type: SearchQueryType.boolean,
|
||||
occur: SearchQueryOccur.must,
|
||||
queries: [
|
||||
{
|
||||
type: SearchQueryType.match,
|
||||
field: 'workspaceId',
|
||||
match: workspaceId,
|
||||
},
|
||||
{
|
||||
type: SearchQueryType.match,
|
||||
field: 'flavour',
|
||||
match: 'affine:attachment',
|
||||
},
|
||||
{
|
||||
type: SearchQueryType.boolean,
|
||||
occur: SearchQueryOccur.should,
|
||||
queries: blobIds.map(blobId => ({
|
||||
type: SearchQueryType.match,
|
||||
field: 'blob',
|
||||
match: blobId,
|
||||
})),
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
fields: ['blob', 'content'],
|
||||
pagination: {
|
||||
limit: 10000,
|
||||
},
|
||||
},
|
||||
});
|
||||
const blobNameMap = new Map<string, string>();
|
||||
for (const node of result.nodes) {
|
||||
const blobId = node.fields.blob[0] as string;
|
||||
const content = node.fields.content[0] as string;
|
||||
if (blobId && content) {
|
||||
blobNameMap.set(blobId, content);
|
||||
}
|
||||
}
|
||||
return blobNameMap;
|
||||
}
|
||||
|
||||
#formatSearchNodes(nodes: SearchNode[]) {
|
||||
return nodes.map(node => ({
|
||||
...node,
|
||||
|
||||
@@ -15,7 +15,7 @@ export const passwordLimitsFragment = `fragment PasswordLimits on PasswordLimits
|
||||
minLength
|
||||
maxLength
|
||||
}`;
|
||||
export const licenseFragment = `fragment license on License {
|
||||
export const licenseBodyFragment = `fragment licenseBody on License {
|
||||
expiredAt
|
||||
installedAt
|
||||
quantity
|
||||
@@ -1443,10 +1443,10 @@ export const activateLicenseMutation = {
|
||||
op: 'activateLicense',
|
||||
query: `mutation activateLicense($workspaceId: String!, $license: String!) {
|
||||
activateLicense(workspaceId: $workspaceId, license: $license) {
|
||||
...license
|
||||
...licenseBody
|
||||
}
|
||||
}
|
||||
${licenseFragment}`,
|
||||
${licenseBodyFragment}`,
|
||||
};
|
||||
|
||||
export const deactivateLicenseMutation = {
|
||||
@@ -1463,11 +1463,11 @@ export const getLicenseQuery = {
|
||||
query: `query getLicense($workspaceId: String!) {
|
||||
workspace(id: $workspaceId) {
|
||||
license {
|
||||
...license
|
||||
...licenseBody
|
||||
}
|
||||
}
|
||||
}
|
||||
${licenseFragment}`,
|
||||
${licenseBodyFragment}`,
|
||||
};
|
||||
|
||||
export const installLicenseMutation = {
|
||||
@@ -1475,10 +1475,10 @@ export const installLicenseMutation = {
|
||||
op: 'installLicense',
|
||||
query: `mutation installLicense($workspaceId: String!, $license: Upload!) {
|
||||
installLicense(workspaceId: $workspaceId, license: $license) {
|
||||
...license
|
||||
...licenseBody
|
||||
}
|
||||
}
|
||||
${licenseFragment}`,
|
||||
${licenseBodyFragment}`,
|
||||
file: true,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#import './license.gql'
|
||||
#import './license-body.gql'
|
||||
|
||||
mutation activateLicense($workspaceId: String!, $license: String!) {
|
||||
activateLicense(workspaceId: $workspaceId, license: $license) {
|
||||
...license
|
||||
...licenseBody
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
#import './license.gql'
|
||||
#import './license-body.gql'
|
||||
|
||||
query getLicense($workspaceId: String!) {
|
||||
workspace(id: $workspaceId) {
|
||||
license {
|
||||
...license
|
||||
...licenseBody
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#import './license.gql'
|
||||
#import './license-body.gql'
|
||||
|
||||
mutation installLicense($workspaceId: String!, $license: Upload!) {
|
||||
installLicense(workspaceId: $workspaceId, license: $license) {
|
||||
...license
|
||||
...licenseBody
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
fragment license on License {
|
||||
fragment licenseBody on License {
|
||||
expiredAt
|
||||
installedAt
|
||||
quantity
|
||||
@@ -4401,7 +4401,7 @@ export type InstallLicenseMutation = {
|
||||
};
|
||||
};
|
||||
|
||||
export type LicenseFragment = {
|
||||
export type LicenseBodyFragment = {
|
||||
__typename?: 'License';
|
||||
expiredAt: string | null;
|
||||
installedAt: string;
|
||||
|
||||
@@ -16,6 +16,7 @@ export type AppSetting = {
|
||||
autoCheckUpdate: boolean;
|
||||
autoDownloadUpdate: boolean;
|
||||
enableTelemetry: boolean;
|
||||
showLinkedDocInSidebar: boolean;
|
||||
};
|
||||
export const windowFrameStyleOptions: AppSetting['windowFrameStyle'][] = [
|
||||
'frameless',
|
||||
@@ -33,6 +34,7 @@ const appSettingBaseAtom = atomWithStorage<AppSetting>(
|
||||
autoCheckUpdate: true,
|
||||
autoDownloadUpdate: true,
|
||||
enableTelemetry: true,
|
||||
showLinkedDocInSidebar: true,
|
||||
},
|
||||
undefined,
|
||||
{
|
||||
|
||||
@@ -52,6 +52,509 @@ exports[`should get all docs from root doc work 2`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`should parse page doc work 1`] = `
|
||||
{
|
||||
"md": "AFFiNE is an open source all in one workspace, an operating system for all the building blocks of your team wiki, knowledge management and digital assets and a better alternative to Notion and Miro.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# You own your data, with no compromises
|
||||
|
||||
|
||||
## Local-first & Real-time collaborative
|
||||
|
||||
|
||||
We love the idea proposed by Ink & Switch in the famous article about you owning your data, despite the cloud. Furthermore, AFFiNE is the first all-in-one workspace that keeps your data ownership with no compromises on real-time collaboration and editing experience.
|
||||
|
||||
|
||||
AFFiNE is a local-first application upon CRDTs with real-time collaboration support. Your data is always stored locally while multiple nodes remain synced in real-time.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Blocks that assemble your next docs, tasks kanban or whiteboard
|
||||
|
||||
|
||||
There is a large overlap of their atomic "building blocks" between these apps. They are neither open source nor have a plugin system like VS Code for contributors to customize. We want to have something that contains all the features we love and goes one step further.
|
||||
|
||||
|
||||
We are building AFFiNE to be a fundamental open source platform that contains all the building blocks for docs, task management and visual collaboration, hoping you can shape your next workflow with us that can make your life better and also connect others, too.
|
||||
|
||||
|
||||
If you want to learn more about the product design of AFFiNE, here goes the concepts:
|
||||
|
||||
|
||||
To Shape, not to adapt. AFFiNE is built for individuals & teams who care about their data, who refuse vendor lock-in, and who want to have control over their essential tools.
|
||||
|
||||
|
||||
## A true canvas for blocks in any form
|
||||
|
||||
|
||||
[Many editor apps](http://notion.so) claimed to be a canvas for productivity. Since _the Mother of All Demos,_ Douglas Engelbart, a creative and programable digital workspace has been a pursuit and an ultimate mission for generations of tool makers.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"We shape our tools and thereafter our tools shape us”. A lot of pioneers have inspired us a long the way, e.g.:
|
||||
|
||||
|
||||
* Quip & Notion with their great concept of "everything is a block"
|
||||
|
||||
|
||||
* Trello with their Kanban
|
||||
|
||||
|
||||
* Airtable & Miro with their no-code programable datasheets
|
||||
|
||||
|
||||
* Miro & Whimiscal with their edgeless visual whiteboard
|
||||
|
||||
|
||||
* Remnote & Capacities with their object-based tag system
|
||||
|
||||
|
||||
For more details, please refer to our [RoadMap](https://docs.affine.pro/docs/core-concepts/roadmap)
|
||||
|
||||
|
||||
## Self Host
|
||||
|
||||
|
||||
Self host AFFiNE
|
||||
|
||||
|
||||
||Title|Tag|
|
||||
|---|---|---|
|
||||
|Affine Development|Affine Development|<span data-affine-option data-value="AxSe-53xjX" data-option-color="var(--affine-tag-pink)">AFFiNE</span>|
|
||||
|For developers or installations guides, please go to AFFiNE Doc|For developers or installations guides, please go to AFFiNE Doc|<span data-affine-option data-value="0jh9gNw4Yl" data-option-color="var(--affine-tag-orange)">Developers</span>|
|
||||
|Quip & Notion with their great concept of "everything is a block"|Quip & Notion with their great concept of "everything is a block"|<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>|
|
||||
|Trello with their Kanban|Trello with their Kanban|<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>|
|
||||
|Airtable & Miro with their no-code programable datasheets|Airtable & Miro with their no-code programable datasheets|<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>|
|
||||
|Miro & Whimiscal with their edgeless visual whiteboard|Miro & Whimiscal with their edgeless visual whiteboard|<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>|
|
||||
|Remnote & Capacities with their object-based tag system|Remnote & Capacities with their object-based tag system||
|
||||
|
||||
|
||||
## Affine Development
|
||||
|
||||
|
||||
For developer or installation guides, please go to [AFFiNE Development](https://docs.affine.pro/docs/development/quick-start)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
",
|
||||
"parsedBlock": {
|
||||
"children": [
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"content": "AFFiNE is an open source all in one workspace, an operating system for all the building blocks of your team wiki, knowledge management and digital assets and a better alternative to Notion and Miro.
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "FoPQcAyV_m",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "oz48nn_zp8",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "# You own your data, with no compromises
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "g8a-D9-jXS",
|
||||
"type": "h1",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "## Local-first & Real-time collaborative
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "J8lHN1GR_5",
|
||||
"type": "h2",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "We love the idea proposed by Ink & Switch in the famous article about you owning your data, despite the cloud. Furthermore, AFFiNE is the first all-in-one workspace that keeps your data ownership with no compromises on real-time collaboration and editing experience.
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "xCuWdM0VLz",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "AFFiNE is a local-first application upon CRDTs with real-time collaboration support. Your data is always stored locally while multiple nodes remain synced in real-time.
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "zElMi0tViK",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "Z4rK0OF9Wk",
|
||||
"type": "text",
|
||||
},
|
||||
],
|
||||
"content": "",
|
||||
"flavour": "affine:note",
|
||||
"id": "RX4CG2zsBk",
|
||||
"type": undefined,
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"content": "### Blocks that assemble your next docs, tasks kanban or whiteboard
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "DQ0Ryb-SpW",
|
||||
"type": "h3",
|
||||
},
|
||||
],
|
||||
"content": "",
|
||||
"flavour": "affine:note",
|
||||
"id": "S1mkc8zUoU",
|
||||
"type": undefined,
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"content": "There is a large overlap of their atomic "building blocks" between these apps. They are neither open source nor have a plugin system like VS Code for contributors to customize. We want to have something that contains all the features we love and goes one step further.
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "HAZC3URZp_",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "We are building AFFiNE to be a fundamental open source platform that contains all the building blocks for docs, task management and visual collaboration, hoping you can shape your next workflow with us that can make your life better and also connect others, too.
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "0H87ypiuv8",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "If you want to learn more about the product design of AFFiNE, here goes the concepts:
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "Sp4G1KD0Wn",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "To Shape, not to adapt. AFFiNE is built for individuals & teams who care about their data, who refuse vendor lock-in, and who want to have control over their essential tools.
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "RsUhDuEqXa",
|
||||
"type": "text",
|
||||
},
|
||||
],
|
||||
"content": "",
|
||||
"flavour": "affine:note",
|
||||
"id": "yGlBdshAqN",
|
||||
"type": undefined,
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"content": "## A true canvas for blocks in any form
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "Z2HibKzAr-",
|
||||
"type": "h2",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "[Many editor apps](http://notion.so) claimed to be a canvas for productivity. Since _the Mother of All Demos,_ Douglas Engelbart, a creative and programable digital workspace has been a pursuit and an ultimate mission for generations of tool makers.
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "UwvWddamzM",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "g9xKUjhJj1",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": ""We shape our tools and thereafter our tools shape us”. A lot of pioneers have inspired us a long the way, e.g.:
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "wDTn4YJ4pm",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "* Quip & Notion with their great concept of "everything is a block"
|
||||
|
||||
",
|
||||
"flavour": "affine:list",
|
||||
"id": "xFrrdiP3-V",
|
||||
"type": "bulleted",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "* Trello with their Kanban
|
||||
|
||||
",
|
||||
"flavour": "affine:list",
|
||||
"id": "Tp9xyN4Okl",
|
||||
"type": "bulleted",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "* Airtable & Miro with their no-code programable datasheets
|
||||
|
||||
",
|
||||
"flavour": "affine:list",
|
||||
"id": "K_4hUzKZFQ",
|
||||
"type": "bulleted",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "* Miro & Whimiscal with their edgeless visual whiteboard
|
||||
|
||||
",
|
||||
"flavour": "affine:list",
|
||||
"id": "QwMzON2s7x",
|
||||
"type": "bulleted",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "* Remnote & Capacities with their object-based tag system
|
||||
|
||||
",
|
||||
"flavour": "affine:list",
|
||||
"id": "FFVmit6u1T",
|
||||
"type": "bulleted",
|
||||
},
|
||||
],
|
||||
"content": "",
|
||||
"flavour": "affine:note",
|
||||
"id": "6lDiuDqZGL",
|
||||
"type": undefined,
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"content": "For more details, please refer to our [RoadMap](https://docs.affine.pro/docs/core-concepts/roadmap)
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "YqnG5O6AE6",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "## Self Host
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "sbDTmZMZcq",
|
||||
"type": "h2",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "Self host AFFiNE
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "QVvitesfbj",
|
||||
"type": "text",
|
||||
},
|
||||
],
|
||||
"content": "",
|
||||
"flavour": "affine:note",
|
||||
"id": "cauvaHOQmh",
|
||||
"type": undefined,
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"content": "||Title|Tag|
|
||||
|---|---|---|
|
||||
|Affine Development|Affine Development|<span data-affine-option data-value="AxSe-53xjX" data-option-color="var(--affine-tag-pink)">AFFiNE</span>|
|
||||
|For developers or installations guides, please go to AFFiNE Doc|For developers or installations guides, please go to AFFiNE Doc|<span data-affine-option data-value="0jh9gNw4Yl" data-option-color="var(--affine-tag-orange)">Developers</span>|
|
||||
|Quip & Notion with their great concept of "everything is a block"|Quip & Notion with their great concept of "everything is a block"|<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>|
|
||||
|Trello with their Kanban|Trello with their Kanban|<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>|
|
||||
|Airtable & Miro with their no-code programable datasheets|Airtable & Miro with their no-code programable datasheets|<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>|
|
||||
|Miro & Whimiscal with their edgeless visual whiteboard|Miro & Whimiscal with their edgeless visual whiteboard|<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>|
|
||||
|Remnote & Capacities with their object-based tag system|Remnote & Capacities with their object-based tag system||
|
||||
|
||||
",
|
||||
"flavour": "affine:database",
|
||||
"id": "U_GoHFD9At",
|
||||
"rows": [
|
||||
{
|
||||
"Tag": "<span data-affine-option data-value="AxSe-53xjX" data-option-color="var(--affine-tag-pink)">AFFiNE</span>",
|
||||
"Title": "Affine Development
|
||||
|
||||
|
||||
",
|
||||
"undefined": "Affine Development
|
||||
|
||||
|
||||
",
|
||||
},
|
||||
{
|
||||
"Tag": "<span data-affine-option data-value="0jh9gNw4Yl" data-option-color="var(--affine-tag-orange)">Developers</span>",
|
||||
"Title": "For developers or installations guides, please go to AFFiNE Doc
|
||||
|
||||
|
||||
",
|
||||
"undefined": "For developers or installations guides, please go to AFFiNE Doc
|
||||
|
||||
|
||||
",
|
||||
},
|
||||
{
|
||||
"Tag": "<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>",
|
||||
"Title": "Quip & Notion with their great concept of "everything is a block"
|
||||
|
||||
|
||||
",
|
||||
"undefined": "Quip & Notion with their great concept of "everything is a block"
|
||||
|
||||
|
||||
",
|
||||
},
|
||||
{
|
||||
"Tag": "<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>",
|
||||
"Title": "Trello with their Kanban
|
||||
|
||||
|
||||
",
|
||||
"undefined": "Trello with their Kanban
|
||||
|
||||
|
||||
",
|
||||
},
|
||||
{
|
||||
"Tag": "<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>",
|
||||
"Title": "Airtable & Miro with their no-code programable datasheets
|
||||
|
||||
|
||||
",
|
||||
"undefined": "Airtable & Miro with their no-code programable datasheets
|
||||
|
||||
|
||||
",
|
||||
},
|
||||
{
|
||||
"Tag": "<span data-affine-option data-value="HgHsKOUINZ" data-option-color="var(--affine-tag-blue)">Reference</span>",
|
||||
"Title": "Miro & Whimiscal with their edgeless visual whiteboard
|
||||
|
||||
|
||||
",
|
||||
"undefined": "Miro & Whimiscal with their edgeless visual whiteboard
|
||||
|
||||
|
||||
",
|
||||
},
|
||||
{
|
||||
"Tag": "",
|
||||
"Title": "Remnote & Capacities with their object-based tag system
|
||||
|
||||
|
||||
",
|
||||
"undefined": "Remnote & Capacities with their object-based tag system
|
||||
|
||||
|
||||
",
|
||||
},
|
||||
],
|
||||
"title": "Learning From",
|
||||
"type": undefined,
|
||||
},
|
||||
],
|
||||
"content": "",
|
||||
"flavour": "affine:note",
|
||||
"id": "2jwCeO8Yot",
|
||||
"type": undefined,
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"content": "## Affine Development
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "NyHXrMX3R1",
|
||||
"type": "h2",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "For developer or installation guides, please go to [AFFiNE Development](https://docs.affine.pro/docs/development/quick-start)
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "9-K49otbCv",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"content": "
|
||||
|
||||
",
|
||||
"flavour": "affine:paragraph",
|
||||
"id": "faFteK9eG-",
|
||||
"type": "text",
|
||||
},
|
||||
],
|
||||
"content": "",
|
||||
"flavour": "affine:note",
|
||||
"id": "c9MF_JiRgx",
|
||||
"type": undefined,
|
||||
},
|
||||
],
|
||||
"content": "",
|
||||
"flavour": "affine:page",
|
||||
"id": "TnUgtVg7Eu",
|
||||
"type": undefined,
|
||||
},
|
||||
"title": "Write, Draw, Plan all at Once.",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`should read all doc ids from root doc snapshot work 1`] = `
|
||||
[
|
||||
"5nS9BSp3Px",
|
||||
|
||||
@@ -5,6 +5,7 @@ import { expect, test } from 'vitest';
|
||||
import { applyUpdate, Array as YArray, Doc as YDoc, Map as YMap } from 'yjs';
|
||||
|
||||
import {
|
||||
parsePageDoc,
|
||||
readAllBlocksFromDoc,
|
||||
readAllDocIdsFromRootDoc,
|
||||
readAllDocsFromRootDoc,
|
||||
@@ -100,3 +101,20 @@ test('should read all doc ids from root doc snapshot work', async () => {
|
||||
const docIds = readAllDocIdsFromRootDoc(rootDoc);
|
||||
expect(docIds).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should parse page doc work', () => {
|
||||
const doc = new YDoc({
|
||||
guid: 'test-doc',
|
||||
});
|
||||
applyUpdate(doc, docSnapshot);
|
||||
|
||||
const result = parsePageDoc({
|
||||
workspaceId: 'test-space',
|
||||
doc,
|
||||
buildBlobUrl: id => `blob://${id}`,
|
||||
buildDocUrl: id => `doc://${id}`,
|
||||
renderDocTitle: id => `Doc Title ${id}`,
|
||||
});
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
A fork of https://github.com/frysztak/quill-delta-to-markdown
|
||||
@@ -0,0 +1,95 @@
|
||||
// eslint-disable
|
||||
// @ts-nocheck
|
||||
import { Node } from './utils/node';
|
||||
import { encodeLink } from './utils/url';
|
||||
|
||||
export interface InlineReference {
|
||||
type: 'LinkedPage';
|
||||
pageId: string;
|
||||
title?: string;
|
||||
params?: { mode: 'doc' | 'edgeless' };
|
||||
}
|
||||
|
||||
export interface ConverterOptions {
|
||||
convertInlineReferenceLink?: (reference: InlineReference) => {
|
||||
title: string;
|
||||
link: string;
|
||||
};
|
||||
}
|
||||
|
||||
const defaultConvertInlineReferenceLink = (reference: InlineReference) => {
|
||||
return {
|
||||
title: reference.title || '',
|
||||
link: [reference.type, reference.pageId, reference.params?.mode]
|
||||
.filter(Boolean)
|
||||
.join(':'),
|
||||
};
|
||||
};
|
||||
|
||||
export function getConverters(opts: ConverterOptions = {}) {
|
||||
const { convertInlineReferenceLink = defaultConvertInlineReferenceLink } =
|
||||
opts;
|
||||
|
||||
return {
|
||||
embed: {
|
||||
image: function (src) {
|
||||
this.append(' + ')');
|
||||
},
|
||||
// Not a default Quill feature, converts custom divider embed blot added when
|
||||
// creating quill editor instance.
|
||||
// See https://quilljs.com/guides/cloning-medium-with-parchment/#dividers
|
||||
thematic_break: function () {
|
||||
this.open = '\n---\n' + this.open;
|
||||
},
|
||||
},
|
||||
|
||||
inline: {
|
||||
italic: function () {
|
||||
return ['_', '_'];
|
||||
},
|
||||
bold: function () {
|
||||
return ['**', '**'];
|
||||
},
|
||||
link: function (url) {
|
||||
return ['[', '](' + url + ')'];
|
||||
},
|
||||
reference: function (reference: InlineReference) {
|
||||
const { title, link } = convertInlineReferenceLink(reference);
|
||||
return ['[', `${title}](${link})`];
|
||||
},
|
||||
strike: function () {
|
||||
return ['~~', '~~'];
|
||||
},
|
||||
code: function () {
|
||||
return ['`', '`'];
|
||||
},
|
||||
},
|
||||
|
||||
block: {
|
||||
header: function ({ header }) {
|
||||
this.open = '#'.repeat(header) + ' ' + this.open;
|
||||
},
|
||||
blockquote: function () {
|
||||
this.open = '> ' + this.open;
|
||||
},
|
||||
list: {
|
||||
group: function () {
|
||||
return new Node(['', '\n']);
|
||||
},
|
||||
line: function (attrs, group) {
|
||||
if (attrs.list === 'bullet') {
|
||||
this.open = '- ' + this.open;
|
||||
} else if (attrs.list === 'checked') {
|
||||
this.open = '- [x] ' + this.open;
|
||||
} else if (attrs.list === 'unchecked') {
|
||||
this.open = '- [ ] ' + this.open;
|
||||
} else if (attrs.list === 'ordered') {
|
||||
group.count = group.count || 0;
|
||||
var count = ++group.count;
|
||||
this.open = count + '. ' + this.open;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
147
packages/common/reader/src/doc-parser/delta-to-md/delta-to-md.ts
Normal file
147
packages/common/reader/src/doc-parser/delta-to-md/delta-to-md.ts
Normal file
@@ -0,0 +1,147 @@
|
||||
// eslint-disable
|
||||
// @ts-nocheck
|
||||
import { Node } from './utils/node';
|
||||
|
||||
export const deltaToMd = (delta, converters) => {
|
||||
return convert(delta, converters).render().trimEnd() + '\n';
|
||||
};
|
||||
|
||||
function convert(ops, converters) {
|
||||
let group, line, el, activeInline, beginningOfLine;
|
||||
let root = new Node();
|
||||
|
||||
function newLine() {
|
||||
el = line = new Node(['', '\n']);
|
||||
root.append(line);
|
||||
activeInline = {};
|
||||
}
|
||||
newLine();
|
||||
|
||||
for (let i = 0; i < ops.length; i++) {
|
||||
let op = ops[i];
|
||||
|
||||
if (typeof op.insert === 'object') {
|
||||
for (let k in op.insert) {
|
||||
if (converters.embed[k]) {
|
||||
applyInlineAttributes(op.attributes);
|
||||
converters.embed[k].call(el, op.insert[k], op.attributes);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let lines = op.insert.split('\n');
|
||||
|
||||
if (hasBlockLevelAttribute(op.attributes, converters)) {
|
||||
// Some line-level styling (ie headings) is applied by inserting a \n
|
||||
// with the style; the style applies back to the previous \n.
|
||||
// There *should* only be one style in an insert operation.
|
||||
|
||||
for (let j = 1; j < lines.length; j++) {
|
||||
for (let attr in op.attributes) {
|
||||
if (converters.block[attr]) {
|
||||
let fn = converters.block[attr];
|
||||
if (typeof fn === 'object') {
|
||||
if (group && group.type !== attr) {
|
||||
group = null;
|
||||
}
|
||||
if (!group && fn.group) {
|
||||
group = {
|
||||
el: fn.group(),
|
||||
type: attr,
|
||||
value: op.attributes[attr],
|
||||
distance: 0,
|
||||
};
|
||||
root.append(group.el);
|
||||
}
|
||||
|
||||
if (group) {
|
||||
group.el.append(line);
|
||||
group.distance = 0;
|
||||
}
|
||||
fn = fn.line;
|
||||
}
|
||||
|
||||
fn.call(line, op.attributes, group);
|
||||
newLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
beginningOfLine = true;
|
||||
} else {
|
||||
for (let l = 0; l < lines.length; l++) {
|
||||
if ((l > 0 || beginningOfLine) && group && ++group.distance >= 2) {
|
||||
group = null;
|
||||
}
|
||||
applyInlineAttributes(
|
||||
op.attributes,
|
||||
ops[i + 1] && ops[i + 1].attributes
|
||||
);
|
||||
el.append(lines[l]);
|
||||
if (l < lines.length - 1) {
|
||||
newLine();
|
||||
}
|
||||
}
|
||||
beginningOfLine = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
|
||||
function applyInlineAttributes(attrs, next?: any) {
|
||||
let first: any[] = [];
|
||||
let then: any[] = [];
|
||||
attrs = attrs || {};
|
||||
|
||||
let tag = el,
|
||||
seen = {};
|
||||
while (tag._format) {
|
||||
seen[tag._format] = true;
|
||||
if (!attrs[tag._format] || tag.open !== tag.close) {
|
||||
for (let k in seen) {
|
||||
delete activeInline[k];
|
||||
}
|
||||
el = tag.parent();
|
||||
}
|
||||
|
||||
tag = tag.parent();
|
||||
}
|
||||
|
||||
for (let attr in attrs) {
|
||||
if (converters.inline[attr] && attrs[attr]) {
|
||||
if (activeInline[attr] && activeInline[attr] === attrs[attr]) {
|
||||
continue; // do nothing -- we should already be inside this style's tag
|
||||
}
|
||||
|
||||
if (next && attrs[attr] === next[attr]) {
|
||||
first.push(attr); // if the next operation has the same style, this should be the outermost tag
|
||||
} else {
|
||||
then.push(attr);
|
||||
}
|
||||
activeInline[attr] = attrs[attr];
|
||||
}
|
||||
}
|
||||
|
||||
first.forEach(apply);
|
||||
then.forEach(apply);
|
||||
|
||||
function apply(fmt) {
|
||||
let newEl = converters.inline[fmt].call(null, attrs[fmt]);
|
||||
if (Array.isArray(newEl)) {
|
||||
newEl = new Node(newEl);
|
||||
}
|
||||
newEl._format = fmt;
|
||||
el.append(newEl);
|
||||
el = newEl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hasBlockLevelAttribute(attrs, converters) {
|
||||
for (let k in attrs) {
|
||||
if (Object.keys(converters.block).includes(k)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export { getConverters } from './delta-converters';
|
||||
export { deltaToMd } from './delta-to-md';
|
||||
@@ -0,0 +1,66 @@
|
||||
// eslint-disable
|
||||
// @ts-nocheck
|
||||
let id = 0;
|
||||
|
||||
export class Node {
|
||||
id = ++id;
|
||||
children: Node[];
|
||||
open: string;
|
||||
close: string;
|
||||
text: string;
|
||||
|
||||
_format: string;
|
||||
_parent: Node;
|
||||
|
||||
constructor(data?: string[] | string) {
|
||||
if (Array.isArray(data)) {
|
||||
this.open = data[0];
|
||||
this.close = data[1];
|
||||
} else if (typeof data === 'string') {
|
||||
this.text = data;
|
||||
}
|
||||
this.children = [];
|
||||
}
|
||||
|
||||
append(e: Node) {
|
||||
if (!(e instanceof Node)) {
|
||||
e = new Node(e);
|
||||
}
|
||||
if (e._parent) {
|
||||
const idx = e._parent.children.indexOf(e);
|
||||
e._parent.children.splice(idx, 1);
|
||||
}
|
||||
e._parent = this;
|
||||
this.children = this.children.concat(e);
|
||||
}
|
||||
|
||||
render() {
|
||||
const inner =
|
||||
(this.text || '') + this.children.map(c => c.render()).join('');
|
||||
|
||||
if (
|
||||
inner.trim() === '' &&
|
||||
this.open === this.close &&
|
||||
this.open &&
|
||||
this.close
|
||||
) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const wrapped = this.open && this.close;
|
||||
const emptyInner = inner.trim() === '';
|
||||
const fragments = [
|
||||
inner.startsWith(' ') && !emptyInner && wrapped ? ' ' : '',
|
||||
this.open,
|
||||
wrapped ? inner.trim() : inner,
|
||||
this.close,
|
||||
inner.endsWith(' ') && !emptyInner && wrapped ? ' ' : '',
|
||||
].filter(f => f);
|
||||
|
||||
return fragments.join('');
|
||||
}
|
||||
|
||||
parent() {
|
||||
return this._parent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export const encodeLink = (link: string) =>
|
||||
encodeURI(link)
|
||||
.replace(/\(/g, '%28')
|
||||
.replace(/\)/g, '%29')
|
||||
.replace(/(\?|&)response-content-disposition=attachment.*$/, '');
|
||||
437
packages/common/reader/src/doc-parser/parser.ts
Normal file
437
packages/common/reader/src/doc-parser/parser.ts
Normal file
@@ -0,0 +1,437 @@
|
||||
import type { ColumnDataType } from '@blocksuite/affine/model';
|
||||
import { Array as YArray, type Map as YMap, type Text as YText } from 'yjs';
|
||||
|
||||
import { deltaToMd, getConverters } from './delta-to-md';
|
||||
import type {
|
||||
BaseParsedBlock,
|
||||
Flavour,
|
||||
ParsedBlock,
|
||||
ParsedDoc,
|
||||
ParserContext,
|
||||
SerializedCells,
|
||||
YBlock,
|
||||
YBlocks,
|
||||
} from './types';
|
||||
|
||||
export const parseBlockToMd = (
|
||||
block: BaseParsedBlock,
|
||||
padding = ''
|
||||
): string => {
|
||||
if (block.content) {
|
||||
return (
|
||||
block.content
|
||||
.split('\n')
|
||||
.map(line => padding + line)
|
||||
.join('\n') +
|
||||
'\n' +
|
||||
block.children.map(b => parseBlockToMd(b, padding + ' ')).join('')
|
||||
);
|
||||
} else {
|
||||
return block.children.map(b => parseBlockToMd(b, padding)).join('');
|
||||
}
|
||||
};
|
||||
|
||||
export function parseBlock(
|
||||
context: ParserContext,
|
||||
yBlock: YBlock | undefined,
|
||||
yBlocks: YBlocks // all blocks
|
||||
): ParsedBlock | null {
|
||||
if (!yBlock) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const deltaConverters = getConverters({
|
||||
convertInlineReferenceLink: ref => {
|
||||
return {
|
||||
title: ref.title || context.renderDocTitle?.(ref.pageId) || '',
|
||||
link: context.buildDocUrl(ref.pageId),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
const id = yBlock.get('sys:id') as string;
|
||||
const flavour = yBlock.get('sys:flavour') as Flavour;
|
||||
const type = yBlock.get('prop:type') as string;
|
||||
const toMd = () =>
|
||||
deltaToMd((yBlock.get('prop:text') as YText).toDelta(), deltaConverters);
|
||||
const hidden = yBlock.get('prop:hidden') as boolean;
|
||||
const displayMode = yBlock.get('prop:displayMode') as string;
|
||||
const childrenIds =
|
||||
yBlock.get('sys:children') instanceof YArray
|
||||
? (yBlock.get('sys:children') as YArray<string>).toJSON()
|
||||
: [];
|
||||
|
||||
let result: ParsedBlock = {
|
||||
id,
|
||||
flavour,
|
||||
content: '',
|
||||
children: [],
|
||||
type,
|
||||
};
|
||||
|
||||
if (hidden || displayMode === 'edgeless') {
|
||||
return result;
|
||||
}
|
||||
|
||||
try {
|
||||
switch (flavour) {
|
||||
case 'affine:paragraph': {
|
||||
let initial = '';
|
||||
if (type === 'h1') {
|
||||
initial = '# ';
|
||||
} else if (type === 'h2') {
|
||||
initial = '## ';
|
||||
} else if (type === 'h3') {
|
||||
initial = '### ';
|
||||
} else if (type === 'h4') {
|
||||
initial = '#### ';
|
||||
} else if (type === 'h5') {
|
||||
initial = '##### ';
|
||||
} else if (type === 'h6') {
|
||||
initial = '###### ';
|
||||
} else if (type === 'quote') {
|
||||
initial = '> ';
|
||||
}
|
||||
result.content = initial + toMd() + '\n';
|
||||
break;
|
||||
}
|
||||
case 'affine:divider': {
|
||||
result.content = '\n---\n\n';
|
||||
break;
|
||||
}
|
||||
case 'affine:list': {
|
||||
result.content = (type === 'bulleted' ? '* ' : '1. ') + toMd() + '\n';
|
||||
break;
|
||||
}
|
||||
case 'affine:code': {
|
||||
const lang =
|
||||
(yBlock.get('prop:language') as string)?.toLowerCase() || 'txt';
|
||||
// do not transform to delta for code block
|
||||
const caption = yBlock.get('prop:caption') as string;
|
||||
result.content =
|
||||
'```' +
|
||||
lang +
|
||||
(caption ? ` ${caption}` : '') +
|
||||
'\n' +
|
||||
(yBlock.get('prop:text') as YText).toJSON() +
|
||||
'\n```\n\n';
|
||||
break;
|
||||
}
|
||||
case 'affine:image': {
|
||||
const sourceId = yBlock.get('prop:sourceId') as string;
|
||||
const width = yBlock.get('prop:width');
|
||||
const height = yBlock.get('prop:height');
|
||||
// fixme: this may not work if workspace is not public
|
||||
const blobUrl = context.buildBlobUrl(sourceId);
|
||||
const caption = yBlock.get('prop:caption') as string;
|
||||
if (width || height || caption) {
|
||||
result.content =
|
||||
`<img
|
||||
src="${blobUrl}"
|
||||
alt="${caption}"
|
||||
width="${width || 'auto'}"
|
||||
height="${height || 'auto'}"
|
||||
/>
|
||||
` + '\n\n';
|
||||
} else {
|
||||
result.content = `\n\n\n`;
|
||||
}
|
||||
Object.assign(result, {
|
||||
sourceId,
|
||||
width,
|
||||
height,
|
||||
caption,
|
||||
blobUrl,
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
case 'affine:attachment': {
|
||||
const sourceId = yBlock.get('prop:sourceId') as string;
|
||||
const blobUrl = context.buildBlobUrl(sourceId);
|
||||
const caption = yBlock.get('prop:caption') as string;
|
||||
if (type.startsWith('video')) {
|
||||
result.content =
|
||||
`<video muted autoplay loop preload="auto" playsinline>
|
||||
<source src="${blobUrl}" type="${type}" />
|
||||
</video>
|
||||
` + '\n\n';
|
||||
} else {
|
||||
// assume it is an image
|
||||
result.content = `\n\n\n`;
|
||||
}
|
||||
Object.assign(result, {
|
||||
sourceId,
|
||||
blobUrl,
|
||||
caption,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'affine:embed-youtube': {
|
||||
const videoId = yBlock.get('prop:videoId') as string;
|
||||
// prettier-ignore
|
||||
result.content = `
|
||||
<iframe
|
||||
type="text/html"
|
||||
width="100%"
|
||||
height="410px"
|
||||
src="https://www.youtube.com/embed/${videoId}"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
allowfullscreen
|
||||
credentialless>
|
||||
</iframe>` + '\n\n';
|
||||
break;
|
||||
}
|
||||
case 'affine:bookmark': {
|
||||
const url = yBlock.get('prop:url') as string;
|
||||
const caption = yBlock.get('prop:caption') as string;
|
||||
result.content = `\n[](Bookmark,${url})\n\n`;
|
||||
Object.assign(result, {
|
||||
url,
|
||||
caption,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'affine:embed-linked-doc':
|
||||
case 'affine:embed-synced-doc': {
|
||||
const pageId = yBlock.get('prop:pageId') as string;
|
||||
const caption = yBlock.get('prop:caption') as string;
|
||||
result.content = `\n[${caption}](${context.buildDocUrl(pageId)})\n\n`;
|
||||
Object.assign(result, {
|
||||
pageId,
|
||||
caption,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'affine:surface':
|
||||
case 'affine:page':
|
||||
case 'affine:note':
|
||||
case 'affine:frame': {
|
||||
result.content = '';
|
||||
break;
|
||||
}
|
||||
case 'affine:database': {
|
||||
const title = (yBlock.get('prop:title') as YText).toJSON();
|
||||
const childrenTitleById = Object.fromEntries(
|
||||
childrenIds.map(cid => {
|
||||
const child = parseBlock(
|
||||
context,
|
||||
yBlocks.get(cid) as YBlock | undefined,
|
||||
yBlocks
|
||||
);
|
||||
if (!child) {
|
||||
return [cid, ''];
|
||||
}
|
||||
return [cid, parseBlockToMd(child)] as const;
|
||||
})
|
||||
);
|
||||
const cols = (
|
||||
yBlock.get('prop:columns') as YArray<ColumnDataType>
|
||||
).toJSON() as ColumnDataType[];
|
||||
|
||||
const cells = (
|
||||
yBlock.get('prop:cells') as YMap<SerializedCells>
|
||||
).toJSON() as SerializedCells;
|
||||
|
||||
const optionToTagHtml = (option: any) => {
|
||||
return `<span data-affine-option data-value="${option.id}" data-option-color="${option.color}">${option.value}</span>`;
|
||||
};
|
||||
|
||||
const dbRows: string[][] = childrenIds
|
||||
.map(cid => {
|
||||
const row = cells[cid];
|
||||
return cols.map(col => {
|
||||
const value = row?.[col.id]?.value;
|
||||
|
||||
if (col.type !== 'title' && !value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
switch (col.type) {
|
||||
case 'title':
|
||||
return childrenTitleById[cid];
|
||||
case 'select':
|
||||
return optionToTagHtml(
|
||||
(col.data['options'] as any).find(
|
||||
(opt: any) => opt.id === value
|
||||
)
|
||||
);
|
||||
case 'multi-select':
|
||||
return (col.data['options'] as any)
|
||||
.filter((opt: any) => (value as string[]).includes(opt.id))
|
||||
.map(optionToTagHtml)
|
||||
.join('');
|
||||
default:
|
||||
return value ?? '';
|
||||
}
|
||||
});
|
||||
})
|
||||
.filter(row => !row.every(v => !v));
|
||||
const header = cols.map(col => {
|
||||
return col.name;
|
||||
});
|
||||
|
||||
const divider = cols.map(() => {
|
||||
return '---';
|
||||
});
|
||||
|
||||
// convert to markdown table
|
||||
result.content =
|
||||
[header, divider, ...dbRows]
|
||||
.map(row => {
|
||||
return (
|
||||
'|' +
|
||||
row
|
||||
.map(cell => String(cell || '')?.trim())
|
||||
.join('|')
|
||||
.replace(/\n+/g, '<br />') +
|
||||
'|'
|
||||
);
|
||||
})
|
||||
.join('\n') + '\n\n';
|
||||
|
||||
Object.assign(result, {
|
||||
title,
|
||||
rows: dbRows.map(row => {
|
||||
return Object.fromEntries(row.map((v, i) => [cols[i].name, v]));
|
||||
}),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'affine:table': {
|
||||
// Extract row IDs and their order
|
||||
const rowEntries = Object.entries(yBlock.toJSON())
|
||||
.filter(
|
||||
([key]) => key.startsWith('prop:rows.') && key.endsWith('.rowId')
|
||||
)
|
||||
.map(([key, value]) => {
|
||||
const rowId = value as string;
|
||||
const orderKey = key.replace('.rowId', '.order');
|
||||
const order = yBlock.get(orderKey) as string;
|
||||
const backgroundColor = yBlock.get(
|
||||
key.replace('.rowId', '.backgroundColor')
|
||||
) as string | undefined;
|
||||
return { rowId, order, backgroundColor };
|
||||
})
|
||||
.sort((a, b) => a.order.localeCompare(b.order));
|
||||
|
||||
// Extract column IDs and their order
|
||||
const columnEntries = Object.entries(yBlock.toJSON())
|
||||
.filter(
|
||||
([key]) =>
|
||||
key.startsWith('prop:columns.') && key.endsWith('.columnId')
|
||||
)
|
||||
.map(([key, value]) => {
|
||||
const columnId = value as string;
|
||||
const orderKey = key.replace('.columnId', '.order');
|
||||
const order = yBlock.get(orderKey) as string;
|
||||
return { columnId, order };
|
||||
})
|
||||
.sort((a, b) => a.order.localeCompare(b.order));
|
||||
|
||||
// Build the table rows with cell data
|
||||
const tableRows = rowEntries.map(({ rowId }) => {
|
||||
return columnEntries.map(({ columnId }) => {
|
||||
const cellKey = `prop:cells.${rowId}:${columnId}.text`;
|
||||
const cellText = yBlock.get(cellKey) as string | undefined;
|
||||
return cellText || '';
|
||||
});
|
||||
});
|
||||
|
||||
// Store column IDs for reference
|
||||
const columnIds = columnEntries.map(({ columnId }) => columnId);
|
||||
|
||||
// Use the first row as header and the rest as data rows
|
||||
if (tableRows.length > 0) {
|
||||
const headerRow = tableRows[0];
|
||||
const dataRows = tableRows.slice(1);
|
||||
const separators = headerRow.map(() => '---');
|
||||
|
||||
// Convert to markdown table with first row as header
|
||||
result.content =
|
||||
[headerRow, separators, ...dataRows]
|
||||
.map(row => {
|
||||
return (
|
||||
'|' +
|
||||
row
|
||||
.map(cell => String(cell || '')?.trim())
|
||||
.join('|')
|
||||
.replace(/\n+/g, '<br />') +
|
||||
'|'
|
||||
);
|
||||
})
|
||||
.join('\n') + '\n\n';
|
||||
} else {
|
||||
// Handle empty table case
|
||||
result.content = '';
|
||||
}
|
||||
|
||||
Object.assign(result, {
|
||||
columns: columnIds,
|
||||
rows: tableRows,
|
||||
});
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// console.warn("Unknown or unsupported flavour", flavour);
|
||||
}
|
||||
}
|
||||
|
||||
result.children =
|
||||
flavour !== 'affine:database'
|
||||
? childrenIds
|
||||
.map(cid =>
|
||||
parseBlock(
|
||||
context,
|
||||
yBlocks.get(cid) as YBlock | undefined,
|
||||
yBlocks
|
||||
)
|
||||
)
|
||||
.filter(
|
||||
(block): block is ParsedBlock =>
|
||||
!!block &&
|
||||
!(block.content === '' && block.children.length === 0)
|
||||
)
|
||||
: [];
|
||||
} catch (e) {
|
||||
console.warn('Error converting block to md', e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export const parsePageDoc = (ctx: ParserContext): ParsedDoc => {
|
||||
// we assume that the first block is the page block
|
||||
const yBlocks: YBlocks = ctx.doc.getMap('blocks');
|
||||
const maybePageBlock = Object.entries(yBlocks.toJSON()).findLast(
|
||||
([_, b]) => b['sys:flavour'] === 'affine:page'
|
||||
);
|
||||
|
||||
// there are cases that the page is empty due to some weird issues
|
||||
if (!maybePageBlock) {
|
||||
return {
|
||||
title: '',
|
||||
md: '',
|
||||
};
|
||||
} else {
|
||||
const yPage = yBlocks.get(maybePageBlock[0]) as YBlock;
|
||||
const title = yPage.get('prop:title') as YText;
|
||||
const rootBlock = parseBlock(ctx, yPage, yBlocks);
|
||||
if (!rootBlock) {
|
||||
return {
|
||||
title: '',
|
||||
md: '',
|
||||
};
|
||||
}
|
||||
rootBlock.children = rootBlock.children.filter(
|
||||
(block): block is BaseParsedBlock => block.flavour === 'affine:note'
|
||||
);
|
||||
const md = parseBlockToMd(rootBlock);
|
||||
|
||||
return {
|
||||
title: title.toJSON(),
|
||||
parsedBlock: rootBlock,
|
||||
md,
|
||||
};
|
||||
}
|
||||
};
|
||||
152
packages/common/reader/src/doc-parser/types.ts
Normal file
152
packages/common/reader/src/doc-parser/types.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
import { type CellDataType } from '@blocksuite/affine/model';
|
||||
import { type Doc as YDoc, type Map as YMap } from 'yjs';
|
||||
|
||||
export interface WorkspacePage {
|
||||
id: string;
|
||||
guid: string;
|
||||
title: string;
|
||||
createDate: number;
|
||||
trash?: boolean;
|
||||
favorite?: boolean;
|
||||
properties?: Record<string, any>;
|
||||
}
|
||||
|
||||
export type BaseFlavour<T extends string> = `affine:${T}`;
|
||||
|
||||
export type Flavour = BaseFlavour<
|
||||
| 'page'
|
||||
| 'frame'
|
||||
| 'paragraph'
|
||||
| 'code'
|
||||
| 'note'
|
||||
| 'list'
|
||||
| 'divider'
|
||||
| 'embed'
|
||||
| 'image'
|
||||
| 'surface'
|
||||
| 'database'
|
||||
| 'table'
|
||||
| 'attachment'
|
||||
| 'bookmark'
|
||||
| 'embed-youtube'
|
||||
| 'embed-linked-doc'
|
||||
| 'embed-synced-doc'
|
||||
>;
|
||||
|
||||
export interface BaseParsedBlock {
|
||||
id: string;
|
||||
flavour: Flavour;
|
||||
content: string;
|
||||
children: BaseParsedBlock[];
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export interface ParsedDoc {
|
||||
title: string;
|
||||
md: string;
|
||||
parsedBlock?: ParsedBlock;
|
||||
}
|
||||
|
||||
export interface ParagraphBlock extends BaseParsedBlock {
|
||||
flavour: 'affine:paragraph';
|
||||
type: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'quote';
|
||||
}
|
||||
|
||||
export interface DividerBlock extends BaseParsedBlock {
|
||||
flavour: 'affine:divider';
|
||||
}
|
||||
|
||||
export interface ListBlock extends BaseParsedBlock {
|
||||
flavour: 'affine:list';
|
||||
type: 'bulleted' | 'numbered';
|
||||
}
|
||||
|
||||
export interface CodeBlock extends BaseParsedBlock {
|
||||
flavour: 'affine:code';
|
||||
language: string;
|
||||
}
|
||||
|
||||
export interface ImageBlock extends BaseParsedBlock {
|
||||
flavour: 'affine:image';
|
||||
sourceId: string;
|
||||
blobUrl: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
caption?: string;
|
||||
}
|
||||
|
||||
export interface AttachmentBlock extends BaseParsedBlock {
|
||||
flavour: 'affine:attachment';
|
||||
type: string;
|
||||
sourceId: string;
|
||||
}
|
||||
|
||||
export interface EmbedYoutubeBlock extends BaseParsedBlock {
|
||||
flavour: 'affine:embed-youtube';
|
||||
videoId: string;
|
||||
}
|
||||
|
||||
export interface BookmarkBlock extends BaseParsedBlock {
|
||||
flavour: 'affine:bookmark';
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface EmbedLinkedDocBlock extends BaseParsedBlock {
|
||||
flavour: 'affine:embed-linked-doc';
|
||||
pageId: string;
|
||||
}
|
||||
|
||||
export interface EmbedSyncedDocBlock extends BaseParsedBlock {
|
||||
flavour: 'affine:embed-synced-doc';
|
||||
pageId: string;
|
||||
}
|
||||
|
||||
export interface DatabaseBlock extends BaseParsedBlock {
|
||||
title: string;
|
||||
flavour: 'affine:database';
|
||||
rows: Record<string, string>[];
|
||||
}
|
||||
|
||||
export interface TableBlock extends BaseParsedBlock {
|
||||
flavour: 'affine:table';
|
||||
rows: string[][];
|
||||
columns: string[];
|
||||
}
|
||||
|
||||
export type ParsedBlock =
|
||||
| ParagraphBlock
|
||||
| DividerBlock
|
||||
| ListBlock
|
||||
| CodeBlock
|
||||
| ImageBlock
|
||||
| AttachmentBlock
|
||||
| EmbedYoutubeBlock
|
||||
| BookmarkBlock
|
||||
| DatabaseBlock
|
||||
| TableBlock
|
||||
| BaseParsedBlock;
|
||||
|
||||
export interface ParsedDoc {
|
||||
title: string;
|
||||
md: string;
|
||||
parsedBlock?: ParsedBlock;
|
||||
}
|
||||
|
||||
export type SerializedCells = {
|
||||
// row
|
||||
[key: string]: {
|
||||
// column
|
||||
[key: string]: CellDataType;
|
||||
};
|
||||
};
|
||||
|
||||
export type YBlock = YMap<unknown>;
|
||||
export type YBlocks = YMap<YBlock>;
|
||||
|
||||
export interface ParserContext {
|
||||
workspaceId: string;
|
||||
doc: YDoc;
|
||||
buildBlobUrl: (blobId: string) => string;
|
||||
buildDocUrl: (docId: string) => string;
|
||||
renderDocTitle?: (docId: string) => string;
|
||||
}
|
||||
@@ -915,3 +915,5 @@ export function readAllDocIdsFromRootDoc(
|
||||
}
|
||||
return Array.from(docIds);
|
||||
}
|
||||
|
||||
export { parseBlock, parseBlockToMd, parsePageDoc } from './doc-parser/parser';
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public struct LicenseBody: AffineGraphQL.SelectionSet, Fragment {
|
||||
public static var fragmentDefinition: StaticString {
|
||||
#"fragment licenseBody on License { __typename expiredAt installedAt quantity recurring validatedAt variant }"#
|
||||
}
|
||||
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.License }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("expiredAt", AffineGraphQL.DateTime?.self),
|
||||
.field("installedAt", AffineGraphQL.DateTime.self),
|
||||
.field("quantity", Int.self),
|
||||
.field("recurring", GraphQLEnum<AffineGraphQL.SubscriptionRecurring>.self),
|
||||
.field("validatedAt", AffineGraphQL.DateTime.self),
|
||||
.field("variant", GraphQLEnum<AffineGraphQL.SubscriptionVariant>?.self),
|
||||
] }
|
||||
|
||||
public var expiredAt: AffineGraphQL.DateTime? { __data["expiredAt"] }
|
||||
public var installedAt: AffineGraphQL.DateTime { __data["installedAt"] }
|
||||
public var quantity: Int { __data["quantity"] }
|
||||
public var recurring: GraphQLEnum<AffineGraphQL.SubscriptionRecurring> { __data["recurring"] }
|
||||
public var validatedAt: AffineGraphQL.DateTime { __data["validatedAt"] }
|
||||
public var variant: GraphQLEnum<AffineGraphQL.SubscriptionVariant>? { __data["variant"] }
|
||||
}
|
||||
@@ -7,27 +7,23 @@ public class AcceptInviteByInviteIdMutation: GraphQLMutation {
|
||||
public static let operationName: String = "acceptInviteByInviteId"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation acceptInviteByInviteId($workspaceId: String!, $inviteId: String!, $sendAcceptMail: Boolean) { acceptInviteById( workspaceId: $workspaceId inviteId: $inviteId sendAcceptMail: $sendAcceptMail ) }"#
|
||||
#"mutation acceptInviteByInviteId($workspaceId: String!, $inviteId: String!) { acceptInviteById(workspaceId: $workspaceId, inviteId: $inviteId) }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var inviteId: String
|
||||
public var sendAcceptMail: GraphQLNullable<Bool>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
inviteId: String,
|
||||
sendAcceptMail: GraphQLNullable<Bool>
|
||||
inviteId: String
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.inviteId = inviteId
|
||||
self.sendAcceptMail = sendAcceptMail
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"inviteId": inviteId,
|
||||
"sendAcceptMail": sendAcceptMail
|
||||
"inviteId": inviteId
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
@@ -35,12 +31,11 @@ public class AcceptInviteByInviteIdMutation: GraphQLMutation {
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
#warning("Argument 'sendAcceptMail' of field 'acceptInviteById' is deprecated. Reason: 'never used'")
|
||||
#warning("Argument 'workspaceId' of field 'acceptInviteById' is deprecated. Reason: 'never used'")
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("acceptInviteById", Bool.self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"inviteId": .variable("inviteId"),
|
||||
"sendAcceptMail": .variable("sendAcceptMail")
|
||||
"inviteId": .variable("inviteId")
|
||||
]),
|
||||
] }
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ public class ActivateLicenseMutation: GraphQLMutation {
|
||||
public static let operationName: String = "activateLicense"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation activateLicense($workspaceId: String!, $license: String!) { activateLicense(workspaceId: $workspaceId, license: $license) { __typename installedAt validatedAt } }"#
|
||||
#"mutation activateLicense($workspaceId: String!, $license: String!) { activateLicense(workspaceId: $workspaceId, license: $license) { __typename ...licenseBody } }"#,
|
||||
fragments: [LicenseBody.self]
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
@@ -50,12 +51,22 @@ public class ActivateLicenseMutation: GraphQLMutation {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.License }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("installedAt", AffineGraphQL.DateTime.self),
|
||||
.field("validatedAt", AffineGraphQL.DateTime.self),
|
||||
.fragment(LicenseBody.self),
|
||||
] }
|
||||
|
||||
public var expiredAt: AffineGraphQL.DateTime? { __data["expiredAt"] }
|
||||
public var installedAt: AffineGraphQL.DateTime { __data["installedAt"] }
|
||||
public var quantity: Int { __data["quantity"] }
|
||||
public var recurring: GraphQLEnum<AffineGraphQL.SubscriptionRecurring> { __data["recurring"] }
|
||||
public var validatedAt: AffineGraphQL.DateTime { __data["validatedAt"] }
|
||||
public var variant: GraphQLEnum<AffineGraphQL.SubscriptionVariant>? { __data["variant"] }
|
||||
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public var licenseBody: LicenseBody { _toFragment() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ public class AddContextFileMutation: GraphQLMutation {
|
||||
public static let operationName: String = "addContextFile"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation addContextFile($content: Upload!, $options: AddContextFileInput!) { addContextFile(content: $content, options: $options) { __typename id createdAt name chunkSize error status blobId } }"#
|
||||
#"mutation addContextFile($content: Upload!, $options: AddContextFileInput!) { addContextFile(content: $content, options: $options) { __typename id createdAt name mimeType chunkSize error status blobId } }"#
|
||||
))
|
||||
|
||||
public var content: Upload
|
||||
@@ -54,6 +54,7 @@ public class AddContextFileMutation: GraphQLMutation {
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("createdAt", AffineGraphQL.SafeInt.self),
|
||||
.field("name", String.self),
|
||||
.field("mimeType", String.self),
|
||||
.field("chunkSize", AffineGraphQL.SafeInt.self),
|
||||
.field("error", String?.self),
|
||||
.field("status", GraphQLEnum<AffineGraphQL.ContextEmbedStatus>.self),
|
||||
@@ -63,6 +64,7 @@ public class AddContextFileMutation: GraphQLMutation {
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
public var createdAt: AffineGraphQL.SafeInt { __data["createdAt"] }
|
||||
public var name: String { __data["name"] }
|
||||
public var mimeType: String { __data["mimeType"] }
|
||||
public var chunkSize: AffineGraphQL.SafeInt { __data["chunkSize"] }
|
||||
public var error: String? { __data["error"] }
|
||||
public var status: GraphQLEnum<AffineGraphQL.ContextEmbedStatus> { __data["status"] }
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class AddWorkspaceEmbeddingFilesMutation: GraphQLMutation {
|
||||
public static let operationName: String = "addWorkspaceEmbeddingFiles"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation addWorkspaceEmbeddingFiles($workspaceId: String!, $blob: Upload!) { addWorkspaceEmbeddingFiles(workspaceId: $workspaceId, blob: $blob) { __typename fileId fileName blobId mimeType size createdAt } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var blob: Upload
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
blob: Upload
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.blob = blob
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"blob": blob
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("addWorkspaceEmbeddingFiles", AddWorkspaceEmbeddingFiles.self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"blob": .variable("blob")
|
||||
]),
|
||||
] }
|
||||
|
||||
/// Update workspace embedding files
|
||||
public var addWorkspaceEmbeddingFiles: AddWorkspaceEmbeddingFiles { __data["addWorkspaceEmbeddingFiles"] }
|
||||
|
||||
/// AddWorkspaceEmbeddingFiles
|
||||
///
|
||||
/// Parent Type: `CopilotWorkspaceFile`
|
||||
public struct AddWorkspaceEmbeddingFiles: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotWorkspaceFile }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("fileId", String.self),
|
||||
.field("fileName", String.self),
|
||||
.field("blobId", String.self),
|
||||
.field("mimeType", String.self),
|
||||
.field("size", AffineGraphQL.SafeInt.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
] }
|
||||
|
||||
public var fileId: String { __data["fileId"] }
|
||||
public var fileName: String { __data["fileName"] }
|
||||
public var blobId: String { __data["blobId"] }
|
||||
public var mimeType: String { __data["mimeType"] }
|
||||
public var size: AffineGraphQL.SafeInt { __data["size"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class AddWorkspaceEmbeddingIgnoredDocsMutation: GraphQLMutation {
|
||||
public static let operationName: String = "addWorkspaceEmbeddingIgnoredDocs"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation addWorkspaceEmbeddingIgnoredDocs($workspaceId: String!, $add: [String!]!) { updateWorkspaceEmbeddingIgnoredDocs(workspaceId: $workspaceId, add: $add) }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var add: [String]
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
add: [String]
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.add = add
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"add": add
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("updateWorkspaceEmbeddingIgnoredDocs", Int.self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"add": .variable("add")
|
||||
]),
|
||||
] }
|
||||
|
||||
/// Update ignored docs
|
||||
public var updateWorkspaceEmbeddingIgnoredDocs: Int { __data["updateWorkspaceEmbeddingIgnoredDocs"] }
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ public class ClaimAudioTranscriptionMutation: GraphQLMutation {
|
||||
public static let operationName: String = "claimAudioTranscription"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation claimAudioTranscription($jobId: String!) { claimAudioTranscription(jobId: $jobId) { __typename id status title summary transcription { __typename speaker start end transcription } } }"#
|
||||
#"mutation claimAudioTranscription($jobId: String!) { claimAudioTranscription(jobId: $jobId) { __typename id status title summary actions transcription { __typename speaker start end transcription } } }"#
|
||||
))
|
||||
|
||||
public var jobId: String
|
||||
@@ -43,6 +43,7 @@ public class ClaimAudioTranscriptionMutation: GraphQLMutation {
|
||||
.field("status", GraphQLEnum<AffineGraphQL.AiJobStatus>.self),
|
||||
.field("title", String?.self),
|
||||
.field("summary", String?.self),
|
||||
.field("actions", String?.self),
|
||||
.field("transcription", [Transcription]?.self),
|
||||
] }
|
||||
|
||||
@@ -50,6 +51,7 @@ public class ClaimAudioTranscriptionMutation: GraphQLMutation {
|
||||
public var status: GraphQLEnum<AffineGraphQL.AiJobStatus> { __data["status"] }
|
||||
public var title: String? { __data["title"] }
|
||||
public var summary: String? { __data["summary"] }
|
||||
public var actions: String? { __data["actions"] }
|
||||
public var transcription: [Transcription]? { __data["transcription"] }
|
||||
|
||||
/// ClaimAudioTranscription.Transcription
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class InstallLicenseMutation: GraphQLMutation {
|
||||
public static let operationName: String = "installLicense"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation installLicense($workspaceId: String!, $license: Upload!) { installLicense(workspaceId: $workspaceId, license: $license) { __typename ...licenseBody } }"#,
|
||||
fragments: [LicenseBody.self]
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var license: Upload
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
license: Upload
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.license = license
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"license": license
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("installLicense", InstallLicense.self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"license": .variable("license")
|
||||
]),
|
||||
] }
|
||||
|
||||
public var installLicense: InstallLicense { __data["installLicense"] }
|
||||
|
||||
/// InstallLicense
|
||||
///
|
||||
/// Parent Type: `License`
|
||||
public struct InstallLicense: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.License }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.fragment(LicenseBody.self),
|
||||
] }
|
||||
|
||||
public var expiredAt: AffineGraphQL.DateTime? { __data["expiredAt"] }
|
||||
public var installedAt: AffineGraphQL.DateTime { __data["installedAt"] }
|
||||
public var quantity: Int { __data["quantity"] }
|
||||
public var recurring: GraphQLEnum<AffineGraphQL.SubscriptionRecurring> { __data["recurring"] }
|
||||
public var validatedAt: AffineGraphQL.DateTime { __data["validatedAt"] }
|
||||
public var variant: GraphQLEnum<AffineGraphQL.SubscriptionVariant>? { __data["variant"] }
|
||||
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public var licenseBody: LicenseBody { _toFragment() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class InviteBatchMutation: GraphQLMutation {
|
||||
public static let operationName: String = "inviteBatch"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation inviteBatch($workspaceId: String!, $emails: [String!]!, $sendInviteMail: Boolean) { inviteBatch( workspaceId: $workspaceId emails: $emails sendInviteMail: $sendInviteMail ) { __typename email inviteId sentSuccess } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var emails: [String]
|
||||
public var sendInviteMail: GraphQLNullable<Bool>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
emails: [String],
|
||||
sendInviteMail: GraphQLNullable<Bool>
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.emails = emails
|
||||
self.sendInviteMail = sendInviteMail
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"emails": emails,
|
||||
"sendInviteMail": sendInviteMail
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
#warning("Argument 'sendInviteMail' of field 'inviteBatch' is deprecated. Reason: 'never used'")
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("inviteBatch", [InviteBatch].self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"emails": .variable("emails"),
|
||||
"sendInviteMail": .variable("sendInviteMail")
|
||||
]),
|
||||
] }
|
||||
|
||||
public var inviteBatch: [InviteBatch] { __data["inviteBatch"] }
|
||||
|
||||
/// InviteBatch
|
||||
///
|
||||
/// Parent Type: `InviteResult`
|
||||
public struct InviteBatch: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.InviteResult }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("email", String.self),
|
||||
.field("inviteId", String?.self),
|
||||
.field("sentSuccess", Bool.self),
|
||||
] }
|
||||
|
||||
public var email: String { __data["email"] }
|
||||
/// Invite id, null if invite record create failed
|
||||
public var inviteId: String? { __data["inviteId"] }
|
||||
/// Invite email sent success
|
||||
public var sentSuccess: Bool { __data["sentSuccess"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class InviteByEmailMutation: GraphQLMutation {
|
||||
public static let operationName: String = "inviteByEmail"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation inviteByEmail($workspaceId: String!, $email: String!, $sendInviteMail: Boolean) { invite( workspaceId: $workspaceId email: $email sendInviteMail: $sendInviteMail ) }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var email: String
|
||||
public var sendInviteMail: GraphQLNullable<Bool>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
email: String,
|
||||
sendInviteMail: GraphQLNullable<Bool>
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.email = email
|
||||
self.sendInviteMail = sendInviteMail
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"email": email,
|
||||
"sendInviteMail": sendInviteMail
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
#warning("Argument 'sendInviteMail' of field 'invite' is deprecated. Reason: 'never used'")
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("invite", String.self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"email": .variable("email"),
|
||||
"sendInviteMail": .variable("sendInviteMail")
|
||||
]),
|
||||
] }
|
||||
|
||||
public var invite: String { __data["invite"] }
|
||||
}
|
||||
}
|
||||
@@ -7,27 +7,23 @@ public class InviteByEmailsMutation: GraphQLMutation {
|
||||
public static let operationName: String = "inviteByEmails"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation inviteByEmails($workspaceId: String!, $emails: [String!]!, $sendInviteMail: Boolean) { inviteBatch( workspaceId: $workspaceId emails: $emails sendInviteMail: $sendInviteMail ) { __typename email inviteId sentSuccess } }"#
|
||||
#"mutation inviteByEmails($workspaceId: String!, $emails: [String!]!) { inviteMembers(workspaceId: $workspaceId, emails: $emails) { __typename email inviteId sentSuccess } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var emails: [String]
|
||||
public var sendInviteMail: GraphQLNullable<Bool>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
emails: [String],
|
||||
sendInviteMail: GraphQLNullable<Bool>
|
||||
emails: [String]
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.emails = emails
|
||||
self.sendInviteMail = sendInviteMail
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"emails": emails,
|
||||
"sendInviteMail": sendInviteMail
|
||||
"emails": emails
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
@@ -35,21 +31,19 @@ public class InviteByEmailsMutation: GraphQLMutation {
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
#warning("Argument 'sendInviteMail' of field 'inviteBatch' is deprecated. Reason: 'never used'")
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("inviteBatch", [InviteBatch].self, arguments: [
|
||||
.field("inviteMembers", [InviteMember].self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"emails": .variable("emails"),
|
||||
"sendInviteMail": .variable("sendInviteMail")
|
||||
"emails": .variable("emails")
|
||||
]),
|
||||
] }
|
||||
|
||||
public var inviteBatch: [InviteBatch] { __data["inviteBatch"] }
|
||||
public var inviteMembers: [InviteMember] { __data["inviteMembers"] }
|
||||
|
||||
/// InviteBatch
|
||||
/// InviteMember
|
||||
///
|
||||
/// Parent Type: `InviteResult`
|
||||
public struct InviteBatch: AffineGraphQL.SelectionSet {
|
||||
public struct InviteMember: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
@@ -65,6 +59,7 @@ public class InviteByEmailsMutation: GraphQLMutation {
|
||||
/// Invite id, null if invite record create failed
|
||||
public var inviteId: String? { __data["inviteId"] }
|
||||
/// Invite email sent success
|
||||
@available(*, deprecated, message: "Notification will be sent asynchronously")
|
||||
public var sentSuccess: Bool { __data["sentSuccess"] }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ public class LeaveWorkspaceMutation: GraphQLMutation {
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
#warning("Argument 'sendLeaveMail' of field 'leaveWorkspace' is deprecated. Reason: 'no used anymore'")
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("leaveWorkspace", Bool.self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class RemoveWorkspaceEmbeddingFilesMutation: GraphQLMutation {
|
||||
public static let operationName: String = "removeWorkspaceEmbeddingFiles"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation removeWorkspaceEmbeddingFiles($workspaceId: String!, $fileId: String!) { removeWorkspaceEmbeddingFiles(workspaceId: $workspaceId, fileId: $fileId) }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var fileId: String
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
fileId: String
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.fileId = fileId
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"fileId": fileId
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("removeWorkspaceEmbeddingFiles", Bool.self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"fileId": .variable("fileId")
|
||||
]),
|
||||
] }
|
||||
|
||||
/// Remove workspace embedding files
|
||||
public var removeWorkspaceEmbeddingFiles: Bool { __data["removeWorkspaceEmbeddingFiles"] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class RemoveWorkspaceEmbeddingIgnoredDocsMutation: GraphQLMutation {
|
||||
public static let operationName: String = "removeWorkspaceEmbeddingIgnoredDocs"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation removeWorkspaceEmbeddingIgnoredDocs($workspaceId: String!, $remove: [String!]!) { updateWorkspaceEmbeddingIgnoredDocs(workspaceId: $workspaceId, remove: $remove) }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var remove: [String]
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
remove: [String]
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.remove = remove
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"remove": remove
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("updateWorkspaceEmbeddingIgnoredDocs", Int.self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"remove": .variable("remove")
|
||||
]),
|
||||
] }
|
||||
|
||||
/// Update ignored docs
|
||||
public var updateWorkspaceEmbeddingIgnoredDocs: Int { __data["updateWorkspaceEmbeddingIgnoredDocs"] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class RetryAudioTranscriptionMutation: GraphQLMutation {
|
||||
public static let operationName: String = "retryAudioTranscription"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation retryAudioTranscription($workspaceId: String!, $jobId: String!) { retryAudioTranscription(workspaceId: $workspaceId, jobId: $jobId) { __typename id status } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var jobId: String
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
jobId: String
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.jobId = jobId
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"jobId": jobId
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("retryAudioTranscription", RetryAudioTranscription?.self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"jobId": .variable("jobId")
|
||||
]),
|
||||
] }
|
||||
|
||||
public var retryAudioTranscription: RetryAudioTranscription? { __data["retryAudioTranscription"] }
|
||||
|
||||
/// RetryAudioTranscription
|
||||
///
|
||||
/// Parent Type: `TranscriptionResultType`
|
||||
public struct RetryAudioTranscription: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.TranscriptionResultType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("status", GraphQLEnum<AffineGraphQL.AiJobStatus>.self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
public var status: GraphQLEnum<AffineGraphQL.AiJobStatus> { __data["status"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ public class RevokeMemberPermissionMutation: GraphQLMutation {
|
||||
public static let operationName: String = "revokeMemberPermission"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation revokeMemberPermission($workspaceId: String!, $userId: String!) { revoke(workspaceId: $workspaceId, userId: $userId) }"#
|
||||
#"mutation revokeMemberPermission($workspaceId: String!, $userId: String!) { revokeMember(workspaceId: $workspaceId, userId: $userId) }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
@@ -32,12 +32,12 @@ public class RevokeMemberPermissionMutation: GraphQLMutation {
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("revoke", Bool.self, arguments: [
|
||||
.field("revokeMember", Bool.self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"userId": .variable("userId")
|
||||
]),
|
||||
] }
|
||||
|
||||
public var revoke: Bool { __data["revoke"] }
|
||||
public var revokeMember: Bool { __data["revokeMember"] }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class SendTestEmailMutation: GraphQLMutation {
|
||||
public static let operationName: String = "sendTestEmail"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation sendTestEmail($host: String!, $port: Int!, $sender: String!, $username: String!, $password: String!, $ignoreTLS: Boolean!) { sendTestEmail( config: { host: $host port: $port sender: $sender username: $username password: $password ignoreTLS: $ignoreTLS } ) }"#
|
||||
))
|
||||
|
||||
public var host: String
|
||||
public var port: Int
|
||||
public var sender: String
|
||||
public var username: String
|
||||
public var password: String
|
||||
public var ignoreTLS: Bool
|
||||
|
||||
public init(
|
||||
host: String,
|
||||
port: Int,
|
||||
sender: String,
|
||||
username: String,
|
||||
password: String,
|
||||
ignoreTLS: Bool
|
||||
) {
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.sender = sender
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.ignoreTLS = ignoreTLS
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"host": host,
|
||||
"port": port,
|
||||
"sender": sender,
|
||||
"username": username,
|
||||
"password": password,
|
||||
"ignoreTLS": ignoreTLS
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("sendTestEmail", Bool.self, arguments: ["config": [
|
||||
"host": .variable("host"),
|
||||
"port": .variable("port"),
|
||||
"sender": .variable("sender"),
|
||||
"username": .variable("username"),
|
||||
"password": .variable("password"),
|
||||
"ignoreTLS": .variable("ignoreTLS")
|
||||
]]),
|
||||
] }
|
||||
|
||||
public var sendTestEmail: Bool { __data["sendTestEmail"] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class SetEnableDocEmbeddingMutation: GraphQLMutation {
|
||||
public static let operationName: String = "setEnableDocEmbedding"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation setEnableDocEmbedding($id: ID!, $enableDocEmbedding: Boolean!) { updateWorkspace(input: { id: $id, enableDocEmbedding: $enableDocEmbedding }) { __typename id } }"#
|
||||
))
|
||||
|
||||
public var id: ID
|
||||
public var enableDocEmbedding: Bool
|
||||
|
||||
public init(
|
||||
id: ID,
|
||||
enableDocEmbedding: Bool
|
||||
) {
|
||||
self.id = id
|
||||
self.enableDocEmbedding = enableDocEmbedding
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"id": id,
|
||||
"enableDocEmbedding": enableDocEmbedding
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("updateWorkspace", UpdateWorkspace.self, arguments: ["input": [
|
||||
"id": .variable("id"),
|
||||
"enableDocEmbedding": .variable("enableDocEmbedding")
|
||||
]]),
|
||||
] }
|
||||
|
||||
/// Update workspace
|
||||
public var updateWorkspace: UpdateWorkspace { __data["updateWorkspace"] }
|
||||
|
||||
/// UpdateWorkspace
|
||||
///
|
||||
/// Parent Type: `WorkspaceType`
|
||||
public struct UpdateWorkspace: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspaceType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,27 +7,31 @@ public class SubmitAudioTranscriptionMutation: GraphQLMutation {
|
||||
public static let operationName: String = "submitAudioTranscription"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation submitAudioTranscription($workspaceId: String!, $blobId: String!, $blob: Upload!) { submitAudioTranscription( blob: $blob blobId: $blobId workspaceId: $workspaceId ) { __typename id status } }"#
|
||||
#"mutation submitAudioTranscription($workspaceId: String!, $blobId: String!, $blob: Upload, $blobs: [Upload!]) { submitAudioTranscription( blob: $blob blobs: $blobs blobId: $blobId workspaceId: $workspaceId ) { __typename id status } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var blobId: String
|
||||
public var blob: Upload
|
||||
public var blob: GraphQLNullable<Upload>
|
||||
public var blobs: GraphQLNullable<[Upload]>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
blobId: String,
|
||||
blob: Upload
|
||||
blob: GraphQLNullable<Upload>,
|
||||
blobs: GraphQLNullable<[Upload]>
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.blobId = blobId
|
||||
self.blob = blob
|
||||
self.blobs = blobs
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"blobId": blobId,
|
||||
"blob": blob
|
||||
"blob": blob,
|
||||
"blobs": blobs
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
@@ -38,6 +42,7 @@ public class SubmitAudioTranscriptionMutation: GraphQLMutation {
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("submitAudioTranscription", SubmitAudioTranscription?.self, arguments: [
|
||||
"blob": .variable("blob"),
|
||||
"blobs": .variable("blobs"),
|
||||
"blobId": .variable("blobId"),
|
||||
"workspaceId": .variable("workspaceId")
|
||||
]),
|
||||
|
||||
@@ -7,7 +7,7 @@ public class UpdatePromptMutation: GraphQLMutation {
|
||||
public static let operationName: String = "updatePrompt"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation updatePrompt($name: String!, $messages: [CopilotPromptMessageInput!]!) { updateCopilotPrompt(name: $name, messages: $messages) { __typename name model action config { __typename jsonMode frequencyPenalty presencePenalty temperature topP } messages { __typename role content params } } }"#
|
||||
#"mutation updatePrompt($name: String!, $messages: [CopilotPromptMessageInput!]!) { updateCopilotPrompt(name: $name, messages: $messages) { __typename name model action config { __typename frequencyPenalty presencePenalty temperature topP } messages { __typename role content params } } }"#
|
||||
))
|
||||
|
||||
public var name: String
|
||||
@@ -74,14 +74,12 @@ public class UpdatePromptMutation: GraphQLMutation {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotPromptConfigType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("jsonMode", Bool?.self),
|
||||
.field("frequencyPenalty", Double?.self),
|
||||
.field("presencePenalty", Double?.self),
|
||||
.field("temperature", Double?.self),
|
||||
.field("topP", Double?.self),
|
||||
] }
|
||||
|
||||
public var jsonMode: Bool? { __data["jsonMode"] }
|
||||
public var frequencyPenalty: Double? { __data["frequencyPenalty"] }
|
||||
public var presencePenalty: Double? { __data["presencePenalty"] }
|
||||
public var temperature: Double? { __data["temperature"] }
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class ValidateConfigMutation: GraphQLMutation {
|
||||
public static let operationName: String = "validateConfig"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation validateConfig($updates: [UpdateAppConfigInput!]!) { validateAppConfig(updates: $updates) { __typename module key value valid error } }"#
|
||||
))
|
||||
|
||||
public var updates: [UpdateAppConfigInput]
|
||||
|
||||
public init(updates: [UpdateAppConfigInput]) {
|
||||
self.updates = updates
|
||||
}
|
||||
|
||||
public var __variables: Variables? { ["updates": updates] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("validateAppConfig", [ValidateAppConfig].self, arguments: ["updates": .variable("updates")]),
|
||||
] }
|
||||
|
||||
/// validate app configuration
|
||||
public var validateAppConfig: [ValidateAppConfig] { __data["validateAppConfig"] }
|
||||
|
||||
/// ValidateAppConfig
|
||||
///
|
||||
/// Parent Type: `AppConfigValidateResult`
|
||||
public struct ValidateAppConfig: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.AppConfigValidateResult }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("module", String.self),
|
||||
.field("key", String.self),
|
||||
.field("value", AffineGraphQL.JSON.self),
|
||||
.field("valid", Bool.self),
|
||||
.field("error", String?.self),
|
||||
] }
|
||||
|
||||
public var module: String { __data["module"] }
|
||||
public var key: String { __data["key"] }
|
||||
public var value: AffineGraphQL.JSON { __data["value"] }
|
||||
public var valid: Bool { __data["valid"] }
|
||||
public var error: String? { __data["error"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class GetAllWorkspaceEmbeddingIgnoredDocsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getAllWorkspaceEmbeddingIgnoredDocs"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getAllWorkspaceEmbeddingIgnoredDocs($workspaceId: String!) { workspace(id: $workspaceId) { __typename embedding { __typename allIgnoredDocs { __typename docId createdAt } } } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
|
||||
public init(workspaceId: String) {
|
||||
self.workspaceId = workspaceId
|
||||
}
|
||||
|
||||
public var __variables: Variables? { ["workspaceId": workspaceId] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("workspace", Workspace.self, arguments: ["id": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
/// Get workspace by id
|
||||
public var workspace: Workspace { __data["workspace"] }
|
||||
|
||||
/// Workspace
|
||||
///
|
||||
/// Parent Type: `WorkspaceType`
|
||||
public struct Workspace: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspaceType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("embedding", Embedding.self),
|
||||
] }
|
||||
|
||||
public var embedding: Embedding { __data["embedding"] }
|
||||
|
||||
/// Workspace.Embedding
|
||||
///
|
||||
/// Parent Type: `CopilotWorkspaceConfig`
|
||||
public struct Embedding: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotWorkspaceConfig }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("allIgnoredDocs", [AllIgnoredDoc].self),
|
||||
] }
|
||||
|
||||
public var allIgnoredDocs: [AllIgnoredDoc] { __data["allIgnoredDocs"] }
|
||||
|
||||
/// Workspace.Embedding.AllIgnoredDoc
|
||||
///
|
||||
/// Parent Type: `CopilotWorkspaceIgnoredDoc`
|
||||
public struct AllIgnoredDoc: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotWorkspaceIgnoredDoc }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("docId", String.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
] }
|
||||
|
||||
public var docId: String { __data["docId"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class GetCopilotSessionQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getCopilotSession"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getCopilotSession($workspaceId: String!, $sessionId: String!) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename session(sessionId: $sessionId) { __typename id parentSessionId promptName model optionalModels } } } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var sessionId: String
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
sessionId: String
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.sessionId = sessionId
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"sessionId": sessionId
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("currentUser", CurrentUser?.self),
|
||||
] }
|
||||
|
||||
/// Get current user
|
||||
public var currentUser: CurrentUser? { __data["currentUser"] }
|
||||
|
||||
/// CurrentUser
|
||||
///
|
||||
/// Parent Type: `UserType`
|
||||
public struct CurrentUser: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.UserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("copilot", Copilot.self, arguments: ["workspaceId": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
public var copilot: Copilot { __data["copilot"] }
|
||||
|
||||
/// CurrentUser.Copilot
|
||||
///
|
||||
/// Parent Type: `Copilot`
|
||||
public struct Copilot: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Copilot }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("session", Session.self, arguments: ["sessionId": .variable("sessionId")]),
|
||||
] }
|
||||
|
||||
/// Get the session by id
|
||||
public var session: Session { __data["session"] }
|
||||
|
||||
/// CurrentUser.Copilot.Session
|
||||
///
|
||||
/// Parent Type: `CopilotSessionType`
|
||||
public struct Session: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotSessionType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("parentSessionId", AffineGraphQL.ID?.self),
|
||||
.field("promptName", String.self),
|
||||
.field("model", String.self),
|
||||
.field("optionalModels", [String].self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
public var parentSessionId: AffineGraphQL.ID? { __data["parentSessionId"] }
|
||||
public var promptName: String { __data["promptName"] }
|
||||
public var model: String { __data["model"] }
|
||||
public var optionalModels: [String] { __data["optionalModels"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ public class GetCopilotSessionsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getCopilotSessions"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getCopilotSessions($workspaceId: String!, $docId: String, $options: QueryChatSessionsInput) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename sessions(docId: $docId, options: $options) { __typename id parentSessionId promptName } } } }"#
|
||||
#"query getCopilotSessions($workspaceId: String!, $docId: String, $options: QueryChatSessionsInput) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename sessions(docId: $docId, options: $options) { __typename id parentSessionId promptName model optionalModels } } } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
@@ -89,11 +89,15 @@ public class GetCopilotSessionsQuery: GraphQLQuery {
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("parentSessionId", AffineGraphQL.ID?.self),
|
||||
.field("promptName", String.self),
|
||||
.field("model", String.self),
|
||||
.field("optionalModels", [String].self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
public var parentSessionId: AffineGraphQL.ID? { __data["parentSessionId"] }
|
||||
public var promptName: String { __data["promptName"] }
|
||||
public var model: String { __data["model"] }
|
||||
public var optionalModels: [String] { __data["optionalModels"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class GetDocCreatedByUpdatedByListQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getDocCreatedByUpdatedByList"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getDocCreatedByUpdatedByList($workspaceId: String!, $pagination: PaginationInput!) { workspace(id: $workspaceId) { __typename docs(pagination: $pagination) { __typename totalCount pageInfo { __typename endCursor hasNextPage } edges { __typename node { __typename id creatorId lastUpdaterId } } } } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var pagination: PaginationInput
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
pagination: PaginationInput
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.pagination = pagination
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"pagination": pagination
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("workspace", Workspace.self, arguments: ["id": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
/// Get workspace by id
|
||||
public var workspace: Workspace { __data["workspace"] }
|
||||
|
||||
/// Workspace
|
||||
///
|
||||
/// Parent Type: `WorkspaceType`
|
||||
public struct Workspace: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspaceType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("docs", Docs.self, arguments: ["pagination": .variable("pagination")]),
|
||||
] }
|
||||
|
||||
public var docs: Docs { __data["docs"] }
|
||||
|
||||
/// Workspace.Docs
|
||||
///
|
||||
/// Parent Type: `PaginatedDocType`
|
||||
public struct Docs: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedDocType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("totalCount", Int.self),
|
||||
.field("pageInfo", PageInfo.self),
|
||||
.field("edges", [Edge].self),
|
||||
] }
|
||||
|
||||
public var totalCount: Int { __data["totalCount"] }
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
/// Workspace.Docs.PageInfo
|
||||
///
|
||||
/// Parent Type: `PageInfo`
|
||||
public struct PageInfo: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PageInfo }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("endCursor", String?.self),
|
||||
.field("hasNextPage", Bool.self),
|
||||
] }
|
||||
|
||||
public var endCursor: String? { __data["endCursor"] }
|
||||
public var hasNextPage: Bool { __data["hasNextPage"] }
|
||||
}
|
||||
|
||||
/// Workspace.Docs.Edge
|
||||
///
|
||||
/// Parent Type: `DocTypeEdge`
|
||||
public struct Edge: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.DocTypeEdge }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("node", Node.self),
|
||||
] }
|
||||
|
||||
public var node: Node { __data["node"] }
|
||||
|
||||
/// Workspace.Docs.Edge.Node
|
||||
///
|
||||
/// Parent Type: `DocType`
|
||||
public struct Node: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.DocType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", String.self),
|
||||
.field("creatorId", String?.self),
|
||||
.field("lastUpdaterId", String?.self),
|
||||
] }
|
||||
|
||||
public var id: String { __data["id"] }
|
||||
public var creatorId: String? { __data["creatorId"] }
|
||||
public var lastUpdaterId: String? { __data["lastUpdaterId"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ public class GetInviteInfoQuery: GraphQLQuery {
|
||||
.field("getInviteInfo", GetInviteInfo.self, arguments: ["inviteId": .variable("inviteId")]),
|
||||
] }
|
||||
|
||||
/// send workspace invitation
|
||||
/// get workspace invitation info
|
||||
public var getInviteInfo: GetInviteInfo { __data["getInviteInfo"] }
|
||||
|
||||
/// GetInviteInfo
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class GetIsAdminQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getIsAdmin"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getIsAdmin($workspaceId: String!) { isAdmin(workspaceId: $workspaceId) }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
|
||||
public init(workspaceId: String) {
|
||||
self.workspaceId = workspaceId
|
||||
}
|
||||
|
||||
public var __variables: Variables? { ["workspaceId": workspaceId] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("isAdmin", Bool.self, arguments: ["workspaceId": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
/// Get is admin of workspace
|
||||
@available(*, deprecated, message: "use WorkspaceType[role] instead")
|
||||
public var isAdmin: Bool { __data["isAdmin"] }
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class GetIsOwnerQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getIsOwner"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getIsOwner($workspaceId: String!) { isOwner(workspaceId: $workspaceId) }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
|
||||
public init(workspaceId: String) {
|
||||
self.workspaceId = workspaceId
|
||||
}
|
||||
|
||||
public var __variables: Variables? { ["workspaceId": workspaceId] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("isOwner", Bool.self, arguments: ["workspaceId": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
/// Get is owner of workspace
|
||||
@available(*, deprecated, message: "use WorkspaceType[role] instead")
|
||||
public var isOwner: Bool { __data["isOwner"] }
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,8 @@ public class GetLicenseQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getLicense"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getLicense($workspaceId: String!) { workspace(id: $workspaceId) { __typename license { __typename expiredAt installedAt quantity recurring validatedAt } } }"#
|
||||
#"query getLicense($workspaceId: String!) { workspace(id: $workspaceId) { __typename license { __typename ...licenseBody } } }"#,
|
||||
fragments: [LicenseBody.self]
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
@@ -56,11 +57,7 @@ public class GetLicenseQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.License }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("expiredAt", AffineGraphQL.DateTime?.self),
|
||||
.field("installedAt", AffineGraphQL.DateTime.self),
|
||||
.field("quantity", Int.self),
|
||||
.field("recurring", GraphQLEnum<AffineGraphQL.SubscriptionRecurring>.self),
|
||||
.field("validatedAt", AffineGraphQL.DateTime.self),
|
||||
.fragment(LicenseBody.self),
|
||||
] }
|
||||
|
||||
public var expiredAt: AffineGraphQL.DateTime? { __data["expiredAt"] }
|
||||
@@ -68,6 +65,14 @@ public class GetLicenseQuery: GraphQLQuery {
|
||||
public var quantity: Int { __data["quantity"] }
|
||||
public var recurring: GraphQLEnum<AffineGraphQL.SubscriptionRecurring> { __data["recurring"] }
|
||||
public var validatedAt: AffineGraphQL.DateTime { __data["validatedAt"] }
|
||||
public var variant: GraphQLEnum<AffineGraphQL.SubscriptionVariant>? { __data["variant"] }
|
||||
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public var licenseBody: LicenseBody { _toFragment() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ public class GetPromptsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getPrompts"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getPrompts { listCopilotPrompts { __typename name model action config { __typename jsonMode frequencyPenalty presencePenalty temperature topP } messages { __typename role content params } } }"#
|
||||
#"query getPrompts { listCopilotPrompts { __typename name model action config { __typename frequencyPenalty presencePenalty temperature topP } messages { __typename role content params } } }"#
|
||||
))
|
||||
|
||||
public init() {}
|
||||
@@ -57,14 +57,12 @@ public class GetPromptsQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotPromptConfigType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("jsonMode", Bool?.self),
|
||||
.field("frequencyPenalty", Double?.self),
|
||||
.field("presencePenalty", Double?.self),
|
||||
.field("temperature", Double?.self),
|
||||
.field("topP", Double?.self),
|
||||
] }
|
||||
|
||||
public var jsonMode: Bool? { __data["jsonMode"] }
|
||||
public var frequencyPenalty: Double? { __data["frequencyPenalty"] }
|
||||
public var presencePenalty: Double? { __data["presencePenalty"] }
|
||||
public var temperature: Double? { __data["temperature"] }
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class GetUsersCountQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getUsersCount"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getUsersCount { usersCount }"#
|
||||
))
|
||||
|
||||
public init() {}
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("usersCount", Int.self),
|
||||
] }
|
||||
|
||||
/// Get users count
|
||||
public var usersCount: Int { __data["usersCount"] }
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ public class GetWorkspaceConfigQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getWorkspaceConfig"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getWorkspaceConfig($id: String!) { workspace(id: $id) { __typename enableAi enableUrlPreview inviteLink { __typename link expireTime } } }"#
|
||||
#"query getWorkspaceConfig($id: String!) { workspace(id: $id) { __typename enableAi enableUrlPreview enableDocEmbedding inviteLink { __typename link expireTime } } }"#
|
||||
))
|
||||
|
||||
public var id: String
|
||||
@@ -42,6 +42,7 @@ public class GetWorkspaceConfigQuery: GraphQLQuery {
|
||||
.field("__typename", String.self),
|
||||
.field("enableAi", Bool.self),
|
||||
.field("enableUrlPreview", Bool.self),
|
||||
.field("enableDocEmbedding", Bool.self),
|
||||
.field("inviteLink", InviteLink?.self),
|
||||
] }
|
||||
|
||||
@@ -49,6 +50,8 @@ public class GetWorkspaceConfigQuery: GraphQLQuery {
|
||||
public var enableAi: Bool { __data["enableAi"] }
|
||||
/// Enable url previous when sharing
|
||||
public var enableUrlPreview: Bool { __data["enableUrlPreview"] }
|
||||
/// Enable doc embedding
|
||||
public var enableDocEmbedding: Bool { __data["enableDocEmbedding"] }
|
||||
/// invite link for workspace
|
||||
public var inviteLink: InviteLink? { __data["inviteLink"] }
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class GetWorkspaceEmbeddingFilesQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getWorkspaceEmbeddingFiles"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getWorkspaceEmbeddingFiles($workspaceId: String!, $pagination: PaginationInput!) { workspace(id: $workspaceId) { __typename embedding { __typename files(pagination: $pagination) { __typename totalCount pageInfo { __typename endCursor hasNextPage } edges { __typename node { __typename fileId fileName blobId mimeType size createdAt } } } } } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var pagination: PaginationInput
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
pagination: PaginationInput
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.pagination = pagination
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"pagination": pagination
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("workspace", Workspace.self, arguments: ["id": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
/// Get workspace by id
|
||||
public var workspace: Workspace { __data["workspace"] }
|
||||
|
||||
/// Workspace
|
||||
///
|
||||
/// Parent Type: `WorkspaceType`
|
||||
public struct Workspace: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspaceType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("embedding", Embedding.self),
|
||||
] }
|
||||
|
||||
public var embedding: Embedding { __data["embedding"] }
|
||||
|
||||
/// Workspace.Embedding
|
||||
///
|
||||
/// Parent Type: `CopilotWorkspaceConfig`
|
||||
public struct Embedding: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotWorkspaceConfig }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("files", Files.self, arguments: ["pagination": .variable("pagination")]),
|
||||
] }
|
||||
|
||||
public var files: Files { __data["files"] }
|
||||
|
||||
/// Workspace.Embedding.Files
|
||||
///
|
||||
/// Parent Type: `PaginatedCopilotWorkspaceFileType`
|
||||
public struct Files: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCopilotWorkspaceFileType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("totalCount", Int.self),
|
||||
.field("pageInfo", PageInfo.self),
|
||||
.field("edges", [Edge].self),
|
||||
] }
|
||||
|
||||
public var totalCount: Int { __data["totalCount"] }
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
/// Workspace.Embedding.Files.PageInfo
|
||||
///
|
||||
/// Parent Type: `PageInfo`
|
||||
public struct PageInfo: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PageInfo }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("endCursor", String?.self),
|
||||
.field("hasNextPage", Bool.self),
|
||||
] }
|
||||
|
||||
public var endCursor: String? { __data["endCursor"] }
|
||||
public var hasNextPage: Bool { __data["hasNextPage"] }
|
||||
}
|
||||
|
||||
/// Workspace.Embedding.Files.Edge
|
||||
///
|
||||
/// Parent Type: `CopilotWorkspaceFileTypeEdge`
|
||||
public struct Edge: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotWorkspaceFileTypeEdge }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("node", Node.self),
|
||||
] }
|
||||
|
||||
public var node: Node { __data["node"] }
|
||||
|
||||
/// Workspace.Embedding.Files.Edge.Node
|
||||
///
|
||||
/// Parent Type: `CopilotWorkspaceFile`
|
||||
public struct Node: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotWorkspaceFile }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("fileId", String.self),
|
||||
.field("fileName", String.self),
|
||||
.field("blobId", String.self),
|
||||
.field("mimeType", String.self),
|
||||
.field("size", AffineGraphQL.SafeInt.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
] }
|
||||
|
||||
public var fileId: String { __data["fileId"] }
|
||||
public var fileName: String { __data["fileName"] }
|
||||
public var blobId: String { __data["blobId"] }
|
||||
public var mimeType: String { __data["mimeType"] }
|
||||
public var size: AffineGraphQL.SafeInt { __data["size"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class GetWorkspaceEmbeddingIgnoredDocsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getWorkspaceEmbeddingIgnoredDocs"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getWorkspaceEmbeddingIgnoredDocs($workspaceId: String!, $pagination: PaginationInput!) { workspace(id: $workspaceId) { __typename embedding { __typename ignoredDocs(pagination: $pagination) { __typename totalCount pageInfo { __typename endCursor hasNextPage } edges { __typename node { __typename docId createdAt docCreatedAt docUpdatedAt title createdBy createdByAvatar updatedBy } } } } } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var pagination: PaginationInput
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
pagination: PaginationInput
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.pagination = pagination
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"pagination": pagination
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("workspace", Workspace.self, arguments: ["id": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
/// Get workspace by id
|
||||
public var workspace: Workspace { __data["workspace"] }
|
||||
|
||||
/// Workspace
|
||||
///
|
||||
/// Parent Type: `WorkspaceType`
|
||||
public struct Workspace: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspaceType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("embedding", Embedding.self),
|
||||
] }
|
||||
|
||||
public var embedding: Embedding { __data["embedding"] }
|
||||
|
||||
/// Workspace.Embedding
|
||||
///
|
||||
/// Parent Type: `CopilotWorkspaceConfig`
|
||||
public struct Embedding: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotWorkspaceConfig }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("ignoredDocs", IgnoredDocs.self, arguments: ["pagination": .variable("pagination")]),
|
||||
] }
|
||||
|
||||
public var ignoredDocs: IgnoredDocs { __data["ignoredDocs"] }
|
||||
|
||||
/// Workspace.Embedding.IgnoredDocs
|
||||
///
|
||||
/// Parent Type: `PaginatedIgnoredDocsType`
|
||||
public struct IgnoredDocs: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedIgnoredDocsType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("totalCount", Int.self),
|
||||
.field("pageInfo", PageInfo.self),
|
||||
.field("edges", [Edge].self),
|
||||
] }
|
||||
|
||||
public var totalCount: Int { __data["totalCount"] }
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
/// Workspace.Embedding.IgnoredDocs.PageInfo
|
||||
///
|
||||
/// Parent Type: `PageInfo`
|
||||
public struct PageInfo: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PageInfo }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("endCursor", String?.self),
|
||||
.field("hasNextPage", Bool.self),
|
||||
] }
|
||||
|
||||
public var endCursor: String? { __data["endCursor"] }
|
||||
public var hasNextPage: Bool { __data["hasNextPage"] }
|
||||
}
|
||||
|
||||
/// Workspace.Embedding.IgnoredDocs.Edge
|
||||
///
|
||||
/// Parent Type: `CopilotWorkspaceIgnoredDocTypeEdge`
|
||||
public struct Edge: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotWorkspaceIgnoredDocTypeEdge }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("node", Node.self),
|
||||
] }
|
||||
|
||||
public var node: Node { __data["node"] }
|
||||
|
||||
/// Workspace.Embedding.IgnoredDocs.Edge.Node
|
||||
///
|
||||
/// Parent Type: `CopilotWorkspaceIgnoredDoc`
|
||||
public struct Node: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotWorkspaceIgnoredDoc }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("docId", String.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
.field("docCreatedAt", AffineGraphQL.DateTime?.self),
|
||||
.field("docUpdatedAt", AffineGraphQL.DateTime?.self),
|
||||
.field("title", String?.self),
|
||||
.field("createdBy", String?.self),
|
||||
.field("createdByAvatar", String?.self),
|
||||
.field("updatedBy", String?.self),
|
||||
] }
|
||||
|
||||
public var docId: String { __data["docId"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
public var docCreatedAt: AffineGraphQL.DateTime? { __data["docCreatedAt"] }
|
||||
public var docUpdatedAt: AffineGraphQL.DateTime? { __data["docUpdatedAt"] }
|
||||
public var title: String? { __data["title"] }
|
||||
public var createdBy: String? { __data["createdBy"] }
|
||||
public var createdByAvatar: String? { __data["createdByAvatar"] }
|
||||
public var updatedBy: String? { __data["updatedBy"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ public class GetWorkspaceInfoQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getWorkspaceInfo"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getWorkspaceInfo($workspaceId: String!) { isAdmin(workspaceId: $workspaceId) isOwner(workspaceId: $workspaceId) workspace(id: $workspaceId) { __typename team } }"#
|
||||
#"query getWorkspaceInfo($workspaceId: String!) { workspace(id: $workspaceId) { __typename role team } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
@@ -24,17 +24,9 @@ public class GetWorkspaceInfoQuery: GraphQLQuery {
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("isAdmin", Bool.self, arguments: ["workspaceId": .variable("workspaceId")]),
|
||||
.field("isOwner", Bool.self, arguments: ["workspaceId": .variable("workspaceId")]),
|
||||
.field("workspace", Workspace.self, arguments: ["id": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
/// Get is admin of workspace
|
||||
@available(*, deprecated, message: "use WorkspaceType[role] instead")
|
||||
public var isAdmin: Bool { __data["isAdmin"] }
|
||||
/// Get is owner of workspace
|
||||
@available(*, deprecated, message: "use WorkspaceType[role] instead")
|
||||
public var isOwner: Bool { __data["isOwner"] }
|
||||
/// Get workspace by id
|
||||
public var workspace: Workspace { __data["workspace"] }
|
||||
|
||||
@@ -48,9 +40,12 @@ public class GetWorkspaceInfoQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspaceType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("role", GraphQLEnum<AffineGraphQL.Permission>.self),
|
||||
.field("team", Bool.self),
|
||||
] }
|
||||
|
||||
/// Role of current signed in user in workspace
|
||||
public var role: GraphQLEnum<AffineGraphQL.Permission> { __data["role"] }
|
||||
/// if workspace is team workspace
|
||||
public var team: Bool { __data["team"] }
|
||||
}
|
||||
|
||||
@@ -52,16 +52,17 @@ public class GetWorkspacePageMetaByIdQuery: GraphQLQuery {
|
||||
] }
|
||||
|
||||
/// Cloud page metadata of workspace
|
||||
@available(*, deprecated, message: "use [WorkspaceType.doc] instead")
|
||||
public var pageMeta: PageMeta { __data["pageMeta"] }
|
||||
|
||||
/// Workspace.PageMeta
|
||||
///
|
||||
/// Parent Type: `WorkspacePageMeta`
|
||||
/// Parent Type: `WorkspaceDocMeta`
|
||||
public struct PageMeta: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspacePageMeta }
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspaceDocMeta }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class IndexerAggregateQuery: GraphQLQuery {
|
||||
public static let operationName: String = "indexerAggregate"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query indexerAggregate($id: String!, $input: AggregateInput!) { workspace(id: $id) { __typename aggregate(input: $input) { __typename buckets { __typename key count hits { __typename nodes { __typename fields highlights } } } pagination { __typename count hasMore nextCursor } } } }"#
|
||||
))
|
||||
|
||||
public var id: String
|
||||
public var input: AggregateInput
|
||||
|
||||
public init(
|
||||
id: String,
|
||||
input: AggregateInput
|
||||
) {
|
||||
self.id = id
|
||||
self.input = input
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"id": id,
|
||||
"input": input
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("workspace", Workspace.self, arguments: ["id": .variable("id")]),
|
||||
] }
|
||||
|
||||
/// Get workspace by id
|
||||
public var workspace: Workspace { __data["workspace"] }
|
||||
|
||||
/// Workspace
|
||||
///
|
||||
/// Parent Type: `WorkspaceType`
|
||||
public struct Workspace: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspaceType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("aggregate", Aggregate.self, arguments: ["input": .variable("input")]),
|
||||
] }
|
||||
|
||||
/// Search a specific table with aggregate
|
||||
public var aggregate: Aggregate { __data["aggregate"] }
|
||||
|
||||
/// Workspace.Aggregate
|
||||
///
|
||||
/// Parent Type: `AggregateResultObjectType`
|
||||
public struct Aggregate: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.AggregateResultObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("buckets", [Bucket].self),
|
||||
.field("pagination", Pagination.self),
|
||||
] }
|
||||
|
||||
public var buckets: [Bucket] { __data["buckets"] }
|
||||
public var pagination: Pagination { __data["pagination"] }
|
||||
|
||||
/// Workspace.Aggregate.Bucket
|
||||
///
|
||||
/// Parent Type: `AggregateBucketObjectType`
|
||||
public struct Bucket: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.AggregateBucketObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("key", String.self),
|
||||
.field("count", Int.self),
|
||||
.field("hits", Hits.self),
|
||||
] }
|
||||
|
||||
public var key: String { __data["key"] }
|
||||
public var count: Int { __data["count"] }
|
||||
/// The hits object
|
||||
public var hits: Hits { __data["hits"] }
|
||||
|
||||
/// Workspace.Aggregate.Bucket.Hits
|
||||
///
|
||||
/// Parent Type: `AggregateBucketHitsObjectType`
|
||||
public struct Hits: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.AggregateBucketHitsObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("nodes", [Node].self),
|
||||
] }
|
||||
|
||||
public var nodes: [Node] { __data["nodes"] }
|
||||
|
||||
/// Workspace.Aggregate.Bucket.Hits.Node
|
||||
///
|
||||
/// Parent Type: `SearchNodeObjectType`
|
||||
public struct Node: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.SearchNodeObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("fields", AffineGraphQL.JSONObject.self),
|
||||
.field("highlights", AffineGraphQL.JSONObject?.self),
|
||||
] }
|
||||
|
||||
/// The search result fields, see UnionSearchItemObjectType
|
||||
public var fields: AffineGraphQL.JSONObject { __data["fields"] }
|
||||
/// The search result fields, see UnionSearchItemObjectType
|
||||
public var highlights: AffineGraphQL.JSONObject? { __data["highlights"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Workspace.Aggregate.Pagination
|
||||
///
|
||||
/// Parent Type: `SearchResultPagination`
|
||||
public struct Pagination: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.SearchResultPagination }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("count", Int.self),
|
||||
.field("hasMore", Bool.self),
|
||||
.field("nextCursor", String?.self),
|
||||
] }
|
||||
|
||||
public var count: Int { __data["count"] }
|
||||
public var hasMore: Bool { __data["hasMore"] }
|
||||
public var nextCursor: String? { __data["nextCursor"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class IndexerSearchQuery: GraphQLQuery {
|
||||
public static let operationName: String = "indexerSearch"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query indexerSearch($id: String!, $input: SearchInput!) { workspace(id: $id) { __typename search(input: $input) { __typename nodes { __typename fields highlights } pagination { __typename count hasMore nextCursor } } } }"#
|
||||
))
|
||||
|
||||
public var id: String
|
||||
public var input: SearchInput
|
||||
|
||||
public init(
|
||||
id: String,
|
||||
input: SearchInput
|
||||
) {
|
||||
self.id = id
|
||||
self.input = input
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"id": id,
|
||||
"input": input
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("workspace", Workspace.self, arguments: ["id": .variable("id")]),
|
||||
] }
|
||||
|
||||
/// Get workspace by id
|
||||
public var workspace: Workspace { __data["workspace"] }
|
||||
|
||||
/// Workspace
|
||||
///
|
||||
/// Parent Type: `WorkspaceType`
|
||||
public struct Workspace: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspaceType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("search", Search.self, arguments: ["input": .variable("input")]),
|
||||
] }
|
||||
|
||||
/// Search a specific table
|
||||
public var search: Search { __data["search"] }
|
||||
|
||||
/// Workspace.Search
|
||||
///
|
||||
/// Parent Type: `SearchResultObjectType`
|
||||
public struct Search: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.SearchResultObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("nodes", [Node].self),
|
||||
.field("pagination", Pagination.self),
|
||||
] }
|
||||
|
||||
public var nodes: [Node] { __data["nodes"] }
|
||||
public var pagination: Pagination { __data["pagination"] }
|
||||
|
||||
/// Workspace.Search.Node
|
||||
///
|
||||
/// Parent Type: `SearchNodeObjectType`
|
||||
public struct Node: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.SearchNodeObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("fields", AffineGraphQL.JSONObject.self),
|
||||
.field("highlights", AffineGraphQL.JSONObject?.self),
|
||||
] }
|
||||
|
||||
/// The search result fields, see UnionSearchItemObjectType
|
||||
public var fields: AffineGraphQL.JSONObject { __data["fields"] }
|
||||
/// The search result fields, see UnionSearchItemObjectType
|
||||
public var highlights: AffineGraphQL.JSONObject? { __data["highlights"] }
|
||||
}
|
||||
|
||||
/// Workspace.Search.Pagination
|
||||
///
|
||||
/// Parent Type: `SearchResultPagination`
|
||||
public struct Pagination: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.SearchResultPagination }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("count", Int.self),
|
||||
.field("hasMore", Bool.self),
|
||||
.field("nextCursor", String?.self),
|
||||
] }
|
||||
|
||||
public var count: Int { __data["count"] }
|
||||
public var hasMore: Bool { __data["hasMore"] }
|
||||
public var nextCursor: String? { __data["nextCursor"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ public class ListContextObjectQuery: GraphQLQuery {
|
||||
public static let operationName: String = "listContextObject"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query listContextObject($workspaceId: String!, $sessionId: String!, $contextId: String!) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename contexts(sessionId: $sessionId, contextId: $contextId) { __typename docs { __typename id status error createdAt } files { __typename id name blobId chunkSize error status createdAt } tags { __typename type id docs { __typename id status createdAt } createdAt } collections { __typename type id docs { __typename id status createdAt } createdAt } } } } }"#
|
||||
#"query listContextObject($workspaceId: String!, $sessionId: String!, $contextId: String!) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename contexts(sessionId: $sessionId, contextId: $contextId) { __typename docs { __typename id status error createdAt } files { __typename id name mimeType blobId chunkSize error status createdAt } tags { __typename type id docs { __typename id status createdAt } createdAt } collections { __typename type id docs { __typename id status createdAt } createdAt } } } } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
@@ -135,6 +135,7 @@ public class ListContextObjectQuery: GraphQLQuery {
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("name", String.self),
|
||||
.field("mimeType", String.self),
|
||||
.field("blobId", String.self),
|
||||
.field("chunkSize", AffineGraphQL.SafeInt.self),
|
||||
.field("error", String?.self),
|
||||
@@ -144,6 +145,7 @@ public class ListContextObjectQuery: GraphQLQuery {
|
||||
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
public var name: String { __data["name"] }
|
||||
public var mimeType: String { __data["mimeType"] }
|
||||
public var blobId: String { __data["blobId"] }
|
||||
public var chunkSize: AffineGraphQL.SafeInt { __data["chunkSize"] }
|
||||
public var error: String? { __data["error"] }
|
||||
|
||||
@@ -79,11 +79,11 @@ public class ListContextQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotContext }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("id", AffineGraphQL.ID?.self),
|
||||
.field("workspaceId", String.self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
public var id: AffineGraphQL.ID? { __data["id"] }
|
||||
public var workspaceId: String { __data["workspaceId"] }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ public class ListUsersQuery: GraphQLQuery {
|
||||
public static let operationName: String = "listUsers"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query listUsers($filter: ListUserInput!) { users(filter: $filter) { __typename id name email disabled features hasPassword emailVerified avatarUrl } }"#
|
||||
#"query listUsers($filter: ListUserInput!) { users(filter: $filter) { __typename id name email disabled features hasPassword emailVerified avatarUrl } usersCount }"#
|
||||
))
|
||||
|
||||
public var filter: ListUserInput
|
||||
@@ -25,10 +25,13 @@ public class ListUsersQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("users", [User].self, arguments: ["filter": .variable("filter")]),
|
||||
.field("usersCount", Int.self),
|
||||
] }
|
||||
|
||||
/// List registered users
|
||||
public var users: [User] { __data["users"] }
|
||||
/// Get users count
|
||||
public var usersCount: Int { __data["usersCount"] }
|
||||
|
||||
/// User
|
||||
///
|
||||
|
||||
@@ -7,30 +7,38 @@ public class MatchContextQuery: GraphQLQuery {
|
||||
public static let operationName: String = "matchContext"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query matchContext($contextId: String!, $content: String!, $limit: SafeInt, $threshold: Float) { currentUser { __typename copilot { __typename contexts(contextId: $contextId) { __typename matchFiles(content: $content, limit: $limit, threshold: $threshold) { __typename fileId chunk content distance } matchWorkspaceDocs(content: $content, limit: $limit, threshold: $threshold) { __typename docId chunk content distance } } } } }"#
|
||||
#"query matchContext($contextId: String, $workspaceId: String, $content: String!, $limit: SafeInt, $scopedThreshold: Float, $threshold: Float) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename contexts(contextId: $contextId) { __typename matchFiles( content: $content limit: $limit scopedThreshold: $scopedThreshold threshold: $threshold ) { __typename fileId blobId name mimeType chunk content distance } matchWorkspaceDocs( content: $content limit: $limit scopedThreshold: $scopedThreshold threshold: $threshold ) { __typename docId chunk content distance } } } } }"#
|
||||
))
|
||||
|
||||
public var contextId: String
|
||||
public var contextId: GraphQLNullable<String>
|
||||
public var workspaceId: GraphQLNullable<String>
|
||||
public var content: String
|
||||
public var limit: GraphQLNullable<SafeInt>
|
||||
public var scopedThreshold: GraphQLNullable<Double>
|
||||
public var threshold: GraphQLNullable<Double>
|
||||
|
||||
public init(
|
||||
contextId: String,
|
||||
contextId: GraphQLNullable<String>,
|
||||
workspaceId: GraphQLNullable<String>,
|
||||
content: String,
|
||||
limit: GraphQLNullable<SafeInt>,
|
||||
scopedThreshold: GraphQLNullable<Double>,
|
||||
threshold: GraphQLNullable<Double>
|
||||
) {
|
||||
self.contextId = contextId
|
||||
self.workspaceId = workspaceId
|
||||
self.content = content
|
||||
self.limit = limit
|
||||
self.scopedThreshold = scopedThreshold
|
||||
self.threshold = threshold
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"contextId": contextId,
|
||||
"workspaceId": workspaceId,
|
||||
"content": content,
|
||||
"limit": limit,
|
||||
"scopedThreshold": scopedThreshold,
|
||||
"threshold": threshold
|
||||
] }
|
||||
|
||||
@@ -56,7 +64,7 @@ public class MatchContextQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.UserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("copilot", Copilot.self),
|
||||
.field("copilot", Copilot.self, arguments: ["workspaceId": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
public var copilot: Copilot { __data["copilot"] }
|
||||
@@ -90,11 +98,13 @@ public class MatchContextQuery: GraphQLQuery {
|
||||
.field("matchFiles", [MatchFile].self, arguments: [
|
||||
"content": .variable("content"),
|
||||
"limit": .variable("limit"),
|
||||
"scopedThreshold": .variable("scopedThreshold"),
|
||||
"threshold": .variable("threshold")
|
||||
]),
|
||||
.field("matchWorkspaceDocs", [MatchWorkspaceDoc].self, arguments: [
|
||||
"content": .variable("content"),
|
||||
"limit": .variable("limit"),
|
||||
"scopedThreshold": .variable("scopedThreshold"),
|
||||
"threshold": .variable("threshold")
|
||||
]),
|
||||
] }
|
||||
@@ -115,12 +125,18 @@ public class MatchContextQuery: GraphQLQuery {
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("fileId", String.self),
|
||||
.field("blobId", String.self),
|
||||
.field("name", String.self),
|
||||
.field("mimeType", String.self),
|
||||
.field("chunk", AffineGraphQL.SafeInt.self),
|
||||
.field("content", String.self),
|
||||
.field("distance", Double?.self),
|
||||
] }
|
||||
|
||||
public var fileId: String { __data["fileId"] }
|
||||
public var blobId: String { __data["blobId"] }
|
||||
public var name: String { __data["name"] }
|
||||
public var mimeType: String { __data["mimeType"] }
|
||||
public var chunk: AffineGraphQL.SafeInt { __data["chunk"] }
|
||||
public var content: String { __data["content"] }
|
||||
public var distance: Double? { __data["distance"] }
|
||||
|
||||
@@ -7,27 +7,39 @@ public class MatchFilesQuery: GraphQLQuery {
|
||||
public static let operationName: String = "matchFiles"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query matchFiles($contextId: String!, $content: String!, $limit: SafeInt) { currentUser { __typename copilot { __typename contexts(contextId: $contextId) { __typename matchFiles(content: $content, limit: $limit) { __typename fileId chunk content distance } } } } }"#
|
||||
#"query matchFiles($contextId: String, $workspaceId: String, $content: String!, $limit: SafeInt, $scopedThreshold: Float, $threshold: Float) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename contexts(contextId: $contextId) { __typename matchFiles( content: $content limit: $limit scopedThreshold: $scopedThreshold threshold: $threshold ) { __typename fileId blobId chunk content distance } } } } }"#
|
||||
))
|
||||
|
||||
public var contextId: String
|
||||
public var contextId: GraphQLNullable<String>
|
||||
public var workspaceId: GraphQLNullable<String>
|
||||
public var content: String
|
||||
public var limit: GraphQLNullable<SafeInt>
|
||||
public var scopedThreshold: GraphQLNullable<Double>
|
||||
public var threshold: GraphQLNullable<Double>
|
||||
|
||||
public init(
|
||||
contextId: String,
|
||||
contextId: GraphQLNullable<String>,
|
||||
workspaceId: GraphQLNullable<String>,
|
||||
content: String,
|
||||
limit: GraphQLNullable<SafeInt>
|
||||
limit: GraphQLNullable<SafeInt>,
|
||||
scopedThreshold: GraphQLNullable<Double>,
|
||||
threshold: GraphQLNullable<Double>
|
||||
) {
|
||||
self.contextId = contextId
|
||||
self.workspaceId = workspaceId
|
||||
self.content = content
|
||||
self.limit = limit
|
||||
self.scopedThreshold = scopedThreshold
|
||||
self.threshold = threshold
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"contextId": contextId,
|
||||
"workspaceId": workspaceId,
|
||||
"content": content,
|
||||
"limit": limit
|
||||
"limit": limit,
|
||||
"scopedThreshold": scopedThreshold,
|
||||
"threshold": threshold
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
@@ -52,7 +64,7 @@ public class MatchFilesQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.UserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("copilot", Copilot.self),
|
||||
.field("copilot", Copilot.self, arguments: ["workspaceId": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
public var copilot: Copilot { __data["copilot"] }
|
||||
@@ -85,7 +97,9 @@ public class MatchFilesQuery: GraphQLQuery {
|
||||
.field("__typename", String.self),
|
||||
.field("matchFiles", [MatchFile].self, arguments: [
|
||||
"content": .variable("content"),
|
||||
"limit": .variable("limit")
|
||||
"limit": .variable("limit"),
|
||||
"scopedThreshold": .variable("scopedThreshold"),
|
||||
"threshold": .variable("threshold")
|
||||
]),
|
||||
] }
|
||||
|
||||
@@ -103,12 +117,14 @@ public class MatchFilesQuery: GraphQLQuery {
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("fileId", String.self),
|
||||
.field("blobId", String.self),
|
||||
.field("chunk", AffineGraphQL.SafeInt.self),
|
||||
.field("content", String.self),
|
||||
.field("distance", Double?.self),
|
||||
] }
|
||||
|
||||
public var fileId: String { __data["fileId"] }
|
||||
public var blobId: String { __data["blobId"] }
|
||||
public var chunk: AffineGraphQL.SafeInt { __data["chunk"] }
|
||||
public var content: String { __data["content"] }
|
||||
public var distance: Double? { __data["distance"] }
|
||||
|
||||
@@ -7,27 +7,39 @@ public class MatchWorkspaceDocsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "matchWorkspaceDocs"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query matchWorkspaceDocs($contextId: String!, $content: String!, $limit: SafeInt) { currentUser { __typename copilot { __typename contexts(contextId: $contextId) { __typename matchWorkspaceDocs(content: $content, limit: $limit) { __typename docId chunk content distance } } } } }"#
|
||||
#"query matchWorkspaceDocs($contextId: String, $workspaceId: String, $content: String!, $limit: SafeInt, $scopedThreshold: Float, $threshold: Float) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename contexts(contextId: $contextId) { __typename matchWorkspaceDocs( content: $content limit: $limit scopedThreshold: $scopedThreshold threshold: $threshold ) { __typename docId chunk content distance } } } } }"#
|
||||
))
|
||||
|
||||
public var contextId: String
|
||||
public var contextId: GraphQLNullable<String>
|
||||
public var workspaceId: GraphQLNullable<String>
|
||||
public var content: String
|
||||
public var limit: GraphQLNullable<SafeInt>
|
||||
public var scopedThreshold: GraphQLNullable<Double>
|
||||
public var threshold: GraphQLNullable<Double>
|
||||
|
||||
public init(
|
||||
contextId: String,
|
||||
contextId: GraphQLNullable<String>,
|
||||
workspaceId: GraphQLNullable<String>,
|
||||
content: String,
|
||||
limit: GraphQLNullable<SafeInt>
|
||||
limit: GraphQLNullable<SafeInt>,
|
||||
scopedThreshold: GraphQLNullable<Double>,
|
||||
threshold: GraphQLNullable<Double>
|
||||
) {
|
||||
self.contextId = contextId
|
||||
self.workspaceId = workspaceId
|
||||
self.content = content
|
||||
self.limit = limit
|
||||
self.scopedThreshold = scopedThreshold
|
||||
self.threshold = threshold
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"contextId": contextId,
|
||||
"workspaceId": workspaceId,
|
||||
"content": content,
|
||||
"limit": limit
|
||||
"limit": limit,
|
||||
"scopedThreshold": scopedThreshold,
|
||||
"threshold": threshold
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
@@ -52,7 +64,7 @@ public class MatchWorkspaceDocsQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.UserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("copilot", Copilot.self),
|
||||
.field("copilot", Copilot.self, arguments: ["workspaceId": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
public var copilot: Copilot { __data["copilot"] }
|
||||
@@ -85,7 +97,9 @@ public class MatchWorkspaceDocsQuery: GraphQLQuery {
|
||||
.field("__typename", String.self),
|
||||
.field("matchWorkspaceDocs", [MatchWorkspaceDoc].self, arguments: [
|
||||
"content": .variable("content"),
|
||||
"limit": .variable("limit")
|
||||
"limit": .variable("limit"),
|
||||
"scopedThreshold": .variable("scopedThreshold"),
|
||||
"threshold": .variable("threshold")
|
||||
]),
|
||||
] }
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user