@arken/seer-protocol 0.1.1 → 0.1.2

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 (112) hide show
  1. package/.rush/temp/shrinkwrap-deps.json +537 -56
  2. package/area/area.models.ts +15 -0
  3. package/area/area.router.ts +74 -0
  4. package/area/area.schema.ts +22 -0
  5. package/area/area.types.ts +26 -0
  6. package/area/index.ts +5 -0
  7. package/asset/asset.models.ts +59 -0
  8. package/asset/asset.router.ts +55 -0
  9. package/asset/asset.schema.ts +27 -0
  10. package/asset/asset.types.ts +22 -0
  11. package/asset/index.ts +5 -0
  12. package/chain/chain.models.ts +50 -0
  13. package/chain/chain.router.ts +104 -0
  14. package/chain/chain.schema.ts +52 -0
  15. package/chain/chain.types.ts +24 -0
  16. package/chain/index.ts +5 -0
  17. package/character/character.models.ts +174 -0
  18. package/character/character.router.ts +314 -0
  19. package/character/character.schema.ts +147 -0
  20. package/character/character.types.ts +64 -0
  21. package/character/index.ts +5 -0
  22. package/chat/chat.models.ts +43 -0
  23. package/chat/chat.router.ts +67 -0
  24. package/chat/chat.schema.ts +36 -0
  25. package/chat/chat.types.ts +20 -0
  26. package/chat/index.ts +5 -0
  27. package/collection/collection.models.ts +76 -0
  28. package/collection/collection.router.ts +91 -0
  29. package/collection/collection.schema.ts +90 -0
  30. package/collection/collection.types.ts +36 -0
  31. package/collection/index.ts +5 -0
  32. package/core/core.models.ts +1380 -0
  33. package/core/core.router.ts +1781 -0
  34. package/core/core.schema.ts +847 -0
  35. package/core/core.types.ts +340 -0
  36. package/core/index.ts +5 -0
  37. package/evolution/evolution.models.ts +1 -1
  38. package/evolution/evolution.router.ts +8 -8
  39. package/evolution/evolution.schema.ts +1 -1
  40. package/evolution/evolution.types.ts +1 -1
  41. package/game/game.models.ts +53 -0
  42. package/game/game.router.ts +110 -0
  43. package/game/game.schema.ts +23 -0
  44. package/game/game.types.ts +28 -0
  45. package/game/index.ts +5 -0
  46. package/index.ts +39 -2
  47. package/infinite/infinite.models.ts +1 -1
  48. package/infinite/infinite.router.ts +8 -8
  49. package/infinite/infinite.schema.ts +1 -1
  50. package/infinite/infinite.types.ts +1 -1
  51. package/interface/index.ts +5 -0
  52. package/interface/interface.canonicalize.ts +279 -0
  53. package/interface/interface.models.ts +40 -0
  54. package/interface/interface.router.ts +175 -0
  55. package/interface/interface.schema.ts +59 -0
  56. package/interface/interface.types.ts +25 -0
  57. package/isles/isles.models.ts +1 -1
  58. package/isles/isles.router.ts +8 -8
  59. package/isles/isles.schema.ts +1 -1
  60. package/isles/isles.types.ts +1 -1
  61. package/item/index.ts +5 -0
  62. package/item/item.models.ts +124 -0
  63. package/item/item.router.ts +103 -0
  64. package/item/item.schema.ts +120 -0
  65. package/item/item.types.ts +74 -0
  66. package/job/index.ts +5 -0
  67. package/job/job.models.ts +14 -0
  68. package/job/job.router.ts +44 -0
  69. package/job/job.schema.ts +9 -0
  70. package/job/job.types.ts +23 -0
  71. package/market/index.ts +5 -0
  72. package/market/market.models.ts +113 -0
  73. package/market/market.router.ts +73 -0
  74. package/market/market.schema.ts +140 -0
  75. package/market/market.types.ts +56 -0
  76. package/oasis/oasis.models.ts +1 -1
  77. package/oasis/oasis.router.ts +2 -2
  78. package/oasis/oasis.schema.ts +1 -1
  79. package/oasis/oasis.types.ts +1 -1
  80. package/package.json +10 -3
  81. package/product/index.ts +5 -0
  82. package/product/product.models.ts +166 -0
  83. package/product/product.router.ts +93 -0
  84. package/product/product.schema.ts +149 -0
  85. package/product/product.types.ts +33 -0
  86. package/profile/index.ts +5 -0
  87. package/profile/profile.models.ts +214 -0
  88. package/profile/profile.router.ts +72 -0
  89. package/profile/profile.schema.ts +156 -0
  90. package/profile/profile.types.ts +22 -0
  91. package/raffle/index.ts +5 -0
  92. package/raffle/raffle.models.ts +44 -0
  93. package/raffle/raffle.router.ts +90 -0
  94. package/raffle/raffle.schema.ts +32 -0
  95. package/raffle/raffle.types.ts +30 -0
  96. package/router.ts +23 -29
  97. package/schema.ts +321 -0
  98. package/skill/index.ts +5 -0
  99. package/skill/skill.models.ts +16 -0
  100. package/skill/skill.router.ts +201 -0
  101. package/skill/skill.schema.ts +40 -0
  102. package/skill/skill.types.ts +33 -0
  103. package/trek/trek.models.ts +1 -1
  104. package/trek/trek.router.ts +1 -1
  105. package/trek/trek.schema.ts +1 -1
  106. package/trek/trek.types.ts +1 -1
  107. package/types.ts +172 -5
  108. package/video/index.ts +5 -0
  109. package/video/video.models.ts +25 -0
  110. package/video/video.router.ts +143 -0
  111. package/video/video.schema.ts +46 -0
  112. package/video/video.types.ts +33 -0
