@playcraft/common 0.0.27 → 0.0.30

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 (63) hide show
  1. package/dist/agent-tools/types.d.ts +372 -1
  2. package/dist/agent-tools/types.d.ts.map +1 -1
  3. package/dist/agent-tools/types.js +32 -1
  4. package/dist/agent-tools/types.js.map +1 -1
  5. package/dist/recommend/api-types.d.ts +74 -0
  6. package/dist/recommend/api-types.d.ts.map +1 -1
  7. package/dist/recommend/atom-graph/basic-atom-graph.d.ts +3 -0
  8. package/dist/recommend/atom-graph/basic-atom-graph.d.ts.map +1 -0
  9. package/dist/recommend/atom-graph/basic-atom-graph.js +291 -0
  10. package/dist/recommend/atom-graph/basic-atom-graph.js.map +1 -0
  11. package/dist/recommend/atom-graph/basic-atom-skill-graph.d.ts +3 -0
  12. package/dist/recommend/atom-graph/basic-atom-skill-graph.d.ts.map +1 -0
  13. package/dist/recommend/atom-graph/basic-atom-skill-graph.js +130 -0
  14. package/dist/recommend/atom-graph/basic-atom-skill-graph.js.map +1 -0
  15. package/dist/recommend/atom-graph/index.d.ts +6 -0
  16. package/dist/recommend/atom-graph/index.d.ts.map +1 -0
  17. package/dist/recommend/atom-graph/index.js +6 -0
  18. package/dist/recommend/atom-graph/index.js.map +1 -0
  19. package/dist/recommend/atom-graph/remix-examples.d.ts +6 -0
  20. package/dist/recommend/atom-graph/remix-examples.d.ts.map +1 -0
  21. package/dist/recommend/atom-graph/remix-examples.js +192 -0
  22. package/dist/recommend/atom-graph/remix-examples.js.map +1 -0
  23. package/dist/recommend/atom-graph/types.d.ts +332 -0
  24. package/dist/recommend/atom-graph/types.d.ts.map +1 -0
  25. package/dist/recommend/atom-graph/types.js +2 -0
  26. package/dist/recommend/atom-graph/types.js.map +1 -0
  27. package/dist/recommend/atom-graph/validate.d.ts +7 -0
  28. package/dist/recommend/atom-graph/validate.d.ts.map +1 -0
  29. package/dist/recommend/atom-graph/validate.js +140 -0
  30. package/dist/recommend/atom-graph/validate.js.map +1 -0
  31. package/dist/recommend/index.d.ts +1 -0
  32. package/dist/recommend/index.d.ts.map +1 -1
  33. package/dist/recommend/index.js +1 -0
  34. package/dist/recommend/index.js.map +1 -1
  35. package/package.json +2 -1
  36. package/dist/auth/jwt.test.d.ts +0 -2
  37. package/dist/auth/jwt.test.d.ts.map +0 -1
  38. package/dist/auth/jwt.test.js +0 -13
  39. package/dist/auth/jwt.test.js.map +0 -1
  40. package/dist/auth/signature.spec.d.ts +0 -2
  41. package/dist/auth/signature.spec.d.ts.map +0 -1
  42. package/dist/auth/signature.spec.js +0 -195
  43. package/dist/auth/signature.spec.js.map +0 -1
  44. package/dist/messenger/server.test.d.ts +0 -2
  45. package/dist/messenger/server.test.d.ts.map +0 -1
  46. package/dist/messenger/server.test.js +0 -66
  47. package/dist/messenger/server.test.js.map +0 -1
  48. package/dist/models/converters.d.ts +0 -11
  49. package/dist/models/converters.d.ts.map +0 -1
  50. package/dist/models/converters.js +0 -25
  51. package/dist/models/converters.js.map +0 -1
  52. package/dist/models/converters.test.d.ts +0 -2
  53. package/dist/models/converters.test.d.ts.map +0 -1
  54. package/dist/models/converters.test.js +0 -18
  55. package/dist/models/converters.test.js.map +0 -1
  56. package/dist/models/scene.test.d.ts +0 -2
  57. package/dist/models/scene.test.d.ts.map +0 -1
  58. package/dist/models/scene.test.js +0 -12
  59. package/dist/models/scene.test.js.map +0 -1
  60. package/dist/sharedb/server.test.d.ts +0 -2
  61. package/dist/sharedb/server.test.d.ts.map +0 -1
  62. package/dist/sharedb/server.test.js +0 -59
  63. package/dist/sharedb/server.test.js.map +0 -1
