@xpert-ai/plugin-spaces 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +25 -2
  2. package/dist/access.d.ts +38 -0
  3. package/dist/access.js +96 -0
  4. package/dist/ai.d.ts +43 -0
  5. package/dist/ai.js +143 -0
  6. package/dist/artifacts.d.ts +9 -0
  7. package/dist/artifacts.js +40 -0
  8. package/dist/capability.d.ts +22 -0
  9. package/dist/capability.js +63 -0
  10. package/dist/content.d.ts +19 -0
  11. package/dist/content.js +47 -0
  12. package/dist/documents.d.ts +36 -0
  13. package/dist/documents.js +158 -0
  14. package/dist/domain.d.ts +95 -0
  15. package/dist/domain.js +23 -0
  16. package/dist/editors.d.ts +16 -0
  17. package/dist/editors.js +63 -0
  18. package/dist/entities.d.ts +68 -0
  19. package/dist/entities.js +251 -0
  20. package/dist/files.d.ts +79 -0
  21. package/dist/files.js +228 -0
  22. package/dist/imports.d.ts +83 -0
  23. package/dist/imports.js +139 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/index.js +48 -0
  26. package/dist/knowledge.d.ts +43 -0
  27. package/dist/knowledge.js +166 -0
  28. package/dist/middleware.d.ts +17 -0
  29. package/dist/middleware.js +82 -0
  30. package/dist/pages.d.ts +38 -0
  31. package/dist/pages.js +41 -0
  32. package/dist/proposal-id.d.ts +3 -0
  33. package/dist/proposal-id.js +11 -0
  34. package/dist/references.d.ts +22 -0
  35. package/dist/references.js +119 -0
  36. package/dist/remote/app.css +4 -0
  37. package/dist/remote/app.js +167 -0
  38. package/dist/resource-provider.d.ts +36 -0
  39. package/dist/resource-provider.js +144 -0
  40. package/dist/spaces.d.ts +95 -0
  41. package/dist/spaces.js +228 -0
  42. package/dist/subpages.d.ts +24 -0
  43. package/dist/subpages.js +118 -0
  44. package/dist/view.d.ts +97 -0
  45. package/dist/view.js +226 -0
  46. package/docs/.mintignore +7 -0
  47. package/docs/AGENTS.md +3 -0
  48. package/docs/LICENSE +21 -0
  49. package/docs/README.md +3 -0
  50. package/docs/architecture.mdx +49 -0
  51. package/docs/collaboration.mdx +50 -0
  52. package/docs/docs.json +39 -0
  53. package/docs/feishu-document-import.mdx +118 -0
  54. package/docs/index.mdx +12 -0
  55. package/docs/insert-menu-plan.mdx +74 -0
  56. package/docs/math-subpages.mdx +62 -0
  57. package/docs/page-resources-and-connectors.mdx +103 -0
  58. package/docs/quickstart.mdx +17 -0
  59. package/migrations/20261023-document-import-origin.sql +4 -0
  60. package/migrations/20261023-subpages.sql +6 -0
  61. package/package.json +79 -4