@@ -1,8 +1,8 @@
1
1
  import { z as zod } from 'zod';
2
2
  import { initTRPC } from '@trpc/server';
3
- import { customErrorFormatter, hasRole } from '@arken/rpc';
3
+ import { customErrorFormatter, hasRole } from '@arken/node/rpc';
4
4
  import * as Arken from '@arken/node';
5
- import { Query, getQueryInput, inferRouterOutputs, inferRouterInputs } from '@arken/schema';
5
+ import { Query, getQueryInput, inferRouterOutputs, inferRouterInputs } from '@arken/node/schema';
6
6
  import { RouterContext } from '../../types';
7
7
 
8
8
  export const z = zod;
@@ -1316,20 +1316,20 @@ export type RouterOutput = inferRouterOutputs<Router>;
1316
1316
  // }
1317
1317
  // });
1318
1318
 
1319
- // import type * as Arken from '@arken/types';
1320
- // import { isDebug, log } from '@arken/util';
1319
+ // import type * as Arken from '@arken/node/types';
1320
+ // import { isDebug, log } from '@arken/node/util';
1321
1321
  // import * as dotenv from 'dotenv';
1322
- // import { catchExceptions, subProcesses } from '@arken/process';
1322
+ // import { catchExceptions, subProcesses } from '@arken/node/process';
1323
1323
  // import fetch from 'node-fetch';
1324
1324
 
1325
1325
  // import path from 'path';
1326
1326
  // import jetpack, { find } from 'fs-jetpack';
1327
1327
  // import beautify from 'json-beautify';
1328
- // import { fancyTimeFormat } from '@arken/time';
1328
+ // import { fancyTimeFormat } from '@arken/node/time';
1329
1329
  // import md5 from 'js-md5';
1330
1330
  // import { getClientSocket } from '@arken/websocket';
1331
- // import { isValidRequest, getSignedRequest } from '@arken/web3';
1332
- // import getUsername from '@arken/legacy/getOldUsername';
1331
+ // import { isValidRequest, getSignedRequest } from '@arken/node/web3';
1332
+ // import getUsername from '@arken/node/legacy/getOldUsername';
1333
1333
  // import { z } from 'zod';
1334
1334
 
1335
1335
  // export async function monitorEvolutionRealms(app) {}
@@ -1 +1 @@
1
- import { z, ObjectId, Entity } from '@arken/schema';
1
+ import { z, ObjectId, Entity } from '@arken/node/schema';
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { Model, Document } from '@arken/mongo';
2
+ import { Model, Document } from '@arken/node/mongo';
3
3
  import * as schema from './infinite.schema';
4
4
 
5
5
  export type * from './infinite.router';
