@things-factory/figure-ui 10.1.8 → 10.1.10

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/figure-ui",
3
- "version": "10.1.8",
3
+ "version": "10.1.10",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "@things-factory:registry": "https://registry.npmjs.org"
@@ -37,8 +37,8 @@
37
37
  "@operato/shell": "^10.0.0",
38
38
  "@operato/styles": "^10.0.0",
39
39
  "@operato/utils": "^10.0.0",
40
- "@things-factory/figure-service": "^10.1.8",
40
+ "@things-factory/figure-service": "^10.1.9",
41
41
  "three": "^0.185.1"
42
42
  },
43
- "gitHead": "c402982e29aab3b49e56bea4e41948be6a749c7f"
43
+ "gitHead": "6f3e8480be33889220db17e9f1f4857c62b261b5"
44
44
  }
@@ -138,6 +138,14 @@ test('모델러 AI 입구는 후보만 알리고, 팔레트·그림·현재 정
138
138
  assert.match(source, /this\.failure = \(err as Error\)\.message/)
139
139
  })
140
140
 
141
+ test('그림이 붙은 AI 요청은 JSON이 아니라 GraphQL multipart Upload 링크를 탄다', () => {
142
+ const path = fileURLToPath(new URL('../client/graphql/index.ts', import.meta.url))
143
+ const source = readFileSync(path, 'utf8')
144
+ const propose = source.slice(source.indexOf('export async function proposeFigure'), source.indexOf('/**\n * 발행한다'))
145
+
146
+ assert.match(propose, /context: \{ hasUpload: !!request\.image \}/)
147
+ })
148
+
141
149
  test('모델러의 수락·거절 피드백은 다음 인라인 후보 요청에도 같은 Figure 세션에서만 전달한다', () => {
142
150
  const path = fileURLToPath(new URL('../client/pages/figure-modeller-page.ts', import.meta.url))
143
151
  const source = readFileSync(path, 'utf8')
@@ -167,3 +175,29 @@ test('발행 게이트 수정안은 원본을 바꾸지 않고 후보로만 연
167
175
  assert.match(modeller, /private take\(\)[\s\S]*applyProposal\(this\.folded, this\.proposalSession\.source, this\.proposalSession\.picked\)[\s\S]*this\.dirty = true/)
168
176
  assert.match(session, /export function openSizingFix[\s\S]*anchor: \{ \.\.\.\(part\.anchor \?\? \{\}\), \[fix\.axis\]: fix\.to \}/)
169
177
  })
178
+
179
+ test('새 Figure 경로는 MDI에 남아 있는 직전 Figure를 재사용하지 않고 빈 초안을 만든다', () => {
180
+ const path = fileURLToPath(new URL('../client/pages/figure-modeller-page.ts', import.meta.url))
181
+ const source = readFileSync(path, 'utf8')
182
+ const pageUpdated = source.slice(source.indexOf('async pageUpdated'), source.indexOf(' private async load'))
183
+ const startNew = source.slice(source.indexOf(' private startNew()'), source.indexOf(' private rename'))
184
+
185
+ // resourceId가 없다는 것은 명시적으로 「새 Figure」를 뜻한다.
186
+ assert.match(pageUpdated, /if \(!this\.figure\)[\s\S]*this\.startNew\(\)/)
187
+ assert.match(pageUpdated, /if \(this\.figure\.id\)[\s\S]*this\.startNew\(\)/)
188
+ // 새 초안은 저장 식별자·선택·기존 부품·진단을 모두 초기화한다.
189
+ assert.match(startNew, /this\.figure = \{ id: '', type: draftType, name: '' \}/)
190
+ assert.match(startNew, /const \{ board, parts \} = startingModel\(draftType\)/)
191
+ assert.match(startNew, /this\.selected = -1/)
192
+ assert.match(startNew, /this\.dirty = true/)
193
+ assert.match(startNew, /this\.violations = \[\]/)
194
+ })
195
+
196
+ test('빈 새 Figure는 캔버스의 직전 씬을 폐기하고 안내 상태로 전환한다', () => {
197
+ const path = fileURLToPath(new URL('../client/modeller/figure-canvas.ts', import.meta.url))
198
+ const source = readFileSync(path, 'utf8')
199
+ const standUp = source.slice(source.indexOf(' private standUp()'), source.indexOf(' /**\n * 지금 판 위에'))
200
+
201
+ assert.match(standUp, /if \(!board\) \{[\s\S]*this\.teardown\(\)/)
202
+ assert.match(standUp, /if \(this\.parts\.length === 0\) \{[\s\S]*this\.teardown\(\)[\s\S]*canvas-appears-once-a-part-exists/)
203
+ })