@@ -0,0 +1,140 @@
1
+ const DEFAULT_TOPOLOGY_EDGE_KINDS = ['requires'];
2
+ export function getAtomNode(graph, nodeId) {
3
+ return graph.nodes.find((node) => node.id === nodeId);
4
+ }
5
+ export function getAtomEdges(graph, edgeKinds) {
6
+ if (!edgeKinds)
7
+ return graph.edges;
8
+ const allowed = new Set(edgeKinds);
9
+ return graph.edges.filter((edge) => allowed.has(edge.kind));
10
+ }
11
+ export function findAtomAncestors(graph, nodeId, edgeKinds = DEFAULT_TOPOLOGY_EDGE_KINDS) {
12
+ const incoming = new Map();
13
+ for (const edge of getAtomEdges(graph, edgeKinds)) {
14
+ const sources = incoming.get(edge.to) ?? [];
15
+ sources.push(edge.from);
16
+ incoming.set(edge.to, sources);
17
+ }
18
+ const visited = new Set();
19
+ const stack = [...(incoming.get(nodeId) ?? [])];
20
+ while (stack.length > 0) {
21
+ const current = stack.pop();
22
+ if (!current || visited.has(current))
23
+ continue;
24
+ visited.add(current);
25
+ stack.push(...(incoming.get(current) ?? []));
26
+ }
27
+ return [...visited];
28
+ }
29
+ export function topologicalSortAtomGraph(graph, edgeKinds = DEFAULT_TOPOLOGY_EDGE_KINDS) {
30
+ const nodeIds = graph.nodes.map((node) => node.id);
31
+ const nodeIdSet = new Set(nodeIds);
32
+ const topologyEdges = getAtomEdges(graph, edgeKinds).filter((edge) => nodeIdSet.has(edge.from) && nodeIdSet.has(edge.to));
33
+ const indegree = new Map();
34
+ const outgoing = new Map();
35
+ for (const nodeId of nodeIds) {
36
+ indegree.set(nodeId, 0);
37
+ outgoing.set(nodeId, []);
38
+ }
39
+ for (const edge of topologyEdges) {
40
+ outgoing.get(edge.from)?.push(edge.to);
41
+ indegree.set(edge.to, (indegree.get(edge.to) ?? 0) + 1);
42
+ }
43
+ const queue = nodeIds.filter((nodeId) => (indegree.get(nodeId) ?? 0) === 0);
44
+ const sorted = [];
45
+ while (queue.length > 0) {
46
+ const current = queue.shift();
47
+ if (!current)
48
+ continue;
49
+ sorted.push(current);
50
+ for (const next of outgoing.get(current) ?? []) {
51
+ const nextIndegree = (indegree.get(next) ?? 0) - 1;
52
+ indegree.set(next, nextIndegree);
53
+ if (nextIndegree === 0)
54
+ queue.push(next);
55
+ }
56
+ }
57
+ return sorted;
58
+ }
59
+ export function validateAtomGraph(graph) {
60
+ const errors = [];
61
+ const warnings = [];
62
+ const seenNodeIds = new Set();
63
+ const duplicateNodeIds = new Set();
64
+ for (const node of graph.nodes) {
65
+ if (seenNodeIds.has(node.id))
66
+ duplicateNodeIds.add(node.id);
67
+ seenNodeIds.add(node.id);
68
+ }
69
+ for (const nodeId of duplicateNodeIds) {
70
+ errors.push({
71
+ code: 'duplicate_node_id',
72
+ nodeId,
73
+ message: `Atom graph contains duplicate node id "${nodeId}".`,
74
+ });
75
+ }
76
+ const nodeIds = new Set(graph.nodes.map((node) => node.id));
77
+ const connectedNodeIds = new Set();
78
+ for (const edge of graph.edges) {
79
+ connectedNodeIds.add(edge.from);
80
+ connectedNodeIds.add(edge.to);
81
+ if (!nodeIds.has(edge.from)) {
82
+ errors.push({
83
+ code: 'edge_missing_source',
84
+ edge,
85
+ message: `Atom edge references missing source node "${edge.from}".`,
86
+ });
87
+ }
88
+ if (!nodeIds.has(edge.to)) {
89
+ errors.push({
90
+ code: 'edge_missing_target',
91
+ edge,
92
+ message: `Atom edge references missing target node "${edge.to}".`,
93
+ });
94
+ }
95
+ if (edge.weight !== undefined && (edge.weight < 0 || edge.weight > 1)) {
96
+ warnings.push({
97
+ code: 'invalid_edge_weight',
98
+ edge,
99
+ message: `Atom edge weight should be between 0 and 1, got ${edge.weight}.`,
100
+ });
101
+ }
102
+ }
103
+ for (const node of graph.nodes) {
104
+ if (!connectedNodeIds.has(node.id)) {
105
+ warnings.push({
106
+ code: 'isolated_node',
107
+ nodeId: node.id,
108
+ message: `Atom node "${node.id}" has no edges.`,
109
+ });
110
+ }
111
+ }
112
+ const topologicalOrder = topologicalSortAtomGraph(graph);
113
+ if (topologicalOrder.length !== graph.nodes.length) {
114
+ errors.push({
115
+ code: 'cycle_detected',
116
+ message: 'Atom graph contains a cycle in requires edges.',
117
+ });
118
+ }
119
+ // Gameplay nodes must have a requires path to an engine OR scaffold (component) node.
120
+ // In slot-level graphs, the root is an engine node (phaser/threejs/playcanvas).
121
+ // In skill-level graphs, the root is a prefab/scaffold node (e.g. match3_casual.prefab), category `component`.
122
+ const runtimeNodeIds = new Set(graph.nodes.filter((node) => node.category === 'engine' || node.category === 'component').map((node) => node.id));
123
+ for (const gameplayNode of graph.nodes.filter((node) => node.category === 'gameplay')) {
124
+ const ancestors = findAtomAncestors(graph, gameplayNode.id);
125
+ if (!ancestors.some((ancestorId) => runtimeNodeIds.has(ancestorId))) {
126
+ warnings.push({
127
+ code: 'gameplay_without_engine_path',
128
+ nodeId: gameplayNode.id,
129
+ message: `Gameplay atom "${gameplayNode.id}" has no requires path to an engine or scaffold (component) atom.`,
130
+ });
131
+ }
132
+ }
133
+ return {
134
+ valid: errors.length === 0,
135
+ errors,
136
+ warnings,
137
+ topologicalOrder,
138
+ };
139
+ }
140
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/recommend/atom-graph/validate.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  export * from './types.js';
2
2
  export * from './api-types.js';