@@ -0,0 +1,5 @@
1
+ export * as Types from './interface.types';
2
+ export * as Models from './interface.models';
3
+ export * as Schemas from './interface.schema';
4
+ export * from './interface.router';
5
+ export * from './interface.service';
@@ -0,0 +1,279 @@
1
+ import get from 'lodash/get';
2
+
3
+ type AnyObj = Record<string, any>;
4
+
5
+ // --- same sugar compilation as web (keep it identical across runtimes) ---
6
+ function isObject(x: any) {
7
+ return !!x && typeof x === 'object' && !Array.isArray(x);
8
+ }
9
+ function isSugarExpr(x: any) {
10
+ return isObject(x) && '$' in x;
11
+ }
12
+ function isJsonLogicExpr(x: any) {
13
+ return isObject(x) && '$expr' in x;
14
+ }
15
+
16
+ function sugarArgToLogic(arg: any): any {
17
+ if (typeof arg === 'string' && arg.startsWith('$')) return { var: arg.slice(1) };
18
+ return arg;
19
+ }
20
+
21
+ export function compileSugarToJsonLogic(expr: any): any {
22
+ if (!isSugarExpr(expr)) return expr;
23
+
24
+ const raw = expr.$;
25
+ if (!Array.isArray(raw) || raw.length === 0) return { $expr: raw };
26
+
27
+ const [op, ...rest] = raw;
28
+ const args = rest.map(sugarArgToLogic);
29
+
30
+ const map: Record<string, (a: any[]) => any> = {
31
+ var: (a) => ({ var: a[0] }),
32
+ not: (a) => ({ '!': [a[0]] }),
33
+ and: (a) => ({ and: a }),
34
+ or: (a) => ({ or: a }),
35
+ eq: (a) => ({ '==': [a[0], a[1]] }),
36
+ ne: (a) => ({ '!=': [a[0], a[1]] }),
37
+ gt: (a) => ({ '>': [a[0], a[1]] }),
38
+ gte: (a) => ({ '>=': [a[0], a[1]] }),
39
+ lt: (a) => ({ '<': [a[0], a[1]] }),
40
+ lte: (a) => ({ '<=': [a[0], a[1]] }),
41
+ cat: (a) => ({ cat: a }),
42
+ if: (a) => ({ if: a }),
43
+ };
44
+
45
+ const fn = map[String(op)];
46
+ const compiled = fn ? fn(args) : { [String(op)]: args };
47
+ return { $expr: compiled };
48
+ }
49
+
50
+ // --- template-to-jsonlogic compiler (same logic as web) ---
51
+ function isTemplateString(s: any) {
52
+ return typeof s === 'string' && s.includes('{{') && s.includes('}}');
53
+ }
54
+ function isSingleMustacheWholeString(s: string) {
55
+ const t = s.trim();
56
+ return t.startsWith('{{') && t.endsWith('}}') && t.indexOf('{{') === 0 && t.lastIndexOf('}}') === t.length - 2;
57
+ }
58
+
59
+ function parseInlineArgs(raw: string): string[] {
60
+ const out: string[] = [];
61
+ let buf = '';
62
+ let depth = 0;
63
+ let quote: "'" | '"' | null = null;
64
+
65
+ const push = () => {
66
+ const s = buf.trim();
67
+ if (s) out.push(s);
68
+ buf = '';
69
+ };
70
+
71
+ for (let i = 0; i < raw.length; i++) {
72
+ const ch = raw[i];
73
+
74
+ if (quote) {
75
+ buf += ch;
76
+ if (ch === quote && raw[i - 1] !== '\\') quote = null;
77
+ continue;
78
+ }
79
+
80
+ if (ch === '"' || ch === "'") {
81
+ quote = ch as any;
82
+ buf += ch;
83
+ continue;
84
+ }
85
+
86
+ if (ch === '(') depth++;
87
+ if (ch === ')') depth = Math.max(0, depth - 1);
88
+
89
+ if (ch === ',' && depth === 0) {
90
+ push();
91
+ continue;
92
+ }
93
+
94
+ buf += ch;
95
+ }
96
+
97
+ push();
98
+ return out;
99
+ }
100
+
101
+ function parseLiteralOrVar(token: string): any {
102
+ const t = token.trim();
103
+
104
+ if ((t.startsWith('"') && t.endsWith('"')) || (t.startsWith("'") && t.endsWith("'"))) {
105
+ try {
106
+ if (t.startsWith("'")) return JSON.parse('"' + t.slice(1, -1).replace(/"/g, '\\"') + '"');
107
+ return JSON.parse(t);
108
+ } catch {
109
+ return t.slice(1, -1);
110
+ }
111
+ }
112
+
113
+ if (t === 'true') return true;
114
+ if (t === 'false') return false;
115
+ if (t === 'null') return null;
116
+
117
+ if (/^-?\d+(\.\d+)?$/.test(t)) return Number(t);
118
+
119
+ return { var: t };
120
+ }
121
+
122
+ function compileInlineMustacheToJsonLogic(expr: string): any {
123
+ const s = expr.trim();
124
+
125
+ if (/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\[[0-9]+\])*$/.test(s)) {
126
+ return { var: s };
127
+ }
128
+
129
+ const m = /^([A-Za-z_$][\w$]*)\(([\s\S]*)\)$/.exec(s);
130
+ if (!m) return { var: s };
131
+
132
+ const fn = m[1];
133
+ const argRaw = m[2] ?? '';
134
+ const argTokens = parseInlineArgs(argRaw);
135
+ const args = argTokens.map(parseLiteralOrVar);
136
+
137
+ const map: Record<string, any> = {
138
+ not: (a: any[]) => ({ '!': [a[0]] }),
139
+ and: (a: any[]) => ({ and: a }),
140
+ or: (a: any[]) => ({ or: a }),
141
+
142
+ eq: (a: any[]) => ({ '==': [a[0], a[1]] }),
143
+ ne: (a: any[]) => ({ '!=': [a[0], a[1]] }),
144
+ gt: (a: any[]) => ({ '>': [a[0], a[1]] }),
145
+ gte: (a: any[]) => ({ '>=': [a[0], a[1]] }),
146
+ lt: (a: any[]) => ({ '<': [a[0], a[1]] }),
147
+ lte: (a: any[]) => ({ '<=': [a[0], a[1]] }),
148
+
149
+ cat: (a: any[]) => ({ cat: a }),
150
+ if: (a: any[]) => ({ if: a }),
151
+ };
152
+
153
+ const builder = map[fn];
154
+ if (builder) return builder(args);
155
+
156
+ return { [fn]: args };
157
+ }
158
+
159
+ function compileInterpolatedStringToCat(s: string): any {
160
+ const parts: any[] = [];
161
+ let i = 0;
162
+
163
+ while (i < s.length) {
164
+ const start = s.indexOf('{{', i);
165
+ if (start === -1) {
166
+ const tail = s.slice(i);
167
+ if (tail) parts.push(tail);
168
+ break;
169
+ }
170
+
171
+ const head = s.slice(i, start);
172
+ if (head) parts.push(head);
173
+
174
+ const end = s.indexOf('}}', start + 2);
175
+ if (end === -1) {
176
+ parts.push(s.slice(start));
177
+ break;
178
+ }
179
+
180
+ const inner = s.slice(start + 2, end);
181
+ parts.push(compileInlineMustacheToJsonLogic(inner));
182
+
183
+ i = end + 2;
184
+ }
185
+
186
+ if (parts.length === 1) return parts[0];
187
+ return { cat: parts };
188
+ }
189
+
190
+ function compileTemplateStringToJsonLogicValue(input: string): any {
191
+ let out = String(input);
192
+
193
+ const ifRe = /{{#if\s+([^}]+)}}([\s\S]*?)({{else}}([\s\S]*?))?{{\/if}}/g;
194
+
195
+ for (let loop = 0; loop < 10; loop++) {
196
+ const prev = out;
197
+ out = out.replace(ifRe, (_m, condRaw, thenPart, _elseWhole, elsePart) => {
198
+ const cond = String(condRaw ?? '').trim();
199
+ const thenS = String(thenPart ?? '');
200
+ const elseS = String(elsePart ?? '');
201
+ return `__IF__(${cond})__THEN__(${thenS})__ELSE__(${elseS})__END__`;
202
+ });
203
+ if (out === prev) break;
204
+ }
205
+
206
+ const ifSentinelRe = /^__IF__\(([\s\S]*)\)__THEN__\(([\s\S]*)\)__ELSE__\(([\s\S]*)\)__END__$/;
207
+ const mm = ifSentinelRe.exec(out);
208
+ if (mm) {
209
+ const condExpr = compileInlineMustacheToJsonLogic(mm[1]);
210
+ const thenCompiled = compileTemplateStringToJsonLogicValue(mm[2]);
211
+ const elseCompiled = compileTemplateStringToJsonLogicValue(mm[3]);
212
+ return { if: [condExpr, thenCompiled, elseCompiled] };
213
+ }
214
+
215
+ if (isSingleMustacheWholeString(out) && !out.includes('{{#if')) {
216
+ const inner = out.trim().slice(2, -2);
217
+ return compileInlineMustacheToJsonLogic(inner);
218
+ }
219
+
220
+ if (out.includes('{{')) {
221
+ return compileInterpolatedStringToCat(out);
222
+ }
223
+
224
+ return out;
225
+ }
226
+
227
+ function compileTemplateStringToExpr(s: string) {
228
+ if (!isTemplateString(s)) return s;
229
+ const compiled = compileTemplateStringToJsonLogicValue(s);
230
+ if (compiled && typeof compiled === 'object') return { $expr: compiled };
231
+ return compiled;
232
+ }
233
+
234
+ // --- canonicalize: walk any JSON-ish tree and rewrite templates/sugar into $expr ---
235
+ export function canonicalizeInterfaceDoc(input: any): any {
236
+ const seen = new Map<any, any>();
237
+
238
+ const walk = (v: any): any => {
239
+ if (v === null || v === undefined) return v;
240
+ if (typeof v === 'number' || typeof v === 'boolean') return v;
241
+
242
+ // IMPORTANT: Seer canonicalization should NOT preserve functions (DB-safe only)
243
+ if (typeof v === 'function') return undefined;
244
+
245
+ if (typeof v === 'string') {
246
+ // forbid legacy JS formulas at the canonical layer
247
+ if (v.trim().startsWith('=')) {
248
+ // best practice: reject, but you can also keep as-is if you must
249
+ throw new Error('Canonical interface spec cannot contain legacy "=..." formulas.');
250
+ }
251
+ if (isTemplateString(v)) return walk(compileTemplateStringToExpr(v));
252
+ return v;
253
+ }
254
+
255
+ if (Array.isArray(v)) return v.map(walk);
256
+
257
+ if (typeof v === 'object') {
258
+ if (seen.has(v)) return seen.get(v);
259
+
260
+ // sugar -> $expr
261
+ if (isSugarExpr(v)) return walk(compileSugarToJsonLogic(v));
262
+
263
+ // already $expr: canonicalize inside it too (deep)
264
+ if (isJsonLogicExpr(v)) {
265
+ const out = { $expr: walk((v as any).$expr) };
266
+ return out;
267
+ }
268
+
269
+ const out: AnyObj = {};
270
+ seen.set(v, out);
271
+ for (const [k, val] of Object.entries(v)) out[k] = walk(val);
272
+ return out;
273
+ }
274
+
275
+ return v;
276
+ };
277
+
278
+ return walk(input);
279
+ }
@@ -0,0 +1,40 @@
1
+ // arken/packages/node/modules/interface/interface.models.ts
2
+ //
3
+ import * as mongo from '../../util/mongo';
4
+ import type * as Types from './interface.types';
5
+
6
+ export const Interface = mongo.createModel<Types.InterfaceDocument>('Interface', {
7
+ key: { type: String, required: true },
8
+ submissions: [{ type: mongo.Schema.Types.ObjectId, ref: 'InterfaceSubmission' }],
9
+ groupId: { type: mongo.Schema.Types.ObjectId, ref: 'InterfaceGroup', required: true },
10
+
11
+ status: {
12
+ type: String,
13
+ default: 'Active',
14
+ enum: ['Paused', 'Pending', 'Active', 'Archived', 'Published', 'Draft'],
15
+ },
16
+
17
+ // ✅ NEW (typed-wrapper-safe): store as Mixed, validate via Zod on IO
18
+ inherits: { type: mongo.Schema.Types.Mixed, default: [] }, // string[]
19
+ variables: { type: mongo.Schema.Types.Mixed, default: {} }, // record
20
+ patches: { type: mongo.Schema.Types.Mixed, default: [] }, // patch[]
21
+
22
+ nodes: { type: mongo.Schema.Types.Mixed, default: [] },
23
+ version: { type: Number },
24
+ });
25
+
26
+ export const InterfaceGroup = mongo.createModel<Types.InterfaceGroupDocument>('InterfaceGroup', {});
27
+
28
+ export const InterfaceComponent = mongo.createModel<Types.InterfaceComponentDocument>('InterfaceComponent', {
29
+ value: { type: Object, default: {} },
30
+ type: { type: String },
31
+ hasAttachment: { type: Boolean },
32
+ hasValidation: { type: Boolean },
33
+ isDisabled: { type: Boolean },
34
+ isEditable: { type: Boolean },
35
+ isRequired: { type: Boolean },
36
+ });
37
+
38
+ export const InterfaceSubmission = mongo.createModel<Types.InterfaceSubmissionDocument>('InterfaceSubmission', {
39
+ interfaceId: { type: mongo.Schema.Types.ObjectId, ref: 'Interface' } as any,
40
+ });
@@ -0,0 +1,175 @@
1
+ import { z as zod } from 'zod';
2
+ import { initTRPC, inferRouterInputs } from '@trpc/server';
3
+ import { customErrorFormatter, hasRole } from '../../util/rpc';
4
+ import type { RouterContext } from '../../types';
5
+ import { Interface, InterfaceGroup, InterfaceComponent } from './interface.schema';
6
+ import { Query, getQueryInput, getQueryOutput, inferRouterOutputs } from '../../schema';
7
+
8
+ export const z = zod;
9
+ export const t = initTRPC.context<RouterContext>().create();
10
+ export const router = t.router;
11
+ export const procedure = t.procedure;
12
+
13
+ export const createRouter = () =>
14
+ router({
15
+ // Interface Procedures
16
+ getInterface: procedure
17
+ .use(hasRole('guest', t))
18
+ .use(customErrorFormatter(t))
19
+ .input(getQueryInput(Interface))
20
+ .output(Interface)
21
+ .query(({ input, ctx }) => (ctx.app.service.Interface.getInterface as any)(input, ctx)),
22
+
23
+ createInterface: procedure
24
+ .use(hasRole('user', t))
25
+ .use(customErrorFormatter(t))
26
+ .input(getQueryInput(Interface))
27
+ .output(Interface.pick({ id: true, name: true }))
28
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.createInterface as any)(input, ctx)),
29
+
30
+ updateInterface: procedure
31
+ .use(hasRole('user', t))
32
+ .use(customErrorFormatter(t))
33
+ .input(getQueryInput(Interface))
34
+ .output(Interface.pick({ id: true }))
35
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.updateInterface as any)(input, ctx)),
36
+
37
+ deleteInterface: procedure
38
+ .use(hasRole('user', t))
39
+ .use(customErrorFormatter(t))
40
+ .input(getQueryInput(Interface))
41
+ // .output(Interface.pick({ id: true }))
42
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.deleteInterface as any)(input, ctx)),
43
+
44
+ getInterfaces: procedure
45
+ .use(hasRole('user', t))
46
+ .use(customErrorFormatter(t))
47
+ .input(getQueryInput(Interface))
48
+ .output(z.object({ items: z.array(Interface), total: z.number() }))
49
+ .query(({ input, ctx }) => (ctx.app.service.Interface.getInterfaces as any)(input, ctx)),
50
+
51
+ // getInterface: procedure
52
+ // .use(hasRole('guest', t))
53
+ // .use(customErrorFormatter(t))
54
+ // .input(getQueryInput(Interface))
55
+ // .output(Interface)
56
+ // .query(({ input, ctx }) => (ctx.app.service.Interface.getInterface as any)(input, ctx)),
57
+
58
+ // getInterfaces: procedure
59
+ // .use(hasRole('guest', t))
60
+ // .use(customErrorFormatter(t))
61
+ // .input(getQueryInput(Interface))
62
+ // .output(z.array(Interface))
63
+ // .query(({ input, ctx }) => (ctx.app.service.Interface.getInterfaces as any)(input, ctx)),
64
+
65
+ // createInterface: procedure
66
+ // .use(hasRole('admin', t))
67
+ // .use(customErrorFormatter(t))
68
+ // .input(getQueryInput(Interface))
69
+ // .output(Interface.pick({ id: true }))
70
+ // .mutation(({ input, ctx }) => (ctx.app.service.Interface.createInterface as any)(input, ctx)),
71
+
72
+ // updateInterface: procedure
73
+ // .use(hasRole('admin', t))
74
+ // .use(customErrorFormatter(t))
75
+ // .input(getQueryInput(Interface))
76
+ // .output(Interface.pick({ id: true }))
77
+ // .mutation(({ input, ctx }) => (ctx.app.service.Interface.updateInterface as any)(input, ctx)),
78
+
79
+ // deleteInterface: procedure
80
+ // .use(hasRole('admin', t))
81
+ // .use(customErrorFormatter(t))
82
+ // .input(getQueryInput(Interface))
83
+ // .output(Interface.pick({ id: true }))
84
+ // .mutation(({ input, ctx }) => (ctx.app.service.Interface.deleteInterface as any)(input, ctx)),
85
+
86
+ // InterfaceGroup Procedures
87
+ getInterfaceGroup: procedure
88
+ .use(hasRole('guest', t))
89
+ .use(customErrorFormatter(t))
90
+ .input(getQueryInput(InterfaceGroup))
91
+ .output(InterfaceGroup)
92
+ .query(({ input, ctx }) => (ctx.app.service.Interface.getInterfaceGroup as any)(input, ctx)),
93
+
94
+ getInterfaceGroups: procedure
95
+ .use(hasRole('guest', t))
96
+ .use(customErrorFormatter(t))
97
+ .input(getQueryInput(InterfaceGroup))
98
+ .output(z.array(InterfaceGroup))
99
+ .query(({ input, ctx }) => (ctx.app.service.Interface.getInterfaceGroups as any)(input, ctx)),
100
+
101
+ createInterfaceGroup: procedure
102
+ .use(hasRole('admin', t))
103
+ .use(customErrorFormatter(t))
104
+ .input(getQueryInput(InterfaceGroup))
105
+ .output(InterfaceGroup.pick({ id: true }))
106
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.createInterfaceGroup as any)(input, ctx)),
107
+
108
+ updateInterfaceGroup: procedure
109
+ .use(hasRole('admin', t))
110
+ .use(customErrorFormatter(t))
111
+ .input(getQueryInput(InterfaceGroup))
112
+ .output(InterfaceGroup.pick({ id: true }))
113
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.updateInterfaceGroup as any)(input, ctx)),
114
+
115
+ // InterfaceComponent Procedures
116
+ getInterfaceComponent: procedure
117
+ .use(hasRole('guest', t))
118
+ .use(customErrorFormatter(t))
119
+ .input(getQueryInput(InterfaceComponent))
120
+ .output(InterfaceComponent)
121
+ .query(({ input, ctx }) => (ctx.app.service.Interface.getInterfaceComponent as any)(input, ctx)),
122
+
123
+ createInterfaceComponent: procedure
124
+ .use(hasRole('admin', t))
125
+ .use(customErrorFormatter(t))
126
+ .input(getQueryInput(InterfaceComponent))
127
+ .output(InterfaceComponent.pick({ id: true }))
128
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.createInterfaceComponent as any)(input, ctx)),
129
+
130
+ updateInterfaceComponent: procedure
131
+ .use(hasRole('admin', t))
132
+ .use(customErrorFormatter(t))
133
+ .input(getQueryInput(InterfaceComponent))
134
+ .output(InterfaceComponent.pick({ id: true }))
135
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.updateInterfaceComponent as any)(input, ctx)),
136
+
137
+ publishInterface: procedure
138
+ .use(hasRole('admin', t))
139
+ .use(customErrorFormatter(t))
140
+ .input(getQueryInput(Interface))
141
+ .output(Interface.pick({ id: true }))
142
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.updateInterfaceComponent as any)(input, ctx)),
143
+
144
+ deactivateInterface: procedure
145
+ .use(hasRole('admin', t))
146
+ .use(customErrorFormatter(t))
147
+ .input(getQueryInput(Interface))
148
+ .output(Interface.pick({ id: true }))
149
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.updateInterfaceComponent as any)(input, ctx)),
150
+
151
+ resetInterface: procedure
152
+ .use(hasRole('admin', t))
153
+ .use(customErrorFormatter(t))
154
+ .input(getQueryInput(Interface))
155
+ .output(Interface.pick({ id: true }))
156
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.updateInterfaceComponent as any)(input, ctx)),
157
+
158
+ acceptInterfaceSubmission: procedure
159
+ .use(hasRole('admin', t))
160
+ .use(customErrorFormatter(t))
161
+ .input(getQueryInput(Interface))
162
+ .output(Interface.pick({ id: true }))
163
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.updateInterfaceComponent as any)(input, ctx)),
164
+
165
+ createInterfaceDraft: procedure
166
+ .use(hasRole('admin', t))
167
+ .use(customErrorFormatter(t))
168
+ .input(getQueryInput(Interface))
169
+ .output(Interface.pick({ id: true }))
170
+ .mutation(({ input, ctx }) => (ctx.app.service.Interface.createInterfaceDraft as any)(input, ctx)),
171
+ });
172
+
173
+ export type Router = ReturnType<typeof createRouter>;
174
+ export type RouterInput = inferRouterInputs<Router>;
175
+ export type RouterOutput = inferRouterOutputs<Router>;
@@ -0,0 +1,59 @@
1
+ // arken/packages/node/modules/interface/interface.schema.ts
2
+ //
3
+ import { z, ObjectId, Entity } from '../../schema';
4
+
5
+ // Patch ops for interface composition
6
+ const InterfacePatch = z.object({
7
+ op: z.enum(['merge', 'replace', 'remove', 'push', 'unshift', 'splice']).default('merge'),
8
+ key: z.string().min(1), // target node key (or special key like "root")
9
+ path: z.string().optional(), // optional deep path inside that node, ex: "props.omit"
10
+ value: z.unknown().optional(), // payload for merge/replace/push/etc
11
+ });
12
+
13
+ export const Interface = Entity.merge(
14
+ z.object({
15
+ ratingId: ObjectId.optional(),
16
+ groupId: ObjectId.optional(),
17
+ submissions: z.array(ObjectId).optional(),
18
+
19
+ // ✅ NEW: composition / inheritance
20
+ inherits: z.array(z.string()).default([]),
21
+
22
+ // ✅ NEW: variables available to formula scope + patch engine
23
+ variables: z.record(z.unknown()).default({}),
24
+
25
+ // ✅ NEW: patch list applied on top of inherited/base nodes
26
+ patches: z.array(InterfacePatch).default([]),
27
+
28
+ // existing
29
+ nodes: z.any(), // you can later tighten this to z.array(AnyNodeSchema)
30
+ version: z.number().optional(),
31
+ status: z.enum(['Paused', 'Pending', 'Active', 'Archived', 'Published', 'Draft']).default('Active'),
32
+ })
33
+ );
34
+
35
+ export const InterfaceGroup = Entity.merge(
36
+ z.object({
37
+ roles: z.array(ObjectId).optional(),
38
+ })
39
+ );
40
+
41
+ export const InterfaceComponent = Entity.merge(
42
+ z.object({
43
+ value: z.unknown().optional(),
44
+ data: z.record(z.unknown()).optional(),
45
+ type: z.string().optional(),
46
+ hasAttachment: z.boolean().optional(),
47
+ hasValidation: z.boolean().optional(),
48
+ isDisabled: z.boolean().optional(),
49
+ isEditable: z.boolean().optional(),
50
+ isRequired: z.boolean().optional(),
51
+ })
52
+ );
53
+
54
+ export const InterfaceSubmission = Entity.merge(
55
+ z.object({
56
+ interfaceId: ObjectId,
57
+ interface: ObjectId.optional(),
58
+ })
59
+ );
@@ -0,0 +1,25 @@
1
+ import { z, Model, Document } from '../../util/mongo';
2
+ import * as schema from './interface.schema';
3
+
4
+ export type * from './interface.router';
5
+ export type * from './interface.service';
6
+ export type { RouterContext } from '../../types';
7
+
8
+ export type Interface = z.infer<typeof schema.Interface>;
9
+ export type InterfaceDocument = Interface & Document;
10
+
11
+ export type InterfaceGroup = z.infer<typeof schema.InterfaceGroup>;
12
+ export type InterfaceGroupDocument = InterfaceGroup & Document;
13
+
14
+ export type InterfaceComponent = z.infer<typeof schema.InterfaceComponent>;
15
+ export type InterfaceComponentDocument = InterfaceComponent & Document;
16
+
17
+ export type InterfaceSubmission = z.infer<typeof schema.InterfaceSubmission>;
18
+ export type InterfaceSubmissionDocument = InterfaceSubmission & Document;
19
+
20
+ export type Mappings = {
21
+ Interface: Model<InterfaceDocument>;
22
+ InterfaceGroup: Model<InterfaceGroupDocument>;
23
+ InterfaceComponent: Model<InterfaceComponentDocument>;
24
+ InterfaceSubmission: Model<InterfaceSubmissionDocument>;
25
+ };
@@ -1,3 +1,3 @@
1
- import * as mongo from '@arken/mongo';
1
+ import * as mongo from '@arken/node/mongo';
2
2
 