@@ -0,0 +1,158 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { BadRequestException, ConflictException, Inject, Injectable } from '@nestjs/common';
14
+ import { ContentDocumentsRuntimeCapability, ProjectFilesRuntimeCapability, XPERT_RUNTIME_CAPABILITIES_TOKEN } from '@xpert-ai/plugin-sdk';
15
+ import { createHash, randomUUID } from 'node:crypto';
16
+ import { SpaceAccess } from './access.js';
17
+ import { denied, scoped } from './domain.js';
18
+ export const contentHash = (buffer) => createHash('sha256').update(buffer).digest('hex');
19
+ export const safeName = (name) => name.replace(/[\\/\u0000-\u001f]/gu, '_').replace(/^\.+/u, '_').slice(0, 180) || 'Untitled';
20
+ /** Runtime memory and Space checkpoints are infrastructure, not library content. */
21
+ export const isInternalSpacePath = (filePath) => ['.xpert', '.space-history', '.space-trash'].includes(filePath.split('/')[0]);
22
+ /** Project files are the portable content; Space rows retain collaboration and presentation metadata. */
23
+ let SpaceDocuments = class SpaceDocuments {
24
+ access;
25
+ runtime;
26
+ constructor(access, runtime) {
27
+ this.access = access;
28
+ this.runtime = runtime;
29
+ }
30
+ content() { return this.runtime.require(ContentDocumentsRuntimeCapability); }
31
+ api() { return this.runtime.require(ProjectFilesRuntimeCapability); }
32
+ scope(actor, space) {
33
+ if (!space.projectId)
34
+ throw denied();
35
+ return { actor, projectId: space.projectId };
36
+ }
37
+ async path(actor, item) {
38
+ const parent = item.parentId ? await this.access.items.findOneByOrFail({ ...scoped(actor), id: item.parentId }) : null;
39
+ if (parent && (parent.kind !== 'folder' || !parent.filePath))
40
+ throw denied();
41
+ const name = safeName(item.title);
42
+ return `${parent?.filePath ? `${parent.filePath}/` : ''}${item.kind === 'page' && !name.endsWith('.md') ? `${name}.md` : name}`;
43
+ }
44
+ async initialize(actor, space, item, content) {
45
+ if (!space.projectId)
46
+ throw denied();
47
+ if (item.kind === 'page')
48
+ await this.content().validateImport({ ...this.scope(actor, space),
49
+ assistantId: actor.assistantId, modelKey: 'markdown.tiptap', markdown: content?.toString('utf8') ?? '' });
50
+ const filePath = await this.path(actor, item);
51
+ await this.access.items.update(item.id, { filePath });
52
+ let sha256 = null;
53
+ if (item.kind === 'folder')
54
+ await this.api().mkdir({ ...this.scope(actor, space), path: filePath });
55
+ else if (content)
56
+ ({ sha256 } = await this.api().write({ ...this.scope(actor, space), path: filePath, buffer: content, expectedHash: null }));
57
+ await this.access.items.update(item.id, { filePath, fileHash: sha256, syncStatus: content || item.kind === 'folder' ? 'ready' : 'pending' });
58
+ Object.assign(item, { filePath, fileHash: sha256 });
59
+ if (item.kind === 'page')
60
+ await this.registerPage(actor, space, item);
61
+ return item;
62
+ }
63
+ /** Register the file on creation/discovery; opening a page never migrates or mutates its model. */
64
+ async registerPage(actor, space, item) {
65
+ if (!item.filePath)
66
+ throw denied();
67
+ await this.content().register({ ...this.scope(actor, space), assistantId: actor.assistantId,
68
+ resourceId: item.id, path: item.filePath, title: item.title, modelKey: 'markdown.tiptap',
69
+ source: { providerKey: 'spaces', resourceId: item.id } });
70
+ await this.access.items.update(item.id, { editorKey: 'markdown.tiptap' });
71
+ item.editorKey = 'markdown.tiptap';
72
+ }
73
+ async write(actor, itemId, buffer) {
74
+ const { space, item } = await this.access.resource(actor, itemId, 'write');
75
+ if (!space.projectId || !item?.filePath)
76
+ throw denied();
77
+ if (item.editorKey === 'markdown.tiptap')
78
+ throw new ConflictException('spaces.editor_api_required');
79
+ const { sha256 } = await this.api().write({ ...this.scope(actor, space), path: item.filePath, buffer, expectedHash: item.fileHash });
80
+ await this.access.items.update(item.id, { fileHash: sha256, syncStatus: 'ready', syncError: null });
81
+ return { sha256, filePath: item.filePath, projectId: space.projectId };
82
+ }
83
+ async read(actor, space, item) {
84
+ if (!space.projectId)
85
+ throw denied();
86
+ if (!item.filePath)
87
+ return null;
88
+ return this.api().read({ ...this.scope(actor, space), path: item.filePath });
89
+ }
90
+ async editableMarkdown(actor, space, buffer) {
91
+ try {
92
+ await this.content().validateImport({ ...this.scope(actor, space), assistantId: actor.assistantId,
93
+ modelKey: 'markdown.tiptap', markdown: buffer.toString('utf8') });
94
+ return true;
95
+ }
96
+ catch (error) {
97
+ // Unsupported portable Markdown remains a downloadable file; permission/infrastructure errors propagate.
98
+ if (error instanceof BadRequestException)
99
+ return false;
100
+ throw error;
101
+ }
102
+ }
103
+ /** Discover files created by other Assistants without importing hidden version/trash storage. */
104
+ async discover(actor, space, canWrite) {
105
+ if (!space.projectId)
106
+ throw denied();
107
+ const files = await this.api().list({ ...this.scope(actor, space), depth: 12 });
108
+ const existing = await this.access.items.findBy({ ...scoped(actor), spaceId: space.id });
109
+ if (existing.some((item) => item.syncError === 'spaces.location_pending'))
110
+ return;
111
+ const byPath = new Map(existing.filter((item) => item.filePath && !item.deleted).map((item) => [item.filePath, item]));
112
+ for (const file of files.sort((a, b) => a.path.split('/').length - b.path.split('/').length)) {
113
+ if (isInternalSpacePath(file.path))
114
+ continue;
115
+ const known = byPath.get(file.path);
116
+ if (known) {
117
+ // Resume a first registration interrupted after inserting the navigation row.
118
+ // Readers can discover portable files; only editors may initialize collaborative state.
119
+ if (canWrite && !known.editorKey && (known.kind === 'page' ||
120
+ (known.kind === 'file' && file.path.endsWith('.md') && file.size <= 100000))) {
121
+ const source = await this.api().read({ ...this.scope(actor, space), path: file.path });
122
+ if (await this.editableMarkdown(actor, space, source.buffer)) {
123
+ await this.registerPage(actor, space, known);
124
+ await this.access.items.update(known.id, { kind: 'page' });
125
+ }
126
+ }
127
+ continue;
128
+ }
129
+ const parentPath = file.path.includes('/') ? file.path.slice(0, file.path.lastIndexOf('/')) : '';
130
+ const parentId = parentPath ? byPath.get(parentPath)?.id : null;
131
+ if (parentPath && !parentId)
132
+ continue;
133
+ const name = file.path.split('/').pop();
134
+ let kind = file.kind === 'directory' ? 'folder' : canWrite && name.endsWith('.md') && file.size <= 100000 ? 'page' : 'file';
135
+ const content = kind === 'page' ? await this.api().read({ ...this.scope(actor, space), path: file.path }) : null;
136
+ if (content && !(await this.editableMarkdown(actor, space, content.buffer)))
137
+ kind = 'file';
138
+ {
139
+ await this.access.items.createQueryBuilder().insert().values({
140
+ ...scoped(actor), spaceId: space.id, id: randomUUID(), parentId: parentId ?? null,
141
+ createdById: actor.userId, title: kind === 'page' ? name.slice(0, -3) : name, kind,
142
+ filePath: file.path, fileHash: content?.sha256 ?? null,
143
+ markdown: content?.buffer.toString('utf8') ?? '', syncStatus: 'ready'
144
+ }).orIgnore().execute();
145
+ const item = await this.access.items.findOneByOrFail({ ...scoped(actor), spaceId: space.id, filePath: file.path, deleted: false });
146
+ if (kind === 'page')
147
+ await this.registerPage(actor, space, item);
148
+ byPath.set(file.path, item);
149
+ }
150
+ }
151
+ }
152
+ };
153
+ SpaceDocuments = __decorate([
154
+ Injectable(),
155
+ __param(1, Inject(XPERT_RUNTIME_CAPABILITIES_TOKEN)),
156
+ __metadata("design:paramtypes", [SpaceAccess, Object])
157
+ ], SpaceDocuments);
158
+ export { SpaceDocuments };
@@ -0,0 +1,95 @@
1
+ import { z } from 'zod/v3';
2
+ import { ForbiddenException } from '@nestjs/common';
3
+ import type { ContentActor, ContentOperation } from '@xpert-ai/plugin-sdk';
4
+ export declare const PLUGIN = "@xpert-ai/plugin-spaces";
5
+ export declare const PROVIDER = "spaces";
6
+ export declare const VIEW = "spaces.workspace";
7
+ export declare const id: z.ZodString;
8
+ export declare const title: z.ZodString;
9
+ export declare const actorSchema: z.ZodObject<{
10
+ tenantId: z.ZodString;
11
+ organizationId: z.ZodString;
12
+ userId: z.ZodString;
13
+ assistantId: z.ZodOptional<z.ZodString>;
14
+ projectId: z.ZodOptional<z.ZodString>;
15
+ }, "strip", z.ZodTypeAny, {
16
+ tenantId: string;
17
+ organizationId: string;
18
+ userId: string;
19
+ assistantId?: string | undefined;
20
+ projectId?: string | undefined;
21
+ }, {
22
+ tenantId: string;
23
+ organizationId: string;
24
+ userId: string;
25
+ assistantId?: string | undefined;
26
+ projectId?: string | undefined;
27
+ }>;
28
+ export type SpaceActor = ContentActor & {
29
+ assistantId?: string;
30
+ projectId?: string;
31
+ };
32
+ export declare const roleSchema: z.ZodEnum<["viewer", "commenter", "editor", "manager", "owner"]>;
33
+ export type Role = z.infer<typeof roleSchema>;
34
+ export declare const rank: Record<Role, number>;
35
+ export declare const required: Record<ContentOperation, number>;
36
+ export declare const kindSchema: z.ZodEnum<["folder", "page", "file", "artifact"]>;
37
+ export type ItemKind = z.infer<typeof kindSchema>;
38
+ export declare const blockSchema: z.ZodObject<{
39
+ id: z.ZodString;
40
+ kind: z.ZodEnum<["paragraph", "heading", "code", "bullet"]>;
41
+ text: z.ZodString;
42
+ }, "strict", z.ZodTypeAny, {
43
+ id: string;
44
+ kind: "code" | "paragraph" | "heading" | "bullet";
45
+ text: string;
46
+ }, {
47
+ id: string;
48
+ kind: "code" | "paragraph" | "heading" | "bullet";
49
+ text: string;
50
+ }>;
51
+ export declare const blocksSchema: z.ZodArray<z.ZodObject<{
52
+ id: z.ZodString;
53
+ kind: z.ZodEnum<["paragraph", "heading", "code", "bullet"]>;
54
+ text: z.ZodString;
55
+ }, "strict", z.ZodTypeAny, {
56
+ id: string;
57
+ kind: "code" | "paragraph" | "heading" | "bullet";
58
+ text: string;
59
+ }, {
60
+ id: string;
61
+ kind: "code" | "paragraph" | "heading" | "bullet";
62
+ text: string;
63
+ }>, "many">;
64
+ export type Block = z.infer<typeof blockSchema>;
65
+ export declare const patchSchema: z.ZodObject<{
66
+ itemId: z.ZodString;
67
+ mutationId: z.ZodString;
68
+ expectedSequence: z.ZodNumber;
69
+ blockId: z.ZodString;
70
+ before: z.ZodString;
71
+ after: z.ZodString;
72
+ reason: z.ZodDefault<z.ZodString>;
73
+ }, "strict", z.ZodTypeAny, {
74
+ itemId: string;
75
+ mutationId: string;
76
+ expectedSequence: number;
77
+ blockId: string;
78
+ before: string;
79
+ after: string;
80
+ reason: string;
81
+ }, {
82
+ itemId: string;
83
+ mutationId: string;
84
+ expectedSequence: number;
85
+ blockId: string;
86
+ before: string;
87
+ after: string;
88
+ reason?: string | undefined;
89
+ }>;
90
+ export type PagePatch = z.infer<typeof patchSchema>;
91
+ export declare const scoped: (actor: ContentActor) => {
92
+ tenantId: string;
93
+ organizationId: string;
94
+ };
95
+ export declare const denied: () => ForbiddenException;
package/dist/domain.js ADDED
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod/v3';
2
+ import { ForbiddenException } from '@nestjs/common';
3
+ export const PLUGIN = '@xpert-ai/plugin-spaces';
4
+ export const PROVIDER = 'spaces';
5
+ export const VIEW = 'spaces.workspace';
6
+ export const id = z.string().uuid();
7
+ export const title = z.string().trim().min(1).max(200);
8
+ export const actorSchema = z.object({ tenantId: id, organizationId: id, userId: id, assistantId: id.optional(), projectId: id.optional() });
9
+ export const roleSchema = z.enum(['viewer', 'commenter', 'editor', 'manager', 'owner']);
10
+ export const rank = { viewer: 1, commenter: 2, editor: 3, manager: 4, owner: 5 };
11
+ export const required = { read: 1, comment: 2, write: 3, manage: 4 };
12
+ export const kindSchema = z.enum(['folder', 'page', 'file', 'artifact']);
13
+ export const blockSchema = z.object({
14
+ id, kind: z.enum(['paragraph', 'heading', 'code', 'bullet']), text: z.string().max(100000)
15
+ }).strict();
16
+ export const blocksSchema = z.array(blockSchema).min(1).max(1000);
17
+ export const patchSchema = z.object({
18
+ itemId: id, mutationId: id, expectedSequence: z.number().int().nonnegative(),
19
+ blockId: id, before: z.string().max(100000), after: z.string().max(100000),
20
+ reason: z.string().max(2000).default('')
21
+ }).strict();
22
+ export const scoped = (actor) => ({ tenantId: actor.tenantId, organizationId: actor.organizationId });
23
+ export const denied = () => new ForbiddenException('spaces.access_denied');
@@ -0,0 +1,16 @@
1
+ import { type RuntimeCapabilityRegistry } from '@xpert-ai/plugin-sdk';
2
+ import { SpaceAccess } from './access.js';
3
+ import { SpaceFiles } from './files.js';
4
+ import { SpacesService } from './spaces.js';
5
+ import { type SpaceActor } from './domain.js';
6
+ /** Spaces creates navigation/resources; concrete models and editing belong to editor plugins. */
7
+ export declare class SpaceEditors {
8
+ private readonly access;
9
+ private readonly files;
10
+ private readonly spaces;
11
+ private readonly runtime;
12
+ constructor(access: SpaceAccess, files: SpaceFiles, spaces: SpacesService, runtime: RuntimeCapabilityRegistry);
13
+ private scope;
14
+ list(actor: SpaceActor): Promise<import("@xpert-ai/contracts").FileContentEditorRegistration[]>;
15
+ create(actor: SpaceActor, spaceId: string, parentId: string | null, title: string, editorKey: string, buffer?: Buffer): Promise<import("./entities.js").SpaceItem>;
16
+ }
@@ -0,0 +1,63 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Inject, Injectable } from '@nestjs/common';
14
+ import { ContentEditorsRuntimeCapability, XPERT_RUNTIME_CAPABILITIES_TOKEN } from '@xpert-ai/plugin-sdk';
15
+ import { SpaceAccess } from './access.js';
16
+ import { SpaceFiles } from './files.js';
17
+ import { SpacesService } from './spaces.js';
18
+ import { denied, scoped } from './domain.js';
19
+ /** Spaces creates navigation/resources; concrete models and editing belong to editor plugins. */
20
+ let SpaceEditors = class SpaceEditors {
21
+ access;
22
+ files;
23
+ spaces;
24
+ runtime;
25
+ constructor(access, files, spaces, runtime) {
26
+ this.access = access;
27
+ this.files = files;
28
+ this.spaces = spaces;
29
+ this.runtime = runtime;
30
+ }
31
+ scope(actor) {
32
+ if (!actor.projectId)
33
+ throw denied();
34
+ return { actor, projectId: actor.projectId, assistantId: actor.assistantId };
35
+ }
36
+ async list(actor) {
37
+ await this.access.project(actor);
38
+ return (await this.runtime.require(ContentEditorsRuntimeCapability).list(this.scope(actor))).filter(editor => editor.kind === 'file');
39
+ }
40
+ async create(actor, spaceId, parentId, title, editorKey, buffer) {
41
+ const access = await this.access.resource(actor, parentId ?? spaceId, 'write');
42
+ if (access.space.id !== spaceId)
43
+ throw denied();
44
+ const { registration, buffer: bytes } = await this.runtime.require(ContentEditorsRuntimeCapability).prepare({ ...this.scope(actor), editorKey, buffer });
45
+ const fileName = title.toLowerCase().endsWith(`.${registration.extension}`) ? title : `${title}.${registration.extension}`;
46
+ const item = await this.spaces.createItem(actor, { spaceId, parentId, title: fileName, kind: 'file' });
47
+ try {
48
+ await this.access.items.update({ ...scoped(actor), id: item.id }, { editorKey });
49
+ await this.files.put(actor, item.id, bytes, fileName, registration.mimeType);
50
+ return await this.access.items.findOneByOrFail({ ...scoped(actor), id: item.id });
51
+ }
52
+ catch (error) {
53
+ await this.access.items.update({ ...scoped(actor), id: item.id }, { deleted: true });
54
+ throw error;
55
+ }
56
+ }
57
+ };
58
+ SpaceEditors = __decorate([
59
+ Injectable(),
60
+ __param(3, Inject(XPERT_RUNTIME_CAPABILITIES_TOKEN)),
61
+ __metadata("design:paramtypes", [SpaceAccess, SpaceFiles, SpacesService, Object])
62
+ ], SpaceEditors);
63
+ export { SpaceEditors };
@@ -0,0 +1,68 @@
1
+ import type { WorkspacePortableFileReference } from '@xpert-ai/plugin-sdk';
2
+ import type { ItemKind } from './domain.js';
3
+ export declare abstract class ScopedEntity {
4
+ id: string;
5
+ tenantId: string;
6
+ organizationId: string;
7
+ createdAt: Date;
8
+ updatedAt: Date;
9
+ }
10
+ export declare class Space extends ScopedEntity {
11
+ /** Storage and membership belong to this Project; Space only adds content metadata. */
12
+ projectId: string;
13
+ knowledgebaseId: string | null;
14
+ title: string;
15
+ ownerId: string;
16
+ visibility: 'personal' | 'team';
17
+ version: number;
18
+ deleted: boolean;
19
+ }
20
+ export declare class SpaceItem extends ScopedEntity {
21
+ /** Immutable import receipt; content stays in the project file. A copy does not inherit remote ACLs. */
22
+ importOrigin: {
23
+ provider: string;
24
+ documentId: string;
25
+ url: string | null;
26
+ revision: string;
27
+ contentHash: string;
28
+ format: 'text/plain';
29
+ importedAt: string;
30
+ warnings: string[];
31
+ bindingId: string;
32
+ requestHash: string;
33
+ } | null;
34
+ /** Logical page parent; parentId continues to mean the physical file folder. */
35
+ parentPageId: string | null;
36
+ /** Original request title makes a retried create idempotent even after a later rename. */
37
+ childRequestTitle: string | null;
38
+ filePath: string | null;
39
+ fileHash: string | null;
40
+ syncStatus: 'pending' | 'ready' | 'conflict' | 'failed';
41
+ syncError: string | null;
42
+ knowledgeDocumentId: string | null;
43
+ indexedHash: string | null;
44
+ indexStatus: 'pending' | 'processing' | 'ready' | 'failed';
45
+ indexError: string | null;
46
+ spaceId: string;
47
+ parentId: string | null;
48
+ createdById: string;
49
+ title: string;
50
+ kind: ItemKind;
51
+ version: number;
52
+ deleted: boolean;
53
+ projectedSequence: number;
54
+ markdown: string;
55
+ editorKey: string | null;
56
+ currentFileVersionId: string | null;
57
+ file: WorkspacePortableFileReference | null;
58
+ artifactId: string | null;
59
+ artifactVersionId: string | null;
60
+ }
61
+ export declare class SpaceFileVersion extends ScopedEntity {
62
+ itemId: string;
63
+ createdById: string;
64
+ reference: WorkspacePortableFileReference;
65
+ revisionId: string | null;
66
+ sha256: string;
67
+ }
68
+ export declare const entities: (typeof Space | typeof SpaceItem | typeof SpaceFileVersion)[];
@@ -0,0 +1,251 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm';
11
+ export class ScopedEntity {
12
+ id;
13
+ tenantId;
14
+ organizationId;
15
+ createdAt;
16
+ updatedAt;
17
+ }
18
+ __decorate([
19
+ PrimaryGeneratedColumn('uuid'),
20
+ __metadata("design:type", String)
21
+ ], ScopedEntity.prototype, "id", void 0);
22
+ __decorate([
23
+ Column({ type: 'uuid' }),
24
+ __metadata("design:type", String)
25
+ ], ScopedEntity.prototype, "tenantId", void 0);
26
+ __decorate([
27
+ Column({ type: 'uuid' }),
28
+ __metadata("design:type", String)
29
+ ], ScopedEntity.prototype, "organizationId", void 0);
30
+ __decorate([
31
+ CreateDateColumn(),
32
+ __metadata("design:type", Date)
33
+ ], ScopedEntity.prototype, "createdAt", void 0);
34
+ __decorate([
35
+ UpdateDateColumn(),
36
+ __metadata("design:type", Date)
37
+ ], ScopedEntity.prototype, "updatedAt", void 0);
38
+ let Space = class Space extends ScopedEntity {
39
+ /** Storage and membership belong to this Project; Space only adds content metadata. */
40
+ projectId;
41
+ knowledgebaseId;
42
+ title;
43
+ ownerId;
44
+ visibility;
45
+ version;
46
+ deleted;
47
+ };
48
+ __decorate([
49
+ Column({ type: 'uuid' }),
50
+ __metadata("design:type", String)
51
+ ], Space.prototype, "projectId", void 0);
52
+ __decorate([
53
+ Column({ type: 'uuid', nullable: true }),
54
+ __metadata("design:type", Object)
55
+ ], Space.prototype, "knowledgebaseId", void 0);
56
+ __decorate([
57
+ Column({ type: 'varchar', length: 200 }),
58
+ __metadata("design:type", String)
59
+ ], Space.prototype, "title", void 0);
60
+ __decorate([
61
+ Column({ type: 'uuid' }),
62
+ __metadata("design:type", String)
63
+ ], Space.prototype, "ownerId", void 0);
64
+ __decorate([
65
+ Column({ type: 'varchar', length: 20 }),
66
+ __metadata("design:type", String)
67
+ ], Space.prototype, "visibility", void 0);
68
+ __decorate([
69
+ Column({ type: 'int', default: 1 }),
70
+ __metadata("design:type", Number)
71
+ ], Space.prototype, "version", void 0);
72
+ __decorate([
73
+ Column({ type: 'boolean', default: false }),
74
+ __metadata("design:type", Boolean)
75
+ ], Space.prototype, "deleted", void 0);
76
+ Space = __decorate([
77
+ Entity('plugin_spaces_space'),
78
+ Index(['tenantId', 'organizationId']),
79
+ Index('IDX_space_project', ['tenantId', 'organizationId', 'projectId'], { unique: true })
80
+ ], Space);
81
+ export { Space };
82
+ let SpaceItem = class SpaceItem extends ScopedEntity {
83
+ /** Immutable import receipt; content stays in the project file. A copy does not inherit remote ACLs. */
84
+ importOrigin;
85
+ /** Logical page parent; parentId continues to mean the physical file folder. */
86
+ parentPageId;
87
+ /** Original request title makes a retried create idempotent even after a later rename. */
88
+ childRequestTitle;
89
+ filePath;
90
+ fileHash;
91
+ syncStatus;
92
+ syncError;
93
+ knowledgeDocumentId;
94
+ indexedHash;
95
+ indexStatus;
96
+ indexError;
97
+ spaceId;
98
+ parentId;
99
+ createdById;
100
+ title;
101
+ kind;
102
+ version;
103
+ deleted;
104
+ projectedSequence;
105
+ markdown;
106
+ editorKey;
107
+ currentFileVersionId;
108
+ file;
109
+ artifactId;
110
+ artifactVersionId;
111
+ };
112
+ __decorate([
113
+ Column({ type: 'jsonb', nullable: true }),
114
+ __metadata("design:type", Object)
115
+ ], SpaceItem.prototype, "importOrigin", void 0);
116
+ __decorate([
117
+ Column({ type: 'uuid', nullable: true }),
118
+ __metadata("design:type", Object)
119
+ ], SpaceItem.prototype, "parentPageId", void 0);
120
+ __decorate([
121
+ Column({ type: 'varchar', length: 200, nullable: true }),
122
+ __metadata("design:type", Object)
123
+ ], SpaceItem.prototype, "childRequestTitle", void 0);
124
+ __decorate([
125
+ Column({ type: 'text', nullable: true }),
126
+ __metadata("design:type", Object)
127
+ ], SpaceItem.prototype, "filePath", void 0);
128
+ __decorate([
129
+ Column({ type: 'varchar', length: 64, nullable: true }),
130
+ __metadata("design:type", Object)
131
+ ], SpaceItem.prototype, "fileHash", void 0);
132
+ __decorate([
133
+ Column({ type: 'varchar', length: 24, default: 'pending' }),
134
+ __metadata("design:type", String)
135
+ ], SpaceItem.prototype, "syncStatus", void 0);
136
+ __decorate([
137
+ Column({ type: 'text', nullable: true }),
138
+ __metadata("design:type", Object)
139
+ ], SpaceItem.prototype, "syncError", void 0);
140
+ __decorate([
141
+ Column({ type: 'uuid', nullable: true }),
142
+ __metadata("design:type", Object)
143
+ ], SpaceItem.prototype, "knowledgeDocumentId", void 0);
144
+ __decorate([
145
+ Column({ type: 'varchar', length: 64, nullable: true }),
146
+ __metadata("design:type", Object)
147
+ ], SpaceItem.prototype, "indexedHash", void 0);
148
+ __decorate([
149
+ Column({ type: 'varchar', length: 24, default: 'pending' }),
150
+ __metadata("design:type", String)
151
+ ], SpaceItem.prototype, "indexStatus", void 0);
152
+ __decorate([
153
+ Column({ type: 'text', nullable: true }),
154
+ __metadata("design:type", Object)
155
+ ], SpaceItem.prototype, "indexError", void 0);
156
+ __decorate([
157
+ Column({ type: 'uuid' }),
158
+ __metadata("design:type", String)
159
+ ], SpaceItem.prototype, "spaceId", void 0);
160
+ __decorate([
161
+ Column({ type: 'uuid', nullable: true }),
162
+ __metadata("design:type", Object)
163
+ ], SpaceItem.prototype, "parentId", void 0);
164
+ __decorate([
165
+ Column({ type: 'uuid' }),
166
+ __metadata("design:type", String)
167
+ ], SpaceItem.prototype, "createdById", void 0);
168
+ __decorate([
169
+ Column({ type: 'varchar', length: 200 }),
170
+ __metadata("design:type", String)
171
+ ], SpaceItem.prototype, "title", void 0);
172
+ __decorate([
173
+ Column({ type: 'varchar', length: 20 }),
174
+ __metadata("design:type", String)
175
+ ], SpaceItem.prototype, "kind", void 0);
176
+ __decorate([
177
+ Column({ type: 'int', default: 1 }),
178
+ __metadata("design:type", Number)
179
+ ], SpaceItem.prototype, "version", void 0);
180
+ __decorate([
181
+ Column({ type: 'boolean', default: false }),
182
+ __metadata("design:type", Boolean)
183
+ ], SpaceItem.prototype, "deleted", void 0);
184
+ __decorate([
185
+ Column({ type: 'int', default: -1 }),
186
+ __metadata("design:type", Number)
187
+ ], SpaceItem.prototype, "projectedSequence", void 0);
188
+ __decorate([
189
+ Column({ type: 'text', default: '' }),
190
+ __metadata("design:type", String)
191
+ ], SpaceItem.prototype, "markdown", void 0);
192
+ __decorate([
193
+ Column({ type: 'varchar', length: 100, nullable: true }),
194
+ __metadata("design:type", Object)
195
+ ], SpaceItem.prototype, "editorKey", void 0);
196
+ __decorate([
197
+ Column({ type: 'uuid', nullable: true }),
198
+ __metadata("design:type", Object)
199
+ ], SpaceItem.prototype, "currentFileVersionId", void 0);
200
+ __decorate([
201
+ Column({ type: 'jsonb', nullable: true }),
202
+ __metadata("design:type", Object)
203
+ ], SpaceItem.prototype, "file", void 0);
204
+ __decorate([
205
+ Column({ type: 'uuid', nullable: true }),
206
+ __metadata("design:type", Object)
207
+ ], SpaceItem.prototype, "artifactId", void 0);
208
+ __decorate([
209
+ Column({ type: 'uuid', nullable: true }),
210
+ __metadata("design:type", Object)
211
+ ], SpaceItem.prototype, "artifactVersionId", void 0);
212
+ SpaceItem = __decorate([
213
+ Entity('plugin_spaces_item'),
214
+ Index(['tenantId', 'organizationId', 'spaceId']),
215
+ Index('IDX_space_page_parent', ['tenantId', 'organizationId', 'spaceId', 'parentPageId']),
216
+ Index('IDX_space_item_active_path', ['spaceId', 'filePath'], { unique: true, where: '"deleted" = false AND "filePath" IS NOT NULL' })
217
+ ], SpaceItem);
218
+ export { SpaceItem };
219
+ let SpaceFileVersion = class SpaceFileVersion extends ScopedEntity {
220
+ itemId;
221
+ createdById;
222
+ reference;
223
+ revisionId;
224
+ sha256;
225
+ };
226
+ __decorate([
227
+ Column({ type: 'uuid' }),
228
+ __metadata("design:type", String)
229
+ ], SpaceFileVersion.prototype, "itemId", void 0);
230
+ __decorate([
231
+ Column({ type: 'uuid' }),
232
+ __metadata("design:type", String)
233
+ ], SpaceFileVersion.prototype, "createdById", void 0);
234
+ __decorate([
235
+ Column({ type: 'jsonb' }),
236
+ __metadata("design:type", Object)
237
+ ], SpaceFileVersion.prototype, "reference", void 0);
238
+ __decorate([
239
+ Column({ type: 'uuid', nullable: true }),
240
+ __metadata("design:type", Object)
241
+ ], SpaceFileVersion.prototype, "revisionId", void 0);
242
+ __decorate([
243
+ Column({ type: 'varchar', length: 64 }),
244
+ __metadata("design:type", String)
245
+ ], SpaceFileVersion.prototype, "sha256", void 0);
246
+ SpaceFileVersion = __decorate([
247
+ Entity('plugin_spaces_file_version'),
248
+ Index(['tenantId', 'organizationId', 'itemId'])
249
+ ], SpaceFileVersion);
250
+ export { SpaceFileVersion };
251
+ export const entities = [Space, SpaceItem, SpaceFileVersion];