@nexia/sdk 0.8.8 → 0.8.9

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/README.md CHANGED
@@ -8,6 +8,35 @@ Report SDK, setup, CLI, Docker, AI-tool and sandbox problems in the [central dev
8
8
 
9
9
  SDK·개발환경·CLI·Docker·AI 도구·샌드박스 문제는 [통합 이슈 창구](https://github.com/nexia-cloud-os/developer-support/issues)에 신고하세요. 기존 이슈를 먼저 검색하고 패키지 버전과 최소 재현 단계를 포함하세요. 인증 정보, 비공개 Core 소스와 고객 데이터는 첨부하지 마세요.
10
10
 
11
+ ## Standalone App frontend tests
12
+
13
+ Run Vitest in the App repository with `environment: 'jsdom'`, its own setup file,
14
+ and the App's React dependencies. Install `@testing-library/react`,
15
+ `@testing-library/jest-dom`, `jsdom`, `i18next`, `msw`, and `vitest` as App test
16
+ dependencies. No Core checkout or Core test setup is required.
17
+
18
+ The existing `configureNexiaAppFrontendHost` API accepts a complete explicit host
19
+ fixture. `configureNexiaAppFrontendTestHost` connects the suite's i18n and MSW
20
+ instances to `appTestI18n` and `appTestServer`.
21
+
22
+ Configure explicit host capabilities through the existing public API in the
23
+ suite's setup file. Supply a real axios instance and explicit public component,
24
+ hook, runtime, and registry fixtures for the capabilities exercised by that suite.
25
+ Missing capabilities should throw instead of supplying automatic UI or permission
26
+ substitutes. No new SDK API or SDK release is needed.
27
+
28
+ Connect the suite's own i18n and MSW instances with
29
+ `configureNexiaAppFrontendTestHost({ i18n, server })`. Register
30
+ `server.listen({ onUnhandledRequest: 'error' })` in Vitest `beforeAll`, run React
31
+ Testing Library `cleanup()` and `server.resetHandlers()` in `afterEach`, and call
32
+ `server.close()` in `afterAll`. Use one installed SDK instance throughout the
33
+ suite so its main and `/testing` exports share the same configured host.
34
+
35
+ App fixtures can verify App branching, validation, and request payloads. A DOM
36
+ substitute for a host component does not verify that component's accessibility,
37
+ keyboard behavior, or production rendering; those checks belong to its host.
38
+ Reconfigure mutable fixtures per test to avoid state leaking between cases.
39
+
11
40
  ## Standalone App styles
12
41
 
13
42
  `nexiaAppConfig(import.meta.url)` generates Tailwind utilities from the App resources, including lazy screens, and records emitted CSS in `nexia-host.json`. The build references the shared `@nexia/sdk/theme.css` token aliases; Core supplies token values and resets. Keep those aliases aligned with the Core theme contract. Do not bundle a second preflight or global theme.
@@ -0,0 +1,17 @@
1
+ ---
2
+ status: published
3
+ version: 0.8.9
4
+ date: 2026-10-16
5
+ title: App frontend compatibility metadata
6
+ description: App frontend compatibility metadata
7
+ ---
8
+
9
+ # App frontend compatibility metadata
10
+
11
+ The standalone App build records its declared `@nexia/sdk` range, the SDK used to build it, and the shared host exports imported by the generated JavaScript. Platforms supporting this metadata can check compatibility before changing the host or opening a new App bundle. SDK version ranges do not replace behavioral compatibility tests.
12
+
13
+ Keep the supported SDK range in the App's `package.json` `peerDependencies` or `dependencies` and retain the dependency lock. Peer requirements take precedence when both are present. Rebuild with this SDK to include the metadata; the metadata alone does not require a new App version or change existing published bundles.
14
+
15
+ Apps without an explicit SDK requirement still build with their existing frontend manifest. Their host compatibility remains unknown and must be verified before a platform update. No automatic App upgrade is introduced.
16
+
17
+ Standalone builds warn when emitted JavaScript uses the deprecated `allowsManualAppFallback` or `isRetryableHandoffFailure` aliases. Replace them with `permitsManualFallback` or `isRetryableFailure`, respectively. No removal version is scheduled. This import check does not inspect erased TypeScript types or PHP annotations.
@@ -0,0 +1,17 @@
1
+ ---
2
+ status: published
3
+ version: 0.8.9
4
+ date: 2026-10-16
5
+ title: 앱 프런트엔드 호환성 메타데이터
6
+ description: 앱 프런트엔드 호환성 메타데이터
7
+ ---
8
+
9
+ # 앱 프런트엔드 호환성 정보
10
+
11
+ 독립 앱 빌드에 선언된 `@nexia/sdk` 지원 범위, 빌드에 사용한 SDK 버전, 생성된 JavaScript가 가져오는 공용 호스트 export 목록이 기록됩니다. 이 정보를 지원하는 플랫폼은 호스트를 바꾸거나 새 앱 번들을 열기 전에 호환성을 확인할 수 있습니다. SDK 버전 범위만으로 실제 동작의 호환성 검증을 대신할 수는 없습니다.
12
+
13
+ 앱 `package.json`의 `peerDependencies` 또는 `dependencies`에 지원 SDK 범위를 유지하고 의존성 잠금 파일을 보관하세요. 두 곳에 모두 있으면 peer 요구사항을 우선합니다. 이번 SDK로 다시 빌드하면 정보가 포함되며, 정보 추가만으로 앱 버전을 올릴 필요는 없습니다. 이미 게시된 번들은 바뀌지 않습니다.
14
+
15
+ 명시적인 SDK 요구사항이 없는 앱도 기존 프런트엔드 manifest 형식으로 빌드됩니다. 다만 호스트 호환성이 확인된 것은 아니므로 플랫폼 업데이트 전에 별도 검증이 필요합니다. 앱을 자동으로 업그레이드하지 않습니다.
16
+
17
+ 독립 빌드의 JavaScript에서 deprecated 별칭인 `allowsManualAppFallback` 또는 `isRetryableHandoffFailure`를 사용하면 경고합니다. 각각 `permitsManualFallback`, `isRetryableFailure`로 바꾸세요. 제거 버전은 정해지지 않았습니다. 이 import 검사는 컴파일 후 사라지는 TypeScript 타입이나 PHP 주석을 검사하지 않습니다.
package/dist/testing.d.ts CHANGED
@@ -6,7 +6,7 @@ export interface NexiaAppFrontendTestHostBindings {
6
6
  use: (...handlers: unknown[]) => void;
7
7
  };
8
8
  }
9
- /** Core test setup installs its i18n and request-interception harness here. */
9
+ /** App or host test setup installs its own i18n and request-interception harness here. */
10
10
  export declare function configureNexiaAppFrontendTestHost(bindings: NexiaAppFrontendTestHostBindings): void;
11
11
  export declare const appTestI18n: {
12
12
  changeLanguage: (language: string) => unknown;
package/dist/testing.js CHANGED
@@ -1,11 +1,11 @@
1
1
  let activeTestHost = null;
2
- /** Core test setup installs its i18n and request-interception harness here. */
2
+ /** App or host test setup installs its own i18n and request-interception harness here. */
3
3
  export function configureNexiaAppFrontendTestHost(bindings) {
4
4
  activeTestHost = bindings;
5
5
  }
6
6
  function testHost() {
7
7
  if (activeTestHost === null) {
8
- throw new Error('Nexia App frontend test host is not configured. Core test setup must configure it before App specs run.');
8
+ throw new Error('Nexia App frontend test host is not configured. Configure it with the test suite’s own i18n and request-interception fixtures before App specs run.');
9
9
  }
10
10
  return activeTestHost;
11
11
  }
package/dist/vite.mjs CHANGED
@@ -76,10 +76,39 @@ export const { api, openFile, sendUserInvitation, useDataMigrationBackgroundOper
76
76
  },
77
77
  generateBundle: { order: 'post', handler(_options, bundle) {
78
78
  // Standalone App builds expose compatibility before executing their entry.
79
- if (owners.length === 1) this.emitFile({
79
+ if (owners.length !== 1) return;
80
+ let appPackage = {};
81
+ try { appPackage = JSON.parse(readFileSync(path.join(owners[0].root, 'package.json'), 'utf8')); }
82
+ catch (error) { if (error.code !== 'ENOENT') throw error; }
83
+ const required = appPackage.peerDependencies?.['@nexia/sdk'] ?? appPackage.dependencies?.['@nexia/sdk'];
84
+ const sdk = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
85
+ const imports = {};
86
+ for (const chunk of Object.values(bundle)) {
87
+ if (chunk.type !== 'chunk') continue;
88
+ for (const [specifier, bindings] of Object.entries(chunk.importedBindings)) {
89
+ if (!nexiaHostPeers.includes(specifier)) continue;
90
+ imports[specifier] = [...new Set([...(imports[specifier] ?? []), ...bindings])].sort();
91
+ }
92
+ for (const specifier of chunk.dynamicImports) {
93
+ if (nexiaHostPeers.includes(specifier)) imports[specifier] = ['*'];
94
+ }
95
+ }
96
+ // These aliases are explicitly deprecated in index.ts; no removal release is declared.
97
+ const deprecated = { allowsManualAppFallback: 'permitsManualFallback', isRetryableHandoffFailure: 'isRetryableFailure' };
98
+ for (const [name, replacement] of Object.entries(deprecated)) {
99
+ if (imports['@nexia/sdk']?.includes(name)) {
100
+ this.warn(`[NEXIA_SDK_DEPRECATED] ${name}: use ${replacement}. Removal version is not scheduled.`);
101
+ }
102
+ }
103
+ this.emitFile({
80
104
  type: 'asset', fileName: 'nexia-host.json',
81
105
  source: JSON.stringify({ version: 1, development_updates: 1, app_key: owners[0].appKey,
82
- styles: Object.keys(bundle).filter(file => file.endsWith('.css')) }),
106
+ styles: Object.keys(bundle).filter(file => file.endsWith('.css')),
107
+ // Preserve builds that predate explicit host requirements. Their compatibility
108
+ // remains unknown; operators must not infer permission to change the host.
109
+ ...(typeof required === 'string' && required.trim() && required.length <= 256
110
+ ? { compatibility: { schema_version: 1, host_contract: 1,
111
+ sdk: { package: '@nexia/sdk', required, built_with: sdk.version }, imports } } : {}) }),
83
112
  });
84
113
  } },
85
114
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexia/sdk",
3
- "version": "0.8.8",
3
+ "version": "0.8.9",
4
4
  "description": "Frontend contracts for Nexia App Packages",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",