3
3
  const { addTagVirtuals, addApplicationVirtual } = mongo;
@@ -1,8 +1,8 @@
1
1
  import { z as zod } from 'zod';
2
2
  import { initTRPC } from '@trpc/server';
3
- import { customErrorFormatter, hasRole } from '@arken/rpc';
3
+ import { customErrorFormatter, hasRole } from '@arken/node/rpc';
4
4
  import * as Arken from '@arken/node';
5
- import { Query, getQueryInput, inferRouterOutputs, inferRouterInputs } from '@arken/schema';
5
+ import { Query, getQueryInput, inferRouterOutputs, inferRouterInputs } from '@arken/node/schema';
6
6
  import { RouterContext } from '../../types';
7
7
 
8
8
  export const z = zod;
@@ -1316,20 +1316,20 @@ export type RouterOutput = inferRouterOutputs<Router>;
1316
1316
  // }
1317
1317
  // });
1318
1318
 
1319
- // import type * as Arken from '@arken/types';
1320
- // import { isDebug, log } from '@arken/util';
1319
+ // import type * as Arken from '@arken/node/types';
1320
+ // import { isDebug, log } from '@arken/node/util';
1321
1321
  // import * as dotenv from 'dotenv';
1322
- // import { catchExceptions, subProcesses } from '@arken/process';
1322
+ // import { catchExceptions, subProcesses } from '@arken/node/process';
1323
1323
  // import fetch from 'node-fetch';
1324
1324
 
1325
1325
  // import path from 'path';
1326
1326
  // import jetpack, { find } from 'fs-jetpack';
1327
1327
  // import beautify from 'json-beautify';
1328
- // import { fancyTimeFormat } from '@arken/time';
1328
+ // import { fancyTimeFormat } from '@arken/node/time';
1329
1329
  // import md5 from 'js-md5';
1330
1330
  // import { getClientSocket } from '@arken/websocket';
1331
- // import { isValidRequest, getSignedRequest } from '@arken/web3';
1332
- // import getUsername from '@arken/legacy/getOldUsername';
1331
+ // import { isValidRequest, getSignedRequest } from '@arken/node/web3';
1332
+ // import getUsername from '@arken/node/legacy/getOldUsername';
1333
1333
  // import { z } from 'zod';
1334
1334
 
1335
1335
  // export async function monitorEvolutionRealms(app) {}