@orion-studios/payload-studio-core 0.1.0-beta.1

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.
@@ -0,0 +1,104 @@
1
+ type StudioNodeData = Record<string, unknown>;
2
+ type StudioNode = {
3
+ id: string;
4
+ type: string;
5
+ data: StudioNodeData;
6
+ };
7
+ type StudioDocumentV1 = {
8
+ schemaVersion: 1;
9
+ title?: string;
10
+ nodes: StudioNode[];
11
+ updatedAt?: string;
12
+ };
13
+ type StudioValidationIssue = {
14
+ code: string;
15
+ message: string;
16
+ path: string;
17
+ severity: 'error' | 'warning';
18
+ };
19
+ type StudioCompileResult = {
20
+ issues: StudioValidationIssue[];
21
+ layout: Record<string, unknown>[];
22
+ };
23
+ type StudioMigration = {
24
+ fromVersion: number;
25
+ migrate: (value: unknown) => StudioDocumentV1;
26
+ toVersion: number;
27
+ };
28
+ type StudioPermission = {
29
+ action: 'create' | 'publish' | 'read' | 'update';
30
+ role: 'admin' | 'client' | 'editor';
31
+ };
32
+ type StudioPaletteItem = {
33
+ description?: string;
34
+ nodeType: string;
35
+ title: string;
36
+ };
37
+ type StudioPaletteGroup = {
38
+ id: string;
39
+ items: StudioPaletteItem[];
40
+ label: string;
41
+ };
42
+ type StudioInspectorField = {
43
+ key: string;
44
+ label: string;
45
+ type: 'array' | 'checkbox' | 'number' | 'select' | 'text' | 'textarea';
46
+ };
47
+ type StudioInspectorPanel = {
48
+ fields: StudioInspectorField[];
49
+ id: string;
50
+ label: string;
51
+ nodeType: string;
52
+ };
53
+ type StudioNodeTypeDefinition = {
54
+ description?: string;
55
+ displayName: string;
56
+ getDefaultData: () => StudioNodeData;
57
+ type: string;
58
+ };
59
+ type StudioModuleManifest = {
60
+ compiler?: {
61
+ compileNode?: (node: StudioNode) => Record<string, unknown> | null;
62
+ };
63
+ displayName: string;
64
+ id: string;
65
+ inspectorPanels: StudioInspectorPanel[];
66
+ migrations: StudioMigration[];
67
+ nodeTypes: StudioNodeTypeDefinition[];
68
+ paletteGroups: StudioPaletteGroup[];
69
+ permissions?: StudioPermission[];
70
+ validators: Array<(value: StudioDocumentV1) => StudioValidationIssue[]>;
71
+ version: string;
72
+ };
73
+ type StudioRegistry = {
74
+ getModuleByID: (id: string) => StudioModuleManifest | undefined;
75
+ getNodeTypeByName: (type: string) => StudioNodeTypeDefinition | undefined;
76
+ listInspectorPanels: () => StudioInspectorPanel[];
77
+ listModules: () => StudioModuleManifest[];
78
+ listPaletteGroups: () => StudioPaletteGroup[];
79
+ listNodeTypes: () => StudioNodeTypeDefinition[];
80
+ };
81
+ type StudioPageService = {
82
+ getPageForStudio: (pageID: string) => Promise<{
83
+ id: string;
84
+ studioDocument: StudioDocumentV1;
85
+ title: string;
86
+ }>;
87
+ publish: (pageID: string, document: StudioDocumentV1, metadata?: Record<string, unknown>) => Promise<{
88
+ id: string;
89
+ status: 'published';
90
+ }>;
91
+ saveDraft: (pageID: string, document: StudioDocumentV1, metadata?: Record<string, unknown>) => Promise<{
92
+ id: string;
93
+ status: 'draft';
94
+ }>;
95
+ validateStudioDocument: (document: StudioDocumentV1) => StudioValidationIssue[];
96
+ };
97
+ declare const createEmptyStudioDocument: (title?: string) => StudioDocumentV1;
98
+ declare function assertStudioDocumentV1(input: unknown): StudioDocumentV1;
99
+ declare function createStudioRegistry(modules: StudioModuleManifest[]): StudioRegistry;
100
+ declare function validateStudioDocument(document: StudioDocumentV1, modules: StudioModuleManifest[]): StudioValidationIssue[];
101
+ declare function compileStudioDocument(document: StudioDocumentV1, modules: StudioModuleManifest[]): StudioCompileResult;
102
+ declare function migrateStudioDocument(value: unknown, migrations: StudioMigration[]): StudioDocumentV1;
103
+
104
+ export { type StudioCompileResult, type StudioDocumentV1, type StudioInspectorField, type StudioInspectorPanel, type StudioMigration, type StudioModuleManifest, type StudioNode, type StudioNodeData, type StudioNodeTypeDefinition, type StudioPageService, type StudioPaletteGroup, type StudioPaletteItem, type StudioPermission, type StudioRegistry, type StudioValidationIssue, assertStudioDocumentV1, compileStudioDocument, createEmptyStudioDocument, createStudioRegistry, migrateStudioDocument, validateStudioDocument };
@@ -0,0 +1,104 @@
1
+ type StudioNodeData = Record<string, unknown>;
2
+ type StudioNode = {
3
+ id: string;
4
+ type: string;
5
+ data: StudioNodeData;
6
+ };
7
+ type StudioDocumentV1 = {
8
+ schemaVersion: 1;
9
+ title?: string;
10
+ nodes: StudioNode[];
11
+ updatedAt?: string;
12
+ };
13
+ type StudioValidationIssue = {
14
+ code: string;
15
+ message: string;
16
+ path: string;
17
+ severity: 'error' | 'warning';
18
+ };
19
+ type StudioCompileResult = {
20
+ issues: StudioValidationIssue[];
21
+ layout: Record<string, unknown>[];
22
+ };
23
+ type StudioMigration = {
24
+ fromVersion: number;
25
+ migrate: (value: unknown) => StudioDocumentV1;
26
+ toVersion: number;
27
+ };
28
+ type StudioPermission = {
29
+ action: 'create' | 'publish' | 'read' | 'update';
30
+ role: 'admin' | 'client' | 'editor';
31
+ };
32
+ type StudioPaletteItem = {
33
+ description?: string;
34
+ nodeType: string;
35
+ title: string;
36
+ };
37
+ type StudioPaletteGroup = {
38
+ id: string;
39
+ items: StudioPaletteItem[];
40
+ label: string;
41
+ };
42
+ type StudioInspectorField = {
43
+ key: string;
44
+ label: string;
45
+ type: 'array' | 'checkbox' | 'number' | 'select' | 'text' | 'textarea';
46
+ };
47
+ type StudioInspectorPanel = {
48
+ fields: StudioInspectorField[];
49
+ id: string;
50
+ label: string;
51
+ nodeType: string;
52
+ };
53
+ type StudioNodeTypeDefinition = {
54
+ description?: string;
55
+ displayName: string;
56
+ getDefaultData: () => StudioNodeData;
57
+ type: string;
58
+ };
59
+ type StudioModuleManifest = {
60
+ compiler?: {
61
+ compileNode?: (node: StudioNode) => Record<string, unknown> | null;
62
+ };
63
+ displayName: string;
64
+ id: string;
65
+ inspectorPanels: StudioInspectorPanel[];
66
+ migrations: StudioMigration[];
67
+ nodeTypes: StudioNodeTypeDefinition[];
68
+ paletteGroups: StudioPaletteGroup[];
69
+ permissions?: StudioPermission[];
70
+ validators: Array<(value: StudioDocumentV1) => StudioValidationIssue[]>;
71
+ version: string;
72
+ };
73
+ type StudioRegistry = {
74
+ getModuleByID: (id: string) => StudioModuleManifest | undefined;
75
+ getNodeTypeByName: (type: string) => StudioNodeTypeDefinition | undefined;
76
+ listInspectorPanels: () => StudioInspectorPanel[];
77
+ listModules: () => StudioModuleManifest[];
78
+ listPaletteGroups: () => StudioPaletteGroup[];
79
+ listNodeTypes: () => StudioNodeTypeDefinition[];
80
+ };
81
+ type StudioPageService = {
82
+ getPageForStudio: (pageID: string) => Promise<{
83
+ id: string;
84
+ studioDocument: StudioDocumentV1;
85
+ title: string;
86
+ }>;
87
+ publish: (pageID: string, document: StudioDocumentV1, metadata?: Record<string, unknown>) => Promise<{
88
+ id: string;
89
+ status: 'published';
90
+ }>;
91
+ saveDraft: (pageID: string, document: StudioDocumentV1, metadata?: Record<string, unknown>) => Promise<{
92
+ id: string;
93
+ status: 'draft';
94
+ }>;
95
+ validateStudioDocument: (document: StudioDocumentV1) => StudioValidationIssue[];
96
+ };
97
+ declare const createEmptyStudioDocument: (title?: string) => StudioDocumentV1;
98
+ declare function assertStudioDocumentV1(input: unknown): StudioDocumentV1;
99
+ declare function createStudioRegistry(modules: StudioModuleManifest[]): StudioRegistry;
100
+ declare function validateStudioDocument(document: StudioDocumentV1, modules: StudioModuleManifest[]): StudioValidationIssue[];
101
+ declare function compileStudioDocument(document: StudioDocumentV1, modules: StudioModuleManifest[]): StudioCompileResult;
102
+ declare function migrateStudioDocument(value: unknown, migrations: StudioMigration[]): StudioDocumentV1;
103
+
104
+ export { type StudioCompileResult, type StudioDocumentV1, type StudioInspectorField, type StudioInspectorPanel, type StudioMigration, type StudioModuleManifest, type StudioNode, type StudioNodeData, type StudioNodeTypeDefinition, type StudioPageService, type StudioPaletteGroup, type StudioPaletteItem, type StudioPermission, type StudioRegistry, type StudioValidationIssue, assertStudioDocumentV1, compileStudioDocument, createEmptyStudioDocument, createStudioRegistry, migrateStudioDocument, validateStudioDocument };
package/dist/index.js ADDED
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ assertStudioDocumentV1: () => assertStudioDocumentV1,
24
+ compileStudioDocument: () => compileStudioDocument,
25
+ createEmptyStudioDocument: () => createEmptyStudioDocument,
26
+ createStudioRegistry: () => createStudioRegistry,
27
+ migrateStudioDocument: () => migrateStudioDocument,
28
+ validateStudioDocument: () => validateStudioDocument
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+ var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
32
+ var makeIssue = (message, path, code = "studio.invalid") => ({
33
+ code,
34
+ message,
35
+ path,
36
+ severity: "error"
37
+ });
38
+ var createEmptyStudioDocument = (title) => ({
39
+ schemaVersion: 1,
40
+ title,
41
+ nodes: [],
42
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
43
+ });
44
+ function assertStudioDocumentV1(input) {
45
+ if (!isRecord(input)) {
46
+ throw new Error("Studio document must be an object");
47
+ }
48
+ if (input.schemaVersion !== 1) {
49
+ throw new Error("Unsupported studio schemaVersion");
50
+ }
51
+ if (!Array.isArray(input.nodes)) {
52
+ throw new Error("Studio document nodes must be an array");
53
+ }
54
+ const nodes = input.nodes.map((node, index) => {
55
+ if (!isRecord(node)) {
56
+ throw new Error(`Node at index ${index} must be an object`);
57
+ }
58
+ if (typeof node.id !== "string" || node.id.length === 0) {
59
+ throw new Error(`Node at index ${index} has invalid id`);
60
+ }
61
+ if (typeof node.type !== "string" || node.type.length === 0) {
62
+ throw new Error(`Node at index ${index} has invalid type`);
63
+ }
64
+ if (!isRecord(node.data)) {
65
+ throw new Error(`Node at index ${index} has invalid data`);
66
+ }
67
+ return {
68
+ id: node.id,
69
+ type: node.type,
70
+ data: node.data
71
+ };
72
+ });
73
+ return {
74
+ schemaVersion: 1,
75
+ title: typeof input.title === "string" ? input.title : void 0,
76
+ nodes,
77
+ updatedAt: typeof input.updatedAt === "string" ? input.updatedAt : void 0
78
+ };
79
+ }
80
+ function createStudioRegistry(modules) {
81
+ const moduleByID = new Map(modules.map((mod) => [mod.id, mod]));
82
+ const nodeTypes = modules.flatMap((mod) => mod.nodeTypes);
83
+ const nodeTypeByName = new Map(nodeTypes.map((definition) => [definition.type, definition]));
84
+ return {
85
+ getModuleByID: (id) => moduleByID.get(id),
86
+ getNodeTypeByName: (type) => nodeTypeByName.get(type),
87
+ listInspectorPanels: () => modules.flatMap((mod) => mod.inspectorPanels),
88
+ listModules: () => [...modules],
89
+ listPaletteGroups: () => modules.flatMap((mod) => mod.paletteGroups),
90
+ listNodeTypes: () => [...nodeTypes]
91
+ };
92
+ }
93
+ function validateStudioDocument(document, modules) {
94
+ const issues = [];
95
+ if (document.schemaVersion !== 1) {
96
+ issues.push(makeIssue("Unsupported schema version", "schemaVersion", "studio.schemaVersion"));
97
+ }
98
+ if (!Array.isArray(document.nodes)) {
99
+ issues.push(makeIssue("Nodes must be an array", "nodes", "studio.nodes"));
100
+ return issues;
101
+ }
102
+ const registry = createStudioRegistry(modules);
103
+ const nodeIDs = /* @__PURE__ */ new Set();
104
+ document.nodes.forEach((node, index) => {
105
+ if (!node.id) {
106
+ issues.push(makeIssue("Node id is required", `nodes.${index}.id`, "studio.node.id"));
107
+ }
108
+ if (nodeIDs.has(node.id)) {
109
+ issues.push(makeIssue("Node id must be unique", `nodes.${index}.id`, "studio.node.id.duplicate"));
110
+ }
111
+ nodeIDs.add(node.id);
112
+ if (!registry.getNodeTypeByName(node.type)) {
113
+ issues.push(makeIssue("Unsupported node type", `nodes.${index}.type`, "studio.node.type"));
114
+ }
115
+ });
116
+ for (const module2 of modules) {
117
+ for (const validate of module2.validators) {
118
+ issues.push(...validate(document));
119
+ }
120
+ }
121
+ return issues;
122
+ }
123
+ function compileStudioDocument(document, modules) {
124
+ const issues = validateStudioDocument(document, modules);
125
+ const compilerEntries = modules.filter((mod) => typeof mod.compiler?.compileNode === "function").map((mod) => mod.compiler?.compileNode);
126
+ const layout = document.nodes.map((node) => {
127
+ for (const compileNode of compilerEntries) {
128
+ if (!compileNode) {
129
+ continue;
130
+ }
131
+ const compiled = compileNode(node);
132
+ if (compiled) {
133
+ return compiled;
134
+ }
135
+ }
136
+ return {
137
+ id: node.id,
138
+ blockType: node.type,
139
+ ...node.data
140
+ };
141
+ });
142
+ return {
143
+ issues,
144
+ layout
145
+ };
146
+ }
147
+ function migrateStudioDocument(value, migrations) {
148
+ const sorted = [...migrations].sort((a, b) => a.fromVersion - b.fromVersion);
149
+ if (isRecord(value) && value.schemaVersion === 1) {
150
+ return assertStudioDocumentV1(value);
151
+ }
152
+ let current = value;
153
+ for (const migration of sorted) {
154
+ if (!isRecord(current) || current.schemaVersion !== migration.fromVersion) {
155
+ continue;
156
+ }
157
+ current = migration.migrate(current);
158
+ }
159
+ return assertStudioDocumentV1(current);
160
+ }
161
+ // Annotate the CommonJS export names for ESM import in node:
162
+ 0 && (module.exports = {
163
+ assertStudioDocumentV1,
164
+ compileStudioDocument,
165
+ createEmptyStudioDocument,
166
+ createStudioRegistry,
167
+ migrateStudioDocument,
168
+ validateStudioDocument
169
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,139 @@
1
+ // src/index.ts
2
+ var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
3
+ var makeIssue = (message, path, code = "studio.invalid") => ({
4
+ code,
5
+ message,
6
+ path,
7
+ severity: "error"
8
+ });
9
+ var createEmptyStudioDocument = (title) => ({
10
+ schemaVersion: 1,
11
+ title,
12
+ nodes: [],
13
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
14
+ });
15
+ function assertStudioDocumentV1(input) {
16
+ if (!isRecord(input)) {
17
+ throw new Error("Studio document must be an object");
18
+ }
19
+ if (input.schemaVersion !== 1) {
20
+ throw new Error("Unsupported studio schemaVersion");
21
+ }
22
+ if (!Array.isArray(input.nodes)) {
23
+ throw new Error("Studio document nodes must be an array");
24
+ }
25
+ const nodes = input.nodes.map((node, index) => {
26
+ if (!isRecord(node)) {
27
+ throw new Error(`Node at index ${index} must be an object`);
28
+ }
29
+ if (typeof node.id !== "string" || node.id.length === 0) {
30
+ throw new Error(`Node at index ${index} has invalid id`);
31
+ }
32
+ if (typeof node.type !== "string" || node.type.length === 0) {
33
+ throw new Error(`Node at index ${index} has invalid type`);
34
+ }
35
+ if (!isRecord(node.data)) {
36
+ throw new Error(`Node at index ${index} has invalid data`);
37
+ }
38
+ return {
39
+ id: node.id,
40
+ type: node.type,
41
+ data: node.data
42
+ };
43
+ });
44
+ return {
45
+ schemaVersion: 1,
46
+ title: typeof input.title === "string" ? input.title : void 0,
47
+ nodes,
48
+ updatedAt: typeof input.updatedAt === "string" ? input.updatedAt : void 0
49
+ };
50
+ }
51
+ function createStudioRegistry(modules) {
52
+ const moduleByID = new Map(modules.map((mod) => [mod.id, mod]));
53
+ const nodeTypes = modules.flatMap((mod) => mod.nodeTypes);
54
+ const nodeTypeByName = new Map(nodeTypes.map((definition) => [definition.type, definition]));
55
+ return {
56
+ getModuleByID: (id) => moduleByID.get(id),
57
+ getNodeTypeByName: (type) => nodeTypeByName.get(type),
58
+ listInspectorPanels: () => modules.flatMap((mod) => mod.inspectorPanels),
59
+ listModules: () => [...modules],
60
+ listPaletteGroups: () => modules.flatMap((mod) => mod.paletteGroups),
61
+ listNodeTypes: () => [...nodeTypes]
62
+ };
63
+ }
64
+ function validateStudioDocument(document, modules) {
65
+ const issues = [];
66
+ if (document.schemaVersion !== 1) {
67
+ issues.push(makeIssue("Unsupported schema version", "schemaVersion", "studio.schemaVersion"));
68
+ }
69
+ if (!Array.isArray(document.nodes)) {
70
+ issues.push(makeIssue("Nodes must be an array", "nodes", "studio.nodes"));
71
+ return issues;
72
+ }
73
+ const registry = createStudioRegistry(modules);
74
+ const nodeIDs = /* @__PURE__ */ new Set();
75
+ document.nodes.forEach((node, index) => {
76
+ if (!node.id) {
77
+ issues.push(makeIssue("Node id is required", `nodes.${index}.id`, "studio.node.id"));
78
+ }
79
+ if (nodeIDs.has(node.id)) {
80
+ issues.push(makeIssue("Node id must be unique", `nodes.${index}.id`, "studio.node.id.duplicate"));
81
+ }
82
+ nodeIDs.add(node.id);
83
+ if (!registry.getNodeTypeByName(node.type)) {
84
+ issues.push(makeIssue("Unsupported node type", `nodes.${index}.type`, "studio.node.type"));
85
+ }
86
+ });
87
+ for (const module of modules) {
88
+ for (const validate of module.validators) {
89
+ issues.push(...validate(document));
90
+ }
91
+ }
92
+ return issues;
93
+ }
94
+ function compileStudioDocument(document, modules) {
95
+ const issues = validateStudioDocument(document, modules);
96
+ const compilerEntries = modules.filter((mod) => typeof mod.compiler?.compileNode === "function").map((mod) => mod.compiler?.compileNode);
97
+ const layout = document.nodes.map((node) => {
98
+ for (const compileNode of compilerEntries) {
99
+ if (!compileNode) {
100
+ continue;
101
+ }
102
+ const compiled = compileNode(node);
103
+ if (compiled) {
104
+ return compiled;
105
+ }
106
+ }
107
+ return {
108
+ id: node.id,
109
+ blockType: node.type,
110
+ ...node.data
111
+ };
112
+ });
113
+ return {
114
+ issues,
115
+ layout
116
+ };
117
+ }
118
+ function migrateStudioDocument(value, migrations) {
119
+ const sorted = [...migrations].sort((a, b) => a.fromVersion - b.fromVersion);
120
+ if (isRecord(value) && value.schemaVersion === 1) {
121
+ return assertStudioDocumentV1(value);
122
+ }
123
+ let current = value;
124
+ for (const migration of sorted) {
125
+ if (!isRecord(current) || current.schemaVersion !== migration.fromVersion) {
126
+ continue;
127
+ }
128
+ current = migration.migrate(current);
129
+ }
130
+ return assertStudioDocumentV1(current);
131
+ }
132
+ export {
133
+ assertStudioDocumentV1,
134
+ compileStudioDocument,
135
+ createEmptyStudioDocument,
136
+ createStudioRegistry,
137
+ migrateStudioDocument,
138
+ validateStudioDocument
139
+ };
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@orion-studios/payload-studio-core",
3
+ "version": "0.1.0-beta.1",
4
+ "description": "Core types, contracts, registry, and validation for Orion Studio",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "require": "./dist/index.js",
12
+ "import": "./dist/index.mjs"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup src/index.ts --format cjs,esm --dts",
20
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
21
+ "typecheck": "tsc --noEmit"
22
+ },
23
+ "keywords": [
24
+ "payload",
25
+ "cms",
26
+ "studio",
27
+ "headless"
28
+ ],
29
+ "author": "Orion Studios",
30
+ "license": "MIT",
31
+ "devDependencies": {
32
+ "tsup": "^8.0.0",
33
+ "typescript": "^5.3.0"
34
+ }
35
+ }