3
3
  export * from './algorithms.js';
4
+ export * from './atom-graph/index.js';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recommend/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recommend/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export * from './types.js';
2
2
  export * from './api-types.js';
3
3
  export * from './algorithms.js';
4
+ export * from './atom-graph/index.js';
4
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recommend/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recommend/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcraft/common",
3
- "version": "0.0.27",
3
+ "version": "0.0.30",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -81,6 +81,7 @@
81
81
  "scripts": {
82
82
  "dev": "tsc -w",
83
83
  "build": "tsc -p tsconfig.json",
84
+ "typecheck": "tsc -p tsconfig.json --noEmit",
84
85
  "prepublishOnly": "pnpm build",
85
86
  "lint": "eslint .",
86
87
  "test": "vitest run",
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=jwt.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jwt.test.d.ts","sourceRoot":"","sources":["../../src/auth/jwt.test.ts"],"names":[],"mappings":""}
@@ -1,13 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { JwtService } from './jwt.js';
3
- describe('JwtService', () => {
4
- it('sign + verify roundtrip', async () => {
5
- const jwt = new JwtService({ secret: 'test-secret' });
6
- const token = await jwt.sign({ sub: 'u1', role: 'admin' }, { subject: 'u1', expiresIn: '1h' });
7
- const payload = await jwt.verify(token);
8
- expect(payload).not.toBeNull();
9
- expect(payload?.sub).toBe('u1');
10
- expect(payload?.role).toBe('admin');
11
- });
12
- });
13
- //# sourceMappingURL=jwt.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jwt.test.js","sourceRoot":"","sources":["../../src/auth/jwt.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/F,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=signature.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"signature.spec.d.ts","sourceRoot":"","sources":["../../src/auth/signature.spec.ts"],"names":[],"mappings":""}
@@ -1,195 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest';
2
- import { generateInternalSignature, verifyInternalSignature, timingSafeEqual, generateSignedHeaders, SIGNATURE_VALIDITY_MS } from './signature';
3
- describe('Signature Utils', () => {
4
- const testSecret = 'test-secret-key-12345';
5
- const testMethod = 'GET';
6
- const testPath = '/api/assets/internal/123';
7
- let testTimestamp;
8
- beforeEach(() => {
9
- testTimestamp = Date.now();
10
- });
11
- describe('generateInternalSignature', () => {
12
- it('should generate a valid signature', () => {
13
- const signature = generateInternalSignature(testMethod, testPath, testTimestamp, testSecret);
14
- expect(signature).toBeDefined();
15
- expect(typeof signature).toBe('string');
16
- expect(signature.length).toBe(64); // SHA256 hex = 64 characters
17
- });
18
- it('should generate consistent signatures for same inputs', () => {
19
- const sig1 = generateInternalSignature(testMethod, testPath, testTimestamp, testSecret);
20
- const sig2 = generateInternalSignature(testMethod, testPath, testTimestamp, testSecret);
21
- expect(sig1).toBe(sig2);
22
- });
23
- it('should generate different signatures for different methods', () => {
24
- const getSig = generateInternalSignature('GET', testPath, testTimestamp, testSecret);
25
- const postSig = generateInternalSignature('POST', testPath, testTimestamp, testSecret);
26
- expect(getSig).not.toBe(postSig);
27
- });
28
- it('should generate different signatures for different paths', () => {
29
- const path1Sig = generateInternalSignature(testMethod, '/api/assets/internal/123', testTimestamp, testSecret);
30
- const path2Sig = generateInternalSignature(testMethod, '/api/scenes/internal/456', testTimestamp, testSecret);
31
- expect(path1Sig).not.toBe(path2Sig);
32
- });
33
- it('should generate different signatures for different timestamps', () => {
34
- const sig1 = generateInternalSignature(testMethod, testPath, testTimestamp, testSecret);
35
- const sig2 = generateInternalSignature(testMethod, testPath, testTimestamp + 1000, testSecret);
36
- expect(sig1).not.toBe(sig2);
37
- });
38
- it('should normalize method to uppercase', () => {
39
- const upperSig = generateInternalSignature('GET', testPath, testTimestamp, testSecret);
40
- const lowerSig = generateInternalSignature('get', testPath, testTimestamp, testSecret);
41
- expect(upperSig).toBe(lowerSig);
42
- });
43
- it('should throw error when missing required parameters', () => {
44
- expect(() => generateInternalSignature('', testPath, testTimestamp, testSecret)).toThrow();
45
- expect(() => generateInternalSignature(testMethod, '', testTimestamp, testSecret)).toThrow();
46
- expect(() => generateInternalSignature(testMethod, testPath, 0, testSecret)).toThrow();
47
- expect(() => generateInternalSignature(testMethod, testPath, testTimestamp, '')).toThrow();
48
- });
49
- });
50
- describe('verifyInternalSignature', () => {
51
- it('should verify valid signature successfully', () => {
52
- const signature = generateInternalSignature(testMethod, testPath, testTimestamp, testSecret);
53
- const result = verifyInternalSignature(testMethod, testPath, testTimestamp, signature, testSecret);
54
- expect(result.valid).toBe(true);
55
- expect(result.error).toBeUndefined();
56
- });
57
- it('should reject invalid signature', () => {
58
- const result = verifyInternalSignature(testMethod, testPath, testTimestamp, 'invalid-signature', testSecret);
59
- expect(result.valid).toBe(false);
60
- expect(result.error).toBe('Signature mismatch');
61
- });
62
- it('should reject expired timestamp', () => {
63
- const oldTimestamp = Date.now() - SIGNATURE_VALIDITY_MS - 1000; // 超过有效期
64
- const signature = generateInternalSignature(testMethod, testPath, oldTimestamp, testSecret);
65
- const result = verifyInternalSignature(testMethod, testPath, oldTimestamp, signature, testSecret);
66
- expect(result.valid).toBe(false);
67
- expect(result.error).toContain('Request expired');
68
- });
69
- it('should reject future timestamp', () => {
70
- const futureTimestamp = Date.now() + 10000; // 未来时间
71
- const signature = generateInternalSignature(testMethod, testPath, futureTimestamp, testSecret);
72
- const result = verifyInternalSignature(testMethod, testPath, futureTimestamp, signature, testSecret);
73
- expect(result.valid).toBe(false);
74
- expect(result.error).toBe('Timestamp is in the future');
75
- });
76
- it('should accept timestamp within validity period', () => {
77
- const recentTimestamp = Date.now() - 60000; // 1 分钟前
78
- const signature = generateInternalSignature(testMethod, testPath, recentTimestamp, testSecret);
79
- const result = verifyInternalSignature(testMethod, testPath, recentTimestamp, signature, testSecret);
80
- expect(result.valid).toBe(true);
81
- });
82
- it('should reject missing parameters', () => {
83
- const signature = generateInternalSignature(testMethod, testPath, testTimestamp, testSecret);
84
- let result = verifyInternalSignature('', testPath, testTimestamp, signature, testSecret);
85
- expect(result.valid).toBe(false);
86
- expect(result.error).toContain('Missing required parameters');
87
- result = verifyInternalSignature(testMethod, '', testTimestamp, signature, testSecret);
88
- expect(result.valid).toBe(false);
89
- result = verifyInternalSignature(testMethod, testPath, testTimestamp, '', testSecret);
90
- expect(result.valid).toBe(false);
91
- result = verifyInternalSignature(testMethod, testPath, testTimestamp, signature, '');
92
- expect(result.valid).toBe(false);
93
- });
94
- it('should reject invalid timestamp format', () => {
95
- const signature = generateInternalSignature(testMethod, testPath, testTimestamp, testSecret);
96
- const result = verifyInternalSignature(testMethod, testPath, NaN, signature, testSecret);
97
- expect(result.valid).toBe(false);
98
- expect(result.error).toBe('Invalid timestamp format');
99
- });
100
- it('should reject signature with wrong method', () => {
101
- const signature = generateInternalSignature('GET', testPath, testTimestamp, testSecret);
102
- const result = verifyInternalSignature('POST', testPath, testTimestamp, signature, testSecret);
103
- expect(result.valid).toBe(false);
104
- expect(result.error).toBe('Signature mismatch');
105
- });
106
- it('should reject signature with wrong path', () => {
107
- const signature = generateInternalSignature(testMethod, '/api/assets/internal/123', testTimestamp, testSecret);
108
- const result = verifyInternalSignature(testMethod, '/api/scenes/internal/456', testTimestamp, signature, testSecret);
109
- expect(result.valid).toBe(false);
110
- expect(result.error).toBe('Signature mismatch');
111
- });
112
- });
113
- describe('timingSafeEqual', () => {
114
- it('should return true for identical strings', () => {
115
- expect(timingSafeEqual('abc123', 'abc123')).toBe(true);
116
- expect(timingSafeEqual('', '')).toBe(true);
117
- });
118
- it('should return false for different strings', () => {
119
- expect(timingSafeEqual('abc123', 'abc124')).toBe(false);
120
- expect(timingSafeEqual('abc', 'def')).toBe(false);
121
- });
122
- it('should return false for strings of different lengths', () => {
123
- expect(timingSafeEqual('abc', 'abcd')).toBe(false);
124
- expect(timingSafeEqual('abcd', 'abc')).toBe(false);
125
- });
126
- it('should return false for non-string inputs', () => {
127
- expect(timingSafeEqual(null, 'abc')).toBe(false);
128
- expect(timingSafeEqual('abc', undefined)).toBe(false);
129
- expect(timingSafeEqual(123, 456)).toBe(false);
130
- });
131
- it('should take constant time regardless of where strings differ', () => {
132
- // 这个测试验证时序安全性的概念
133
- // 实际的时序测试需要更复杂的基准测试
134
- const str1 = 'a'.repeat(100);
135
- const str2Early = 'b' + 'a'.repeat(99); // 第一个字符不同
136
- const str2Late = 'a'.repeat(99) + 'b'; // 最后一个字符不同
137
- expect(timingSafeEqual(str1, str2Early)).toBe(false);
138
- expect(timingSafeEqual(str1, str2Late)).toBe(false);
139
- });
140
- });
141
- describe('generateSignedHeaders', () => {
142
- it('should generate all required headers', () => {
143
- const headers = generateSignedHeaders(testMethod, testPath, testSecret, 'realtime');
144
- expect(headers['X-Internal-Timestamp']).toBeDefined();
145
- expect(headers['X-Internal-Signature']).toBeDefined();
146
- expect(headers['X-Internal-Service']).toBe('realtime');
147
- });
148
- it('should generate valid signature in headers', () => {
149
- const headers = generateSignedHeaders(testMethod, testPath, testSecret, 'realtime');
150
- const timestamp = parseInt(headers['X-Internal-Timestamp'], 10);
151
- const signature = headers['X-Internal-Signature'];
152
- const result = verifyInternalSignature(testMethod, testPath, timestamp, signature, testSecret);
153
- expect(result.valid).toBe(true);
154
- });
155
- it('should generate headers for different services', () => {
156
- const realtimeHeaders = generateSignedHeaders(testMethod, testPath, testSecret, 'realtime');
157
- const messengerHeaders = generateSignedHeaders(testMethod, testPath, testSecret, 'messenger');
158
- expect(realtimeHeaders['X-Internal-Service']).toBe('realtime');
159
- expect(messengerHeaders['X-Internal-Service']).toBe('messenger');
160
- });
161
- it('should generate headers for different HTTP methods', () => {
162
- const getHeaders = generateSignedHeaders('GET', testPath, testSecret, 'realtime');
163
- const postHeaders = generateSignedHeaders('POST', testPath, testSecret, 'realtime');
164
- expect(getHeaders['X-Internal-Signature']).not.toBe(postHeaders['X-Internal-Signature']);
165
- });
166
- });
167
- describe('Integration scenarios', () => {
168
- it('should handle complete request flow', () => {
169
- // 1. 服务生成签名头
170
- const headers = generateSignedHeaders('GET', '/api/assets/internal/123', testSecret, 'realtime');
171
- // 2. Backend 验证签名
172
- const timestamp = parseInt(headers['X-Internal-Timestamp'], 10);
173
- const result = verifyInternalSignature('GET', '/api/assets/internal/123', timestamp, headers['X-Internal-Signature'], testSecret);
174
- expect(result.valid).toBe(true);
175
- });
176
- it('should reject tampered signature', () => {
177
- const headers = generateSignedHeaders('GET', testPath, testSecret, 'realtime');
178
- // 篡改签名
179
- const tamperedSignature = headers['X-Internal-Signature'].replace(/a/g, 'b');
180
- const timestamp = parseInt(headers['X-Internal-Timestamp'], 10);
181
- const result = verifyInternalSignature('GET', testPath, timestamp, tamperedSignature, testSecret);
182
- expect(result.valid).toBe(false);
183
- });
184
- it('should reject replay attack with old timestamp', () => {
185
- // 生成旧的签名
186
- const oldTimestamp = Date.now() - SIGNATURE_VALIDITY_MS - 10000;
187
- const oldSignature = generateInternalSignature('GET', testPath, oldTimestamp, testSecret);
188
- // 尝试重放
189
- const result = verifyInternalSignature('GET', testPath, oldTimestamp, oldSignature, testSecret);
190
- expect(result.valid).toBe(false);
191
- expect(result.error).toContain('Request expired');
192
- });
193
- });
194
- });
195
- //# sourceMappingURL=signature.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"signature.spec.js","sourceRoot":"","sources":["../../src/auth/signature.spec.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=server.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../../src/messenger/server.test.ts"],"names":[],"mappings":""}
@@ -1,66 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { MessengerServer, MessengerMessageType } from './server.js';
3
- describe('MessengerServer', () => {
4
- it('MessengerMessageType has expected keys', () => {
5
- expect(MessengerMessageType.AUTHENTICATE).toBe('authenticate');
6
- expect(MessengerMessageType.PROJECT_WATCH).toBe('project.watch');
7
- expect(MessengerMessageType.SELECTION).toBe('selection');
8
- expect(MessengerMessageType.CHAT_MSG).toBe('chat:msg');
9
- expect(MessengerMessageType.FS).toBe('fs');
10
- });
11
- it('createHealthHandler returns 200 with JSON status for GET /health', () => {
12
- return new Promise((resolve, reject) => {
13
- const server = new MessengerServer({});
14
- const handler = server.createHealthHandler();
15
- const req = { method: 'GET', url: '/health' };
16
- const res = {
17
- statusCode: 0,
18
- setHeader: () => { },
19
- end(body) {
20
- try {
21
- expect(this.statusCode).toBe(200);
22
- const data = JSON.parse(body);
23
- expect(data).toHaveProperty('uptime');
24
- expect(data.connections).toBe(0);
25
- expect(data).toHaveProperty('memory');
26
- expect(data).toHaveProperty('timestamp');
27
- server.close();
28
- resolve();
29
- }
30
- catch (e) {
31
- server.close();
32
- reject(e);
33
- }
34
- },
35
- };
36
- handler(req, res);
37
- });
38
- });
39
- it('createHealthHandler returns 404 for POST /health', () => {
40
- return new Promise((resolve, reject) => {
41
- const server = new MessengerServer({});
42
- const handler = server.createHealthHandler();
43
- const req = { method: 'POST', url: '/health' };
44
- const res = {
45
- statusCode: 0,
46
- end() {
47
- try {
48
- expect(this.statusCode).toBe(404);
49
- server.close();
50
- resolve();
51
- }
52
- catch (e) {
53
- server.close();
54
- reject(e);
55
- }
56
- },
57
- };
58
- handler(req, res);
59
- });
60
- });
61
- it('close() does not throw', () => {
62
- const server = new MessengerServer({});
63
- expect(() => server.close()).not.toThrow();
64
- });
65
- });
66
- //# sourceMappingURL=server.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../src/messenger/server.test.ts"],"names":[],"mappings":"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"}
@@ -1,11 +0,0 @@
1
- export declare class IdConverter {
2
- /**
3
- * 将 UUID 转换为稳定的数字 ID(用于 PlayCanvas 编辑器兼容性)。
4
- *
5
- * 规则:
6
- * - 如果有 externalId 且是纯数字,优先使用 externalId
7
- * - 否则对 uuid 的前 8 个 hex 做哈希取模,得到稳定数字
8
- */
9
- static uuidToNumericId(uuid: string, externalId?: string | null): number;
10
- }
11
- //# sourceMappingURL=converters.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../src/models/converters.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAW;IACtB;;;;;;OAMG;IACH,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;CAiBzE"}
@@ -1,25 +0,0 @@
1
- export class IdConverter {
2
- /**
3
- * 将 UUID 转换为稳定的数字 ID(用于 PlayCanvas 编辑器兼容性)。
4
- *
5
- * 规则:
6
- * - 如果有 externalId 且是纯数字,优先使用 externalId
7
- * - 否则对 uuid 的前 8 个 hex 做哈希取模,得到稳定数字
8
- */
9
- static uuidToNumericId(uuid, externalId) {
10
- if (externalId && /^\d+$/.test(externalId)) {
11
- return parseInt(externalId, 10);
12
- }
13
- const uuidStr = String(uuid);
14
- // 如果传入的本身是短数字字符串,直接当作数字 ID 使用(兼容部分调用链)
15
- if (!uuidStr.includes('-') && /^\d+$/.test(uuidStr) && uuidStr.length < 10) {
16
- const parsed = parseInt(uuidStr, 10);
17
- if (!isNaN(parsed) && parsed > 0)
18
- return parsed;
19
- }
20
- const hash = uuidStr.replace(/-/g, '').substring(0, 8);
21
- const numericId = parseInt(hash, 16) % 9999999;
22
- return numericId > 0 ? numericId : 1000000;
23
- }
24
- }
25
- //# sourceMappingURL=converters.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"converters.js","sourceRoot":"","sources":["../../src/models/converters.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,WAAW;IACtB;;;;;;OAMG;IACH,MAAM,CAAC,eAAe,CAAC,IAAY,EAAE,UAA0B;QAC7D,IAAI,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3C,OAAO,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAClC,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAE7B,uCAAuC;QACvC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC3E,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACrC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC;gBAAE,OAAO,MAAM,CAAC;QAClD,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC;QAC/C,OAAO,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;IAC7C,CAAC;CACF"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=converters.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"converters.test.d.ts","sourceRoot":"","sources":["../../src/models/converters.test.ts"],"names":[],"mappings":""}
@@ -1,18 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { IdConverter } from './converters.js';
3
- describe('IdConverter.uuidToNumericId', () => {
4
- it('prefers numeric externalId', () => {
5
- expect(IdConverter.uuidToNumericId('00000000-0000-0000-0000-000000000000', '123')).toBe(123);
6
- });
7
- it('returns stable numeric id for uuid', () => {
8
- const id1 = IdConverter.uuidToNumericId('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa');
9
- const id2 = IdConverter.uuidToNumericId('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa');
10
- expect(id1).toBe(id2);
11
- expect(typeof id1).toBe('number');
12
- expect(id1).toBeGreaterThan(0);
13
- });
14
- it('accepts short numeric strings', () => {
15
- expect(IdConverter.uuidToNumericId('999')).toBe(999);
16
- });
17
- });
18
- //# sourceMappingURL=converters.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"converters.test.js","sourceRoot":"","sources":["../../src/models/converters.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,GAAG,GAAG,WAAW,CAAC,eAAe,CAAC,sCAAsC,CAAC,CAAC;QAChF,MAAM,GAAG,GAAG,WAAW,CAAC,eAAe,CAAC,sCAAsC,CAAC,CAAC;QAChF,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=scene.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scene.test.d.ts","sourceRoot":"","sources":["../../src/models/scene.test.ts"],"names":[],"mappings":""}
@@ -1,12 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { SceneModel } from './scene.js';
3
- describe('SceneModel.getDefaultData', () => {
4
- it('creates minimal runnable scene data', () => {
5
- const data = SceneModel.getDefaultData('1');
6
- expect(data).toHaveProperty('settings');
7
- expect(data).toHaveProperty('entities');
8
- expect(data.entities).toHaveProperty('root');
9
- expect(data.entities.root).toHaveProperty('components');
10
- });
11
- });
12
- //# sourceMappingURL=scene.test.js.map