@simplysm/sd-claude 14.0.89 → 14.0.90
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/claude/references/sd-simplysm14/README.md +16 -17
- package/claude/references/sd-simplysm14/apis/angular/README.md +52 -30
- package/claude/references/sd-simplysm14/apis/angular/controls.md +200 -38
- package/claude/references/sd-simplysm14/apis/angular/crud.md +41 -53
- package/claude/references/sd-simplysm14/apis/angular/directives.md +66 -22
- package/claude/references/sd-simplysm14/apis/angular/features.md +127 -40
- package/claude/references/sd-simplysm14/apis/angular/infra.md +60 -43
- package/claude/references/sd-simplysm14/apis/angular/layout.md +56 -20
- package/claude/references/sd-simplysm14/apis/angular/overlay.md +74 -74
- package/claude/references/sd-simplysm14/apis/angular/routing-appstructure.md +50 -40
- package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +55 -15
- package/claude/references/sd-simplysm14/apis/angular/shared-data.md +59 -42
- package/claude/references/sd-simplysm14/apis/angular/sheet.md +77 -62
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +8 -7
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +71 -43
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +22 -14
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +19 -19
- package/claude/references/sd-simplysm14/apis/core-browser/README.md +17 -17
- package/claude/references/sd-simplysm14/apis/core-browser/dom-element.md +28 -28
- package/claude/references/sd-simplysm14/apis/core-browser/indexed-db.md +37 -37
- package/claude/references/sd-simplysm14/apis/core-common/README.md +87 -219
- package/claude/references/sd-simplysm14/apis/core-common/array-ext.md +54 -98
- package/claude/references/sd-simplysm14/apis/core-common/async-runtime.md +57 -99
- package/claude/references/sd-simplysm14/apis/core-common/datetime.md +60 -103
- package/claude/references/sd-simplysm14/apis/core-common/errors.md +42 -47
- package/claude/references/sd-simplysm14/apis/core-common/obj.md +42 -88
- package/claude/references/sd-simplysm14/apis/core-common/serialization.md +55 -0
- package/claude/references/sd-simplysm14/apis/core-node/README.md +6 -7
- package/claude/references/sd-simplysm14/apis/core-node/consola.md +17 -12
- package/claude/references/sd-simplysm14/apis/core-node/cpx.md +14 -13
- package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +9 -8
- package/claude/references/sd-simplysm14/apis/core-node/fsx.md +14 -13
- package/claude/references/sd-simplysm14/apis/core-node/pathx.md +4 -8
- package/claude/references/sd-simplysm14/apis/core-node/worker.md +14 -12
- package/claude/references/sd-simplysm14/apis/excel/README.md +22 -22
- package/claude/references/sd-simplysm14/apis/excel/cell.md +37 -29
- package/claude/references/sd-simplysm14/apis/excel/conditional-format.md +29 -15
- package/claude/references/sd-simplysm14/apis/excel/style.md +33 -27
- package/claude/references/sd-simplysm14/apis/excel/utils.md +29 -19
- package/claude/references/sd-simplysm14/apis/excel/workbook-worksheet.md +78 -55
- package/claude/references/sd-simplysm14/apis/excel/wrapper.md +42 -45
- package/claude/references/sd-simplysm14/apis/orm-common/README.md +6 -8
- package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +118 -67
- package/claude/references/sd-simplysm14/apis/orm-common/expr.md +83 -86
- package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +102 -93
- package/claude/references/sd-simplysm14/apis/orm-common/schema.md +138 -81
- package/claude/references/sd-simplysm14/apis/orm-common/types.md +49 -44
- package/claude/references/sd-simplysm14/apis/orm-node/README.md +42 -42
- package/claude/references/sd-simplysm14/apis/orm-node/db-conn.md +44 -33
- package/claude/references/sd-simplysm14/apis/sd-cli/README.md +11 -10
- package/claude/references/sd-simplysm14/apis/service-client/README.md +56 -52
- package/claude/references/sd-simplysm14/apis/service-client/orm.md +33 -28
- package/claude/references/sd-simplysm14/apis/service-client/transport.md +23 -21
- package/claude/references/sd-simplysm14/apis/service-common/README.md +83 -48
- package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +126 -34
- package/claude/references/sd-simplysm14/apis/service-common/protocol.md +109 -54
- package/claude/references/sd-simplysm14/apis/service-server/README.md +69 -81
- package/claude/references/sd-simplysm14/apis/service-server/service-authoring.md +46 -43
- package/claude/references/sd-simplysm14/apis/service-server/transport-internals.md +63 -37
- package/claude/references/sd-simplysm14/apis/service-server/v1-legacy.md +40 -30
- package/claude/references/sd-simplysm14/apis/storage/README.md +17 -17
- package/claude/references/sd-simplysm14/manuals/client-app-structure.md +142 -140
- package/claude/references/sd-simplysm14/manuals/client-orm.md +1 -1
- package/claude/references/sd-simplysm14/manuals/client-service.md +19 -7
- package/claude/references/sd-simplysm14/manuals/client-shared-data.md +2 -2
- package/claude/references/sd-simplysm14/manuals/client-system-log.md +11 -3
- package/claude/references/sd-simplysm14/manuals/data-log.md +0 -1
- package/claude/references/sd-simplysm14/manuals/orm.md +16 -0
- package/claude/rules/sd-design-rules.md +10 -0
- package/claude/skills/sd-demo/SKILL.md +0 -6
- package/claude/skills/sd-docs/SKILL.md +58 -0
- package/claude/{workflows/sd-docs.rules.md → skills/sd-docs/references/subagent-prompt.md} +103 -103
- package/claude/skills/sd-impl/SKILL.md +7 -4
- package/claude/skills/sd-spec/SKILL.md +842 -15
- package/claude/skills/sd-spec/references/example-spec.md +26 -36
- package/package.json +1 -1
- package/claude/references/sd-simplysm14/apis/core-common/json-transfer.md +0 -53
- package/claude/skills/sd-spec/references/spec-authoring.md +0 -519
- package/claude/workflows/sd-docs.js +0 -84
|
@@ -1,73 +1,88 @@
|
|
|
1
1
|
# @simplysm/angular — 시트 (sd-sheet)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## SdSheet<TItem>
|
|
6
|
-
|
|
7
|
-
`<sd-sheet [items]="..." [trackByFn]="...">`.
|
|
8
|
-
|
|
9
|
-
### Inputs
|
|
10
|
-
- key?: string — 지정 시 컬럼 폭/순서/숨김/고정 상태를 `SdSystemConfigProvider` 에 영속하고 설정 버튼(톱니) 노출. 사용자 컬럼 커스터마이즈를 저장하려면 지정.
|
|
11
|
-
- items: TItem[] — 표시 데이터(기본 []).
|
|
12
|
-
- trackByFn: (item, index) => unknown — 행 식별 키. 선택키도 이 값 기준. 기본 `(item) => item`.
|
|
13
|
-
- selectMode?: "single"|"multi" — 행 선택 모드. 미지정 시 선택 비활성. single=단일 행, multi=다중 + 헤더 전체선택 체크박스.
|
|
14
|
-
- autoSelect?: "click"|"focus" — 행 자동 선택 트리거. "click"=행 클릭 시 선택, "focus"=셀 포커스 이동만으로 선택. 키보드 위주면 "focus".
|
|
15
|
-
- getItemSelectableFn?: (item) => boolean | string — 행 선택 가능 여부. string 반환 시 그 사유로 선택 불가.
|
|
16
|
-
- getChildrenFn?: (item, index) => TItem[] | undefined — 트리 자식. 지정 시 확장(▶) 토글 표시.
|
|
17
|
-
- useAutoSort: boolean — 클라이언트 정렬. true 면 sorts 변경 시 sd-sheet 가 items 를 직접 정렬. 서버측 정렬/페이징이면 false 로 두고 외부에서 items 재조회.
|
|
18
|
-
- visiblePageCount: number — 페이지네이션 한 그룹 표시 수(기본 10).
|
|
19
|
-
- totalPageCount: number — 서버측 페이징 시 전체 페이지 수.
|
|
20
|
-
- itemsPerPage: number — >0 이면 클라이언트 페이징(페이지당 행 수).
|
|
21
|
-
- focusMode: "row"|"cell" — 키보드 포커스 단위(기본 cell). "row"=행 전체 이동, "cell"=셀 단위 이동(셀 편집·복사 화면이면 cell).
|
|
22
|
-
- inset: boolean — 테두리 제거(컨테이너 내부 삽입).
|
|
23
|
-
- contentStyle?: string — 스크롤 영역 인라인 스타일.
|
|
24
|
-
- getItemCellClassFn?/getItemCellStyleFn?: (item, colKey) => ... — 셀별 클래스/스타일 동적 지정.
|
|
25
|
-
- hideConfigBar: boolean — 상단 도구 바(설정·페이지네이션) 숨김.
|
|
26
|
-
- columnControlsInput: readonly SdSheetColumn[] — 템플릿이 아닌 코드로 컬럼을 넘길 때(투영 `sd-sheet-column` 과 합쳐짐).
|
|
27
|
-
|
|
28
|
-
### Outputs / Models
|
|
29
|
-
- (output) itemKeydown: `SdSheetItemKeydownEventParam<TItem>` = `{ item; event: KeyboardEvent }` — 행에서 키 입력.
|
|
30
|
-
- (output) cellKeydown: `SdSheetCellKeydownEventParam<TItem>` = `{ item; key: string; event }` — 셀에서 키 입력(key=컬럼 key).
|
|
31
|
-
- (model) selectedKeys: unknown[] — 선택된 행 키 배열(trackByFn 값).
|
|
32
|
-
- (model) expandedItems: TItem[] — 확장된 트리 행.
|
|
33
|
-
- (model) sorts: SortingDef[] — 정렬 상태(`{ key; desc }[]`, 헤더 클릭으로 토글, selection-managers.md 참조).
|
|
34
|
-
- (model) currentPage: number — 현재 페이지(0 기반).
|
|
35
|
-
|
|
36
|
-
## SdSheetColumn<T>
|
|
37
|
-
|
|
38
|
-
`<sd-sheet-column [key]="...">` 디렉티브. 컬럼 1개 정의.
|
|
39
|
-
- key: input.required<string> — 컬럼 식별·정렬/설정 키.
|
|
40
|
-
- header: string | string[] — 헤더 텍스트(배열이면 다단 헤더 그룹).
|
|
41
|
-
- headerStyle?: string — 헤더 셀 스타일.
|
|
42
|
-
- tooltip?: string — 헤더 툴팁.
|
|
43
|
-
- width?: string — 컬럼 폭.
|
|
44
|
-
- fixed: boolean — 좌측 고정 컬럼.
|
|
45
|
-
- hidden: boolean — 숨김.
|
|
46
|
-
- collapse: boolean — 접힘(폭 축소).
|
|
47
|
-
- disableSorting: boolean — 정렬 비활성.
|
|
48
|
-
- disableResizing: boolean — 폭 조절 비활성.
|
|
49
|
-
- ordering: number — 컬럼 정렬 순서(기본 0).
|
|
50
|
-
- (contentChild) cellTplRef: `ng-template[cell]` 필수 — 셀 본문. headerTpl/summaryTpl 템플릿으로 커스텀 헤더·요약 행.
|
|
51
|
-
|
|
52
|
-
## SdSheetColumnCellTemplate<T>
|
|
53
|
-
|
|
54
|
-
`<ng-template cell let-item="item" ...>` 디렉티브. 컬럼 셀 본문 템플릿 규약. 컨텍스트 `SdSheetCellContext<T>` = `{ $implicit; item; index; depth; edit }`(edit=현재 셀 편집모드 여부). `cell = input.required<T[]>()` 로 항목 배열 타입 추론.
|
|
3
|
+
다건 목록·편집 표(그리드). 컬럼 디렉티브 + 셀 템플릿으로 구성하며, 선택·정렬·페이지·트리펼침·셀 편집·컬럼 고정/리사이즈/설정저장을 내장. `sd-crud-list` 는 이 시트를 감싼 표준 골격(crud.md). 셀 본문·정렬·폭 규약은 client-component.md "시트 컬럼·셀 표준" 을 따름.
|
|
55
4
|
|
|
5
|
+
## SdSheet<TItem> (`sd-sheet`)
|
|
6
|
+
|
|
7
|
+
### 입력
|
|
8
|
+
|
|
9
|
+
- `key: string` — 시트 설정(컬럼 폭/숨김/고정/순서) 저장 키. 지정하면 설정 버튼 + `SdSystemConfigProvider` 영속·복원. 없으면 설정 비활성.
|
|
10
|
+
- `items: TItem[]` — 표시할 행 데이터.
|
|
11
|
+
- `trackByFn: (item, index) => unknown` — 행 추적/선택 키 함수(기본 item 자체). 선택은 이 반환값을 키로 사용.
|
|
12
|
+
- `selectMode: "single"|"multi"` — 선택 모드. 미지정이면 선택 비활성. single 은 행 화살표, multi 는 체크박스(전체선택 헤더).
|
|
13
|
+
- `autoSelect: "click"|"focus"` — 자동 선택 트리거. `"click"` = 행/셀 클릭 시 선택, `"focus"` = 셀 포커스 이동만으로 선택. 키보드 위주 화면이면 `"focus"`.
|
|
14
|
+
- `getItemSelectableFn: (item) => boolean | string` — 행 선택 가능 여부. `false`/문자열(사유) 면 선택 불가(문자열은 툴팁으로 표시).
|
|
15
|
+
- `getChildrenFn: (item, index) => TItem[] | undefined` — 트리 자식 함수. 지정 시 펼침 기능 활성(들여쓰기 + 토글).
|
|
16
|
+
- `useAutoSort: boolean` — 클라이언트 정렬. true 면 `sorts` 변경 시 시트가 직접 `items` 정렬. 서버 페이징/정렬이면 false(외부에서 재조회). `sd-crud-list` 는 `totalPageCount===0` 일 때만 true.
|
|
17
|
+
- `totalPageCount: number` — 서버 페이징 총 페이지 수. >0 이면 서버 페이징 모드(시트는 slice 안 함).
|
|
18
|
+
- `itemsPerPage: number` — 클라이언트 페이징 페이지당 행 수. >0 이면 시트가 직접 slice. `totalPageCount` 와 택일.
|
|
19
|
+
- `visiblePageCount: number` — 페이지네이터 표시 번호 개수(기본 10).
|
|
20
|
+
- `focusMode: "row"|"cell"` — 키보드 포커스 단위. `"cell"`(기본) = 셀 단위 이동·셀 포커스 표시, `"row"` = 행 단위(셀 표시 없음). 셀 편집/복사 화면이면 `"cell"`.
|
|
21
|
+
- `inset: boolean` — 테두리·radius 제거(컨테이너 내장).
|
|
22
|
+
- `contentStyle: string` — 스크롤 컨테이너 인라인 스타일.
|
|
23
|
+
- `getItemCellClassFn: (item, colKey) => string` / `getItemCellStyleFn: (item, colKey) => string | undefined` — 셀별 클래스/스타일(삭제행 취소선 등).
|
|
24
|
+
- `hideConfigBar: boolean` — 상단 설정/페이지 바 숨김.
|
|
25
|
+
- `columnControlsInput: readonly SdSheetColumn[]` — 템플릿 외부에서 컬럼 디렉티브를 주입(투영 컬럼과 합쳐짐). `sd-crud-list` 가 투영 컬럼을 시트로 전달할 때 사용.
|
|
26
|
+
|
|
27
|
+
### 출력·모델
|
|
28
|
+
|
|
29
|
+
- `selectedKeys: model<unknown[]>` — 선택된 행 키 배열(`trackByFn` 반환값). single 도 배열(길이 0/1).
|
|
30
|
+
- `expandedItems: model<TItem[]>` — 펼쳐진 트리 항목.
|
|
31
|
+
- `sorts: model<SortingDef[]>` — 정렬 상태(`{ key; desc }[]`). 헤더 클릭으로 토글(Shift=다중). `useAutoSort` 면 직접 정렬, 아니면 외부 재조회 트리거.
|
|
32
|
+
- `currentPage: model<number>` — 현재 페이지(0-based).
|
|
33
|
+
- `itemKeydown: output<SdSheetItemKeydownEventParam<TItem>>` — 행에서 키 입력(`{ item; event }`).
|
|
34
|
+
- `cellKeydown: output<SdSheetCellKeydownEventParam<TItem>>` — 셀에서 키 입력(`{ item; key; event }`. key=컬럼 key).
|
|
35
|
+
|
|
36
|
+
### 컬럼·셀
|
|
37
|
+
|
|
38
|
+
#### SdSheetColumn<T> (`sd-sheet-column`)
|
|
39
|
+
|
|
40
|
+
컬럼 정의 디렉티브. `<sd-sheet>`(또는 `sd-crud-list`) 직속 자식으로 둠.
|
|
41
|
+
|
|
42
|
+
- `key: input.required<string>` — 컬럼 식별 키(설정 저장·셀 키).
|
|
43
|
+
- `header: string | string[]` — 헤더 텍스트(배열이면 다단 헤더로 그룹).
|
|
44
|
+
- `headerStyle: string` — 헤더 셀 스타일.
|
|
45
|
+
- `tooltip: string` — 헤더 도움말(? 표시).
|
|
46
|
+
- `width: string` — 컬럼 폭(미지정=자동). px 지정은 명시 지시 시만(client-component.md).
|
|
47
|
+
- `fixed: boolean` — 좌측 고정 컬럼.
|
|
48
|
+
- `hidden: boolean` — 숨김.
|
|
49
|
+
- `collapse: boolean` — 접힘 컬럼.
|
|
50
|
+
- `disableSorting: boolean` — 헤더 클릭 정렬 비활성.
|
|
51
|
+
- `disableResizing: boolean` — 폭 드래그 리사이즈 비활성.
|
|
52
|
+
- `ordering: number` — 컬럼 정렬 순서.
|
|
53
|
+
- 템플릿: `<ng-template [cell]="items()" let-item="item">`(필수, 셀 본문), `#headerTpl`(헤더 커스텀), `#summaryTpl`(요약 행).
|
|
54
|
+
- `SdSheetCellContext<T> = { $implicit; item: T; index: number; depth: number; edit: boolean }` — 셀 컨텍스트. `let-edit="edit"` 로 편집 모드 여부.
|
|
55
|
+
|
|
56
|
+
#### SdSheetColumnCellTemplate<T> (`ng-template[cell]`)
|
|
57
|
+
|
|
58
|
+
셀 본문 템플릿 디렉티브. `cell: input.required<T[]>` 는 타입 추론용 더미(실제 데이터는 시트 `items`). `let-item`/`let-index`/`let-depth`/`let-edit` 컨텍스트 제공.
|
|
59
|
+
|
|
60
|
+
사용:
|
|
56
61
|
```html
|
|
57
|
-
<sd-sheet [items]="
|
|
58
|
-
<sd-sheet-column key="name" header="이름"
|
|
59
|
-
<ng-template cell let-item="item">
|
|
62
|
+
<sd-sheet [items]="items()" [(selectedKeys)]="selectedKeys" selectMode="single" [trackByFn]="trackByFn">
|
|
63
|
+
<sd-sheet-column [key]="'name'" [header]="'이름'">
|
|
64
|
+
<ng-template [cell]="items()" let-item="item">
|
|
65
|
+
<div class="p-xs-sm">{{ item.name }}</div>
|
|
66
|
+
</ng-template>
|
|
60
67
|
</sd-sheet-column>
|
|
61
68
|
</sd-sheet>
|
|
62
69
|
```
|
|
63
70
|
|
|
64
|
-
|
|
71
|
+
#### SdSheetConfigModal (`sd-sheet-config-modal`)
|
|
72
|
+
|
|
73
|
+
컬럼 폭/순서/고정/숨김을 사용자가 조정하는 설정 모달(`SdModalContentDef<SdSheetConfig | undefined>`). `key` 있는 시트의 설정 버튼이 자동으로 띄움 → 직접 호출 불필요.
|
|
74
|
+
|
|
75
|
+
- `sheetKey: input.required<string>` / `controls: input.required<readonly SdSheetColumn[]>` / `config: input.required<SdSheetConfig | undefined>` — 대상 시트 키·컬럼들·현재 설정.
|
|
76
|
+
- `close: output<SdSheetConfig | undefined>` — 변경된 설정(취소 시 undefined).
|
|
77
|
+
|
|
78
|
+
### 타입 (data/sheet/types)
|
|
65
79
|
|
|
66
|
-
|
|
80
|
+
- `SdSheetColumnDef` — 내부 계산된 컬럼 정의(`key/header/headerStyle/tooltip/width/fixed/hidden/collapse/disableSorting/disableResizing/ordering`).
|
|
81
|
+
- `SdSheetHeaderDef` — 헤더 셀 렌더 정의(`text/colspan/rowspan/isLastRow/fixed/colDef/colIndex`).
|
|
82
|
+
- `SdSheetConfig = { columnRecord: Record<string, { width?; hidden?; fixed?; ordering? }> }` — 영속되는 시트 설정.
|
|
83
|
+
- `SdSheetItemKeydownEventParam<T> = { item: T; event: KeyboardEvent }`.
|
|
84
|
+
- `SdSheetCellKeydownEventParam<T> = { item: T; key: string; event: KeyboardEvent }`.
|
|
67
85
|
|
|
68
|
-
|
|
86
|
+
### 요약 행
|
|
69
87
|
|
|
70
|
-
|
|
71
|
-
- **SdSheetHeaderDef** — 헤더 셀 레이아웃 정의(`text; colspan; rowspan; isLastRow; fixed; colDef; colIndex`).
|
|
72
|
-
- **SdSheetConfig** — 영속되는 설정(`columnRecord: Record<key, { width?; hidden?; fixed?; ordering? }>`).
|
|
73
|
-
- **SdSheetItemKeydownEventParam<T>** / **SdSheetCellKeydownEventParam<T>** — 위 output 이벤트 형태.
|
|
88
|
+
컬럼 중 하나라도 `#summaryTpl` 을 가지면 헤더 하단에 요약 행이 고정 렌더(warning 배경). 집계 값은 시트가 계산하지 않으므로 화면에서 `computed` 로 만들어 넣음(client-component.md).
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# @simplysm/capacitor-plugin-auto-update
|
|
2
2
|
|
|
3
|
-
Capacitor 앱(Android)에서 APK 설치 인텐트를 실행하고, 서버 또는 외부 저장소의 최신 APK 를 받아 자동 업데이트하는 플러그인. 공개 심볼은 모두 `static` 멤버만 가진 abstract 클래스이거나 타입이라 인스턴스 없이 클래스명으로 직접 호출.
|
|
3
|
+
Capacitor 앱(Android)에서 APK 설치 인텐트를 실행하고, 서버 또는 외부 저장소의 최신 APK 를 받아 자동 업데이트하는 플러그인. 공개 심볼은 모두 `static` 멤버만 가진 abstract 클래스이거나 타입이라 인스턴스 없이 클래스명으로 직접 호출. 비-Android(웹) 환경에서는 `ApkInstallerWeb` 폴백으로 설치는 no-op, 권한은 항상 통과로 동작.
|
|
4
4
|
|
|
5
5
|
## 사용 트리거 인덱스
|
|
6
6
|
|
|
7
|
-
- **AutoUpdate** — 앱 부팅 시 "최신 확인 → 권한 → 다운로드 → 설치 → 앱 멈춤" 까지 한 번에 돌리는 자동 업데이트 오케스트레이터. 서버 기반(`run`) 또는 외부 저장소 기반(`runByExternalStorage`).
|
|
8
|
-
- **ApkInstaller** — APK
|
|
7
|
+
- **AutoUpdate** — 앱 부팅 시 "최신 확인 → 권한 → 다운로드 → 설치 → 앱 멈춤" 까지 한 번에 돌리는 자동 업데이트 오케스트레이터. 서버 기반(`run`) 또는 외부 저장소 기반(`runByExternalStorage`). 부트스트랩에서 1회 호출.
|
|
8
|
+
- **ApkInstaller** — APK 설치/권한 확인·요청/현재 버전 조회를 직접 호출하는 저수준 정적 클래스. 자동 업데이트 흐름을 직접 짜거나 단건 설치·권한 처리만 필요할 때.
|
|
9
9
|
- **ApkInstallerPlugin / VersionInfo** — Capacitor 네이티브 브리지 인터페이스 및 버전 정보 타입. 직접 호출보다는 `ApkInstaller` 가 감싸므로 반환 타입 참조·웹 구현체 작성 시 참조용.
|
|
10
10
|
|
|
11
11
|
## AutoUpdate
|
|
@@ -17,14 +17,14 @@ static run(opt: { log: (messageHtml: string) => void; serviceClient: ServiceClie
|
|
|
17
17
|
static runByExternalStorage(opt: { log: (messageHtml: string) => void; dirPath: string }): Promise<void>
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
- log: (messageHtml: string) => void — 진행/오류 상태를 HTML 문자열로 받는 콜백. "최신 버전 확인 중..."
|
|
20
|
+
- log: (messageHtml: string) => void — 진행/오류 상태를 HTML 문자열로 받는 콜백. 매 단계마다 여러 번 호출되며 `"최신 버전 확인 중..."`, `"권한 확인 중..."`, 다운로드 진행률 `(NN.NN%)`, 권한 활성화·재시도 버튼 HTML, 오류 메시지 등이 인자로 들어옴. 부팅 스플래시 등에 그대로 `innerHTML` 로 렌더하는 용도. 버튼 등 인터랙티브 HTML 이 포함되므로 텍스트가 아닌 HTML 로 렌더해야 재시도/다운로드 링크가 동작.
|
|
21
21
|
- serviceClient: ServiceClient (`run` 전용) — `@simplysm/service-client` 의 서비스 클라이언트. 내부에서 `getService<AutoUpdateService>("AutoUpdate").getLastVersion("android")` 로 최신 버전·다운로드 경로를 조회하고, `serviceClient.hostUrl + downloadPath` 로 `fetchUrlBytes` 다운로드. 서버가 버전 정보를 안 주면(`undefined`) 무동작 반환(업데이트 없음). 서버 연동 배포일 때 사용.
|
|
22
|
-
- dirPath: string (`runByExternalStorage` 전용) — 외부 저장소(`FileSystem.getStoragePath("external")`) 기준 상대 디렉토리 경로. 이 폴더의 비-디렉토리 항목 중 확장자가 `.apk` 이고 파일명(확장자 제외)이 `^[0-9.]*$` 인 것을 버전으로 보고 `semver.maxSatisfying(..., "*")` 로 최신을 선정. 서버 없이 USB/SD 등으로 사이드로딩 배포할 때 사용.
|
|
22
|
+
- dirPath: string (`runByExternalStorage` 전용) — 외부 저장소(`FileSystem.getStoragePath("external")`) 기준 상대 디렉토리 경로. 이 폴더의 비-디렉토리 항목 중 확장자가 `.apk` 이고 파일명(확장자 제외)이 `^[0-9.]*$`(숫자·점) 인 것을 버전으로 보고 `semver.maxSatisfying(..., "*")` 로 최신을 선정. 서버 없이 USB/SD 등으로 사이드로딩 배포할 때 사용.
|
|
23
23
|
|
|
24
24
|
동작 차이: `run` 은 다운로드한 바이트를 `appCache` 저장소의 `latest.apk` 로 써서 설치하고, `runByExternalStorage` 는 외부 저장소의 `<dirPath>/<version>.apk` 를 직접 설치 대상으로 삼는다. 두 경로 모두 현재 버전(`ApkInstaller.getVersionInfo().versionName`)과 비교해 `semver.gt(최신, 현재)` 가 아니면(이미 최신·동일·낮음) 반환하고, 어느 한쪽이라도 유효한 semver 가 아니면 업데이트 확인을 건너뛴다.
|
|
25
25
|
|
|
26
26
|
```typescript
|
|
27
|
-
// 앱 부트스트랩에서
|
|
27
|
+
// 앱 부트스트랩에서 (서버 기반)
|
|
28
28
|
await AutoUpdate.run({ log: (h) => (statusEl.innerHTML = h), serviceClient });
|
|
29
29
|
// 또는 오프라인 배포 폴더 기준
|
|
30
30
|
await AutoUpdate.runByExternalStorage({ log: (h) => (statusEl.innerHTML = h), dirPath: "myapp-apks" });
|
|
@@ -45,11 +45,12 @@ static getVersionInfo(): Promise<VersionInfo>
|
|
|
45
45
|
|
|
46
46
|
- checkPermissions() → { granted, manifest } — 설치 권한 상태 조회. granted: boolean = `REQUEST_INSTALL_PACKAGES` 권한이 사용자에게 승인되었는지(false 면 `requestPermissions` 로 유도), manifest: boolean = 해당 권한이 앱 manifest 에 선언되어 있는지(false 면 권한 요청 자체가 불가 → APK 재설치 필요). 설치 전 사전 점검·재시도 폴링에 사용. 웹에서는 둘 다 true.
|
|
47
47
|
- requestPermissions() → void — 설치 권한 요청. Android 에서는 시스템 설정 화면으로 이동시키며 즉시 부여되지 않으므로 이후 `checkPermissions` 폴링으로 승인 여부를 확인해야 함. 웹에서는 동작 없음.
|
|
48
|
-
- install(apkUri: string) → void — APK 설치 인텐트 실행. apkUri 는 로컬 경로가 아니라 `content://` FileProvider URI (보통 `@simplysm/capacitor-plugin-file-system` 의 `FileSystem.getUri(파일경로)` 결과). 웹에서는 미지원 alert 후 반환.
|
|
48
|
+
- install(apkUri: string) → void — APK 설치 인텐트 실행. apkUri 는 로컬 경로가 아니라 `content://` FileProvider URI (보통 `@simplysm/capacitor-plugin-file-system` 의 `FileSystem.getUri(파일경로)` 결과). 내부에서 `{ uri: apkUri }` 로 래핑해 플러그인에 전달. 웹에서는 미지원 alert 후 반환.
|
|
49
49
|
- getVersionInfo() → VersionInfo — 현재 설치된 앱 버전 조회. 서버/외부 버전과 비교할 현재 버전 기준값. 웹 구현은 `versionName` 을 빌드 시 주입된 `env("__VER__")`(없으면 `"0.0.0"`), `versionCode` 를 `"0"` 으로 응답.
|
|
50
50
|
|
|
51
51
|
```typescript
|
|
52
52
|
const { granted, manifest } = await ApkInstaller.checkPermissions();
|
|
53
|
+
if (!manifest) throw new Error("앱을 재설치해야 합니다.");
|
|
53
54
|
if (!granted) await ApkInstaller.requestPermissions();
|
|
54
55
|
await ApkInstaller.install(await FileSystem.getUri(apkFilePath));
|
|
55
56
|
```
|
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
# @simplysm/capacitor-plugin-file-system
|
|
2
2
|
|
|
3
|
-
Capacitor
|
|
3
|
+
Capacitor 네이티브 파일 시스템 접근 플러그인. Android 는 OS 파일 시스템(Android 11+ 는 `MANAGE_EXTERNAL_STORAGE`, 10- 는 `READ/WRITE_EXTERNAL_STORAGE` 권한), 웹은 IndexedDB 기반 가상 파일 시스템으로 동일 API 를 에뮬레이션한다. 권한 확인/요청, 디렉토리 읽기·생성, 파일 읽기·쓰기·삭제, 저장소 경로·파일 URI 조회를 모두 `FileSystem` 정적 메서드로 제공한다.
|
|
4
4
|
|
|
5
5
|
## 사용 트리거 인덱스
|
|
6
6
|
|
|
7
|
-
- **FileSystem** —
|
|
8
|
-
- **StorageType** — `
|
|
9
|
-
- **FileInfo** — `
|
|
10
|
-
- **FileSystemPlugin** — Capacitor
|
|
7
|
+
- **FileSystem** — 앱에서 단말 파일을 읽고 쓰거나 디렉토리·권한을 다룰 때의 진입점. 모든 메서드가 `static async` 이며 인스턴스화 불필요(abstract class). 권한·경로·읽기/쓰기·삭제 전반.
|
|
8
|
+
- **StorageType** — `getStoragePath` 인자. 어느 저장소(외부/앱 전용/캐시 등) 의 기준 경로를 얻을지 고를 때.
|
|
9
|
+
- **FileInfo** — `readdir` 결과 항목 타입. 디렉토리 나열 결과를 순회·필터할 때.
|
|
10
|
+
- **FileSystemPlugin** — 저수준 Capacitor 플러그인 인터페이스(옵션 객체 기반 원형). 보통 직접 쓰지 않고 `FileSystem` 래퍼를 쓰며, 커스텀 네이티브/web 구현이나 옵션·반환 타입 참조가 필요할 때만 사용.
|
|
11
11
|
|
|
12
|
-
## FileSystem
|
|
12
|
+
## FileSystem
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
모든 파일 작업의 진입점. 추상 클래스의 정적 메서드 모음이라 `new` 없이 `FileSystem.메서드()` 로 호출한다. 내부적으로 `registerPlugin<FileSystemPlugin>("FileSystem")` 으로 얻은 네이티브 구현(웹은 `FileSystemWeb`)에 위임하고, 플러그인의 `{ ... }` 래퍼 결과를 평탄화해 반환한다.
|
|
15
15
|
|
|
16
|
-
- `checkPermissions(): Promise<boolean>` — 파일 접근 권한 보유
|
|
17
|
-
- `requestPermissions(): Promise<void>` — 권한 요청. Android 11+ 는 설정 화면으로 이동, Android 10- 는 권한 대화상자 표시. `checkPermissions
|
|
18
|
-
- `readdir(dirPath: string): Promise<FileInfo[]>` — 디렉토리
|
|
19
|
-
- `getStoragePath(type: StorageType): Promise<string>` —
|
|
20
|
-
- `getUri(filePath: string): Promise<string>` — 파일을
|
|
21
|
-
- `writeFile(filePath: string, data: string | Bytes): Promise<void>` — 파일
|
|
22
|
-
- `readFile(filePath: string): Promise<Bytes>` / `readFile(filePath: string, encoding: "utf8"): Promise<string>` — 파일 읽기 오버로드. `encoding` 생략 시 base64 로 읽어 `Bytes`(`bytes.fromBase64`) 반환(바이너리용), `"utf8"` 지정 시 텍스트 `string` 반환. 반환 타입이 오버로드로 갈리므로 바이너리는 인자 없이, 텍스트는 `"utf8"` 명시.
|
|
23
|
-
- `remove(targetPath: string): Promise<void>` —
|
|
24
|
-
- `mkdir(targetPath: string): Promise<void>` — 디렉토리
|
|
25
|
-
- `exists(targetPath: string): Promise<boolean>` — 경로 존재 여부 확인. true
|
|
16
|
+
- `static checkPermissions(): Promise<boolean>` — 파일 접근 권한 보유 여부 확인. true = 권한 있음, false = 없음. 웹은 항상 true. 읽기/쓰기 전 게이트로 호출. 플러그인의 `{ granted }` 를 boolean 으로 풀어 반환.
|
|
17
|
+
- `static requestPermissions(): Promise<void>` — 권한 요청. Android 11+ 는 `MANAGE_EXTERNAL_STORAGE` 설정 화면으로 이동, Android 10- 는 권한 대화상자 표시. 웹은 무동작. `checkPermissions` 가 false 일 때 호출.
|
|
18
|
+
- `static readdir(dirPath: string): Promise<FileInfo[]>` — 디렉토리 내 항목 나열. `dirPath` = 나열할 디렉토리 경로. 디렉토리가 없으면 throw. 폴더 내용을 훑을 때. 각 항목은 `FileInfo`(이름·디렉토리 여부).
|
|
19
|
+
- `static getStoragePath(type: StorageType): Promise<string>` — 표준 저장소 위치의 기준 경로 문자열 조회. `type` = 어느 저장소인지(아래 StorageType). 경로를 하드코딩하지 말고 이 메서드로 베이스 경로를 얻어 join. 웹은 `/webfs/<type>` 가상 경로를 반환하며 해당 경로를 자동 생성.
|
|
20
|
+
- `static getUri(filePath: string): Promise<string>` — 파일을 외부에 넘길 수 있는 URI 조회. `filePath` = 대상 파일 경로. Android 는 FileProvider content:// URI(다른 앱 공유·뷰어 인텐트용), 웹은 `URL.createObjectURL` Blob URL 반환. 웹의 Blob URL 은 사용 후 반드시 `URL.revokeObjectURL(uri)` 로 해제(미해제 시 메모리 누수). 파일이 없으면 throw.
|
|
21
|
+
- `static writeFile(filePath: string, data: string | Bytes): Promise<void>` — 파일 쓰기(부모 디렉토리 자동 생성). `filePath` = 대상 경로. `data` = 문자열이면 utf8 인코딩으로, `Bytes`(Uint8Array)면 base64 로 변환해 바이너리 저장(`bytes.toBase64`, cross-realm 안전). 텍스트면 string, 바이너리면 Bytes 를 넘김.
|
|
22
|
+
- `static readFile(filePath: string): Promise<Bytes>` / `static readFile(filePath: string, encoding: "utf8"): Promise<string>` — 파일 읽기 오버로드. `encoding` 생략 시 base64 로 읽어 `Bytes`(`bytes.fromBase64`) 반환(바이너리용), `"utf8"` 지정 시 텍스트 `string` 반환. 반환 타입이 오버로드로 갈리므로 바이너리는 인자 없이, 텍스트는 `"utf8"` 명시. 파일이 없으면 throw.
|
|
23
|
+
- `static remove(targetPath: string): Promise<void>` — 파일/디렉토리 재귀 삭제. `targetPath` = 삭제 대상 경로(디렉토리면 하위 전체 삭제). 실패 시 throw. 정리·덮어쓰기 전 제거 시.
|
|
24
|
+
- `static mkdir(targetPath: string): Promise<void>` — 디렉토리 재귀 생성. `targetPath` = 생성할 디렉토리 경로(중간 상위 경로까지 모두 생성, 이미 있으면 무동작). 쓰기 전 폴더 보장 시. (`writeFile` 은 부모를 자동 생성하므로 빈 디렉토리만 필요할 때 사용)
|
|
25
|
+
- `static exists(targetPath: string): Promise<boolean>` — 경로 존재 여부 확인. true = 파일·디렉토리 존재, false = 없음. 읽기/삭제 전 분기 조건.
|
|
26
|
+
|
|
27
|
+
`data` 의 `Bytes` 는 `@simplysm/core-common` 의 바이트 배열 타입(Uint8Array 계열). 텍스트는 문자열로 그대로 전달, 바이너리는 `Bytes` 로 전달하면 내부에서 base64 왕복 처리한다.
|
|
28
|
+
|
|
29
|
+
사용 예:
|
|
26
30
|
|
|
27
31
|
```ts
|
|
28
32
|
import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
|
|
@@ -35,32 +39,56 @@ await FileSystem.writeFile(`${base}/notes/memo.txt`, "hello"); // utf8
|
|
|
35
39
|
const text = await FileSystem.readFile(`${base}/notes/memo.txt`, "utf8"); // string
|
|
36
40
|
const raw = await FileSystem.readFile(`${base}/notes/memo.txt`); // Bytes
|
|
37
41
|
for (const f of await FileSystem.readdir(`${base}/notes`)) {
|
|
38
|
-
console.log(f.name
|
|
42
|
+
if (!f.isDirectory) console.log(f.name);
|
|
43
|
+
}
|
|
44
|
+
const uri = await FileSystem.getUri(`${base}/notes/memo.txt`); // 웹: 사용 후 URL.revokeObjectURL(uri)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## StorageType
|
|
48
|
+
|
|
49
|
+
`getStoragePath(type)` 가 받는 저장소 유형 리터럴. 직접 경로를 만들지 말고 이 유형으로 플랫폼 표준 위치를 얻는다.
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
type StorageType =
|
|
53
|
+
| "external" | "externalFiles" | "externalCache" | "externalMedia"
|
|
54
|
+
| "appData" | "appFiles" | "appCache";
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- `"external"` — 외부 저장소 루트(`Environment.getExternalStorageDirectory`). 사용자/타 앱과 공유되는 공용 영역 전체에 접근할 때. `MANAGE_EXTERNAL_STORAGE` 권한 필요.
|
|
58
|
+
- `"externalFiles"` — 앱 전용 외부 파일 디렉토리. 앱이 소유하는 외부 영속 파일(앱 제거 시 함께 삭제)을 둘 때.
|
|
59
|
+
- `"externalCache"` — 앱 전용 외부 캐시 디렉토리. 공간 부족 시 OS 가 회수할 수 있는 외부 임시 캐시를 둘 때.
|
|
60
|
+
- `"externalMedia"` — 앱 전용 외부 미디어 디렉토리. 이미지·동영상 등 미디어 산출물을 외부 미디어 영역에 둘 때.
|
|
61
|
+
- `"appData"` — 앱 데이터 디렉토리(내부 저장소). 앱 비공개 데이터 루트가 필요할 때.
|
|
62
|
+
- `"appFiles"` — 앱 파일 디렉토리(내부 저장소). 앱 비공개 영속 파일을 둘 때.
|
|
63
|
+
- `"appCache"` — 앱 캐시 디렉토리(내부 저장소). 재생성 가능한 내부 임시 캐시를 둘 때.
|
|
64
|
+
|
|
65
|
+
웹에서는 각 유형이 `/webfs/<type>` 가상 경로로 매핑되며 호출 시 해당 디렉토리를 자동 생성한다.
|
|
66
|
+
|
|
67
|
+
## FileInfo
|
|
68
|
+
|
|
69
|
+
`readdir` 가 반환하는 디렉토리 항목 1건.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
interface FileInfo {
|
|
73
|
+
name: string;
|
|
74
|
+
isDirectory: boolean;
|
|
39
75
|
}
|
|
40
76
|
```
|
|
41
77
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- `
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
- `
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
- `getStoragePath(options: { type: StorageType }): Promise<{ path: string }>` — `type` 저장소의 실제 경로를 `path` 로 반환.
|
|
60
|
-
- `getUri(options: { path: string }): Promise<{ uri: string }>` — `path` 파일의 FileProvider URI 를 `uri` 로 반환.
|
|
61
|
-
- `writeFile(options: { path: string; data: string; encoding?: "utf8" | "base64" }): Promise<void>` — `data`(문자열)를 `encoding`(`"utf8"`=텍스트 그대로, `"base64"`=base64 문자열을 바이너리로 디코드해 기록, 생략 시 구현 기본)으로 `path` 에 기록.
|
|
62
|
-
- `readFile(options: { path: string; encoding?: "utf8" | "base64" }): Promise<{ data: string }>` — `path` 내용을 `encoding`(`"utf8"`=텍스트, `"base64"`=바이너리를 base64 문자열로 인코딩)으로 읽어 `data` 로 반환. 플러그인 레벨에서 바이너리는 항상 base64 문자열로 주고받음(`FileSystem` 가 `Bytes` ↔ base64 변환 담당).
|
|
63
|
-
- `remove(options: { path: string }): Promise<void>` — `path` 파일/디렉토리 재귀 삭제.
|
|
64
|
-
- `mkdir(options: { path: string }): Promise<void>` — `path` 디렉토리 재귀 생성.
|
|
65
|
-
- `exists(options: { path: string }): Promise<{ exists: boolean }>` — `path` 존재 여부를 `exists` 로 반환.
|
|
66
|
-
- 직접 호출 대신 `FileSystem` 사용 권장. 커스텀 web 구현 작성 시 이 인터페이스를 구현.
|
|
78
|
+
- `name: string` — 항목 이름(경로가 아닌 파일/디렉토리명). 표시·필터·경로 결합 시.
|
|
79
|
+
- `isDirectory: boolean` — 디렉토리 여부. true = 하위 디렉토리(재귀 탐색 대상), false = 파일. 파일만 처리할지 폴더로 내려갈지 분기할 때.
|
|
80
|
+
|
|
81
|
+
## FileSystemPlugin
|
|
82
|
+
|
|
83
|
+
저수준 Capacitor 플러그인 인터페이스. `FileSystem` 정적 메서드가 내부에서 위임하는 원형으로, 메서드가 옵션 객체(`{ path }`, `{ type }`, `{ path, data, encoding }`)를 받고 결과도 래핑 객체(`{ granted }`, `{ files }`, `{ path }`, `{ uri }`, `{ data }`, `{ exists }`)로 반환한다. 보통 직접 호출하지 않으며, 커스텀 web 구현(`FileSystemPlugin` 구현)을 작성하거나 옵션/반환 타입을 참조해야 할 때만 사용한다.
|
|
84
|
+
|
|
85
|
+
- `checkPermissions(): Promise<{ granted: boolean }>` — 권한 보유 여부를 `granted` 로 반환.
|
|
86
|
+
- `requestPermissions(): Promise<void>` — 권한 요청.
|
|
87
|
+
- `readdir(options: { path: string }): Promise<{ files: FileInfo[] }>` — `path` 디렉토리 항목 목록을 `files` 로 반환.
|
|
88
|
+
- `getStoragePath(options: { type: StorageType }): Promise<{ path: string }>` — `type` 저장소의 실제 경로를 `path` 로 반환.
|
|
89
|
+
- `getUri(options: { path: string }): Promise<{ uri: string }>` — `path` 파일의 외부 전달용 `uri` 반환.
|
|
90
|
+
- `writeFile(options: { path: string; data: string; encoding?: "utf8" | "base64" }): Promise<void>` — `path` 에 `data`(문자열) 기록. `encoding` = 입력 데이터 해석 방식. `"utf8"` = 텍스트 그대로, `"base64"` = base64 문자열을 바이너리로 디코드해 기록. 래퍼 `FileSystem.writeFile` 이 문자열은 `"utf8"`, `Bytes` 는 `"base64"` 로 자동 지정.
|
|
91
|
+
- `readFile(options: { path: string; encoding?: "utf8" | "base64" }): Promise<{ data: string }>` — `path` 읽어 `data`(문자열) 반환. `encoding` = 반환 문자열 형식. `"utf8"` = 텍스트, `"base64"` = 바이너리를 base64 문자열로 인코딩. 플러그인 레벨에서 바이너리는 항상 base64 문자열로 주고받고, `FileSystem` 가 `Bytes` ↔ base64 변환을 담당.
|
|
92
|
+
- `remove(options: { path: string }): Promise<void>` — `path` 파일/디렉토리 재귀 삭제.
|
|
93
|
+
- `mkdir(options: { path: string }): Promise<void>` — `path` 디렉토리 재귀 생성.
|
|
94
|
+
- `exists(options: { path: string }): Promise<{ exists: boolean }>` — `path` 존재 여부를 `exists` 로 반환.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# @simplysm/capacitor-plugin-intent
|
|
2
2
|
|
|
3
|
-
Android 인텐트 송수신 Capacitor 플러그인. 브로드캐스트 수신/전송, 실행 인텐트 조회, `startActivityForResult` 외부 Activity 실행·결과 수신을
|
|
3
|
+
Android 인텐트(Intent) 송수신 Capacitor 플러그인. 브로드캐스트 수신/전송, 실행 인텐트 조회, newIntent 이벤트 리스닝, `startActivityForResult` 외부 Activity 실행·결과 수신을 다룸. 산업용 디바이스(바코드 스캐너·PDA 등, 예: Zebra DataWedge) 연동에 사용. 웹 환경(`IntentWeb`)에서는 실제 동작 없이 경고만 로깅하고 무해한 기본값을 반환하므로 실제 인텐트 처리는 Android 네이티브에서만 일어남.
|
|
4
4
|
|
|
5
5
|
## 사용 트리거 인덱스
|
|
6
6
|
|
|
7
|
-
- **Intent** — 인텐트 작업의 정적
|
|
7
|
+
- **Intent** — 인텐트 작업의 정적 진입점(추상 클래스). 브로드캐스트 구독/전송, 실행 인텐트 조회, newIntent 리스너 등록, 외부 Activity 실행을 할 때. 아래 인라인 섹션 참조.
|
|
8
8
|
- **IntentResult / StartActivityForResultOptions / StartActivityForResultResult** — `Intent` 메서드의 입출력 타입. 콜백 결과·실행 옵션·반환값을 타입으로 다룰 때. 아래 인라인 섹션 참조.
|
|
9
9
|
- **IntentPlugin** — `registerPlugin` 에 쓰이는 Capacitor 네이티브 플러그인 계약. 보통 직접 호출하지 않고 `Intent` 정적 메서드를 거치며, 웹 스텁·네이티브 구현의 저수준 계약 확인용. 아래 인라인 섹션 참조.
|
|
10
10
|
|
|
@@ -12,13 +12,21 @@ Android 인텐트 송수신 Capacitor 플러그인. 브로드캐스트 수신/
|
|
|
12
12
|
|
|
13
13
|
`abstract class Intent` — 정적 메서드만 가진 진입점. 인스턴스화하지 않고 `Intent.xxx()` 형태로 호출하며 모든 메서드는 비동기(`Promise`). 내부적으로 `registerPlugin<IntentPlugin>("Intent")` 로 얻은 플러그인(웹은 `IntentWeb`)을 래핑.
|
|
14
14
|
|
|
15
|
-
- `Intent.subscribe(filters: string[], callback: (result: IntentResult) => void): Promise<() => Promise<void>>` — 브로드캐스트 수신기 등록.
|
|
16
|
-
- `
|
|
17
|
-
- `
|
|
15
|
+
- `Intent.subscribe(filters: string[], callback: (result: IntentResult) => void): Promise<() => Promise<void>>` — 브로드캐스트 수신기 등록.
|
|
16
|
+
- `filters: string[]` — 수신할 인텐트 액션 문자열 배열(예: `"com.symbol.datawedge.api.RESULT_ACTION"`). 이 액션들로 들어오는 브로드캐스트만 콜백으로 전달. 스캐너 결과 액션 등 수신 대상 액션을 등록할 때 지정.
|
|
17
|
+
- `callback: (result: IntentResult) => void` — 매칭 브로드캐스트 도착 시마다 호출. 등록 직후 플러그인이 보내는 `{ id }` 만 담긴 초기 resolve(`result.action == null`)는 내부에서 걸러져 호출되지 않음(실제 수신 시점에만 호출).
|
|
18
|
+
- 반환: 구독 해제 함수 `() => Promise<void>`. 호출 시 내부 `id` 로 해당 수신기만 해제. 화면 진입 시 등록하고 이탈 시 반환 함수로 해제.
|
|
19
|
+
- `Intent.unsubscribeAll(): Promise<void>` — 등록된 모든 브로드캐스트 수신기를 한 번에 해제. 개별 해제 함수를 보관하지 않았거나 화면 정리 시 전체를 일괄 정리할 때.
|
|
20
|
+
- `Intent.send(options: { action: string; extras?: Record<string, unknown> }): Promise<void>` — 브로드캐스트 전송.
|
|
21
|
+
- `action: string` — 전송할 인텐트 액션 문자열(필수). 디바이스 API 가 정의한 명령 액션을 지정.
|
|
22
|
+
- `extras?: Record<string, unknown>` — 함께 보낼 추가 키-값 데이터(선택). 명령 파라미터(예: 스캐너 트리거 토글 값)를 담을 때.
|
|
18
23
|
- `Intent.getLaunchIntent(): Promise<IntentResult>` — 앱을 실행시킨 인텐트 조회. 외부 인텐트로 앱이 기동됐는지·그 `extras` 를 앱 시작 시점에 읽을 때. 웹 스텁은 항상 빈 객체 `{}` 반환.
|
|
19
|
-
- `Intent.addListener(eventName: "newIntent", callback: (result: IntentResult) => void): Promise<PluginListenerHandle>` — 앱 실행 중 새로 들어오는 인텐트 리스너 등록.
|
|
20
|
-
- `
|
|
21
|
-
- `
|
|
24
|
+
- `Intent.addListener(eventName: "newIntent", callback: (result: IntentResult) => void): Promise<PluginListenerHandle>` — 앱 실행 중 새로 들어오는 인텐트 리스너 등록.
|
|
25
|
+
- `eventName: "newIntent"` — 리스닝 대상 이벤트(현재 이 리터럴 하나만 지원). 이미 떠 있는 앱에 인텐트가 재전달되는 singleTop 등 상황에서 발생.
|
|
26
|
+
- `callback: (result: IntentResult) => void` — 새 인텐트 수신 시 호출. 들어온 인텐트의 `action`·`extras` 를 받음.
|
|
27
|
+
- 반환: `PluginListenerHandle`(@capacitor/core). `handle.remove()` 로 이 리스너만 개별 해제.
|
|
28
|
+
- `Intent.removeAllListeners(): Promise<void>` — `addListener` 로 등록한 모든 이벤트 리스너를 일괄 제거. subscribe(브로드캐스트 수신기)와는 별개 채널이므로 둘 다 쓰면 각각 정리해야 함.
|
|
29
|
+
- `Intent.startActivityForResult(options: StartActivityForResultOptions): Promise<StartActivityForResultResult>` — 외부 Activity 를 실행하고 결과를 `await` 로 직접 수신. 결제·서명 등 외부 앱에 1회성 작업을 위임하고 응답을 되받아야 할 때. 반환 `resultCode` 로 성공 판정(Android 규약상 `-1` = RESULT_OK, `0` = RESULT_CANCELED). 옵션·결과 필드는 아래 "입출력 타입" 참조.
|
|
22
30
|
|
|
23
31
|
사용 예:
|
|
24
32
|
|
|
@@ -36,26 +44,26 @@ if (res.resultCode === -1) { /* RESULT_OK */ }
|
|
|
36
44
|
await unsub(); // 개별 해제
|
|
37
45
|
```
|
|
38
46
|
|
|
39
|
-
주의: 웹 플랫폼(`IntentWeb`)에서는 `subscribe`·`send`·`startActivityForResult` 가 실제 동작 없이 경고 로그(`createLogger("capacitor:intent")` → `"웹 환경에서는 지원하지 않습니다."`)만 남긴다. 이때 `subscribe` 는 `{ id: "web-stub" }`(콜백 미호출), `getLaunchIntent` 는 `{}
|
|
47
|
+
주의: 웹 플랫폼(`IntentWeb`)에서는 `subscribe`·`send`·`startActivityForResult` 가 실제 동작 없이 경고 로그(`createLogger("capacitor:intent")` → `"웹 환경에서는 지원하지 않습니다."`)만 남긴다. 이때 `subscribe` 는 `{ id: "web-stub" }`(콜백 미호출), `getLaunchIntent` 는 `{}`(경고 없음), `startActivityForResult` 는 `{ resultCode: 0 }`(항상 CANCELED 로 보임)을 반환하고, `unsubscribe`·`unsubscribeAll` 은 무동작. 웹·하이브리드 공용 코드에서 호출해도 예외는 나지 않으나 인텐트 동작은 Android 에서만 발생함을 전제로 작성할 것.
|
|
40
48
|
|
|
41
49
|
## 입출력 타입
|
|
42
50
|
|
|
43
|
-
`Intent` 메서드의 결과·옵션을 타입으로 다룰 때 참조하는 인터페이스.
|
|
51
|
+
`Intent` 메서드의 결과·옵션을 타입으로 다룰 때 참조하는 인터페이스. "값 없음"은 그대로 `undefined` 로 전달되므로 호출부에서 optional 로 다룰 것.
|
|
44
52
|
|
|
45
53
|
- `IntentResult` — `subscribe`·`addListener` 콜백 인자 및 `getLaunchIntent` 반환 타입.
|
|
46
54
|
- `action?: string` — 인텐트(브로드캐스트) 액션 문자열. 미수신/미설정일 수 있어 선택. `subscribe` 콜백에는 이 값이 채워진 실제 이벤트만 전달됨(초기 resolve 구분 기준).
|
|
47
55
|
- `extras?: Record<string, unknown>` — 인텐트에 담긴 추가 키-값 데이터(스캔된 바코드 값 등). 없을 수 있음.
|
|
48
56
|
- `StartActivityForResultOptions` — `startActivityForResult` 입력. 모든 필드 선택이며 대상 인텐트를 암시적(액션·URI·타입) 또는 명시적(패키지·클래스)으로 구성.
|
|
49
|
-
- `action?: string` — 인텐트 액션. 암시적 인텐트로
|
|
57
|
+
- `action?: string` — 인텐트 액션. 암시적 인텐트로 처리 앱을 띄울 때.
|
|
50
58
|
- `uri?: string` — 인텐트 data URI. URI 로 대상(뷰어·다이얼러 등)을 지정할 때.
|
|
51
|
-
- `extras?: Record<string, unknown>` — 대상 Activity 로 전달할 추가 키-값
|
|
59
|
+
- `extras?: Record<string, unknown>` — 대상 Activity 로 전달할 추가 키-값 데이터(호출 파라미터).
|
|
52
60
|
- `type?: string` — MIME 타입. 데이터 형식으로 처리 대상 앱을 좁힐 때.
|
|
53
61
|
- `packageName?: string` — 실행할 특정 앱 패키지명. 명시적 인텐트화(특정 앱으로만 실행)할 때.
|
|
54
62
|
- `className?: string` — 실행할 특정 Activity 클래스명. `packageName` 과 함께 컴포넌트를 직접 지정할 때.
|
|
55
63
|
- `flags?: number` — Android Intent flags 비트값. 실행 모드(새 태스크 시작 등) 제어가 필요할 때.
|
|
56
64
|
- `StartActivityForResultResult` — `startActivityForResult` 반환.
|
|
57
|
-
- `resultCode: number` — Activity 결과
|
|
58
|
-
- `data?: { action?: string; uri?: string; extras?: Record<string, unknown> }` — 결과 인텐트
|
|
65
|
+
- `resultCode: number` — Activity 결과 코드(필수). Android 규약상 `-1` = RESULT_OK, `0` = RESULT_CANCELED. 성공/취소 분기 판단에 사용(웹 스텁은 항상 `0`).
|
|
66
|
+
- `data?: { action?: string; uri?: string; extras?: Record<string, unknown> }` — 결과 인텐트 데이터(선택, 결과 없으면 부재). `action` = 결과 인텐트 액션, `uri` = 결과 data URI, `extras` = 결과 추가 데이터. 결과 본문은 `data?.extras` 형태로 접근.
|
|
59
67
|
|
|
60
68
|
## IntentPlugin
|
|
61
69
|
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
# @simplysm/capacitor-plugin-usb-storage
|
|
2
2
|
|
|
3
|
-
Capacitor 플러그인. 연결된 USB Mass Storage 장치를 열거하고 권한을 얻은 뒤 디렉토리/파일을
|
|
3
|
+
Capacitor 플러그인. 연결된 USB Mass Storage 장치를 열거하고 권한을 얻은 뒤 디렉토리/파일을 읽는다. Android 는 libaums 네이티브 구현, 브라우저는 IndexedDB 기반 가상 USB 저장소로 에뮬레이션된다. entry 가 노출하는 심볼은 정적 클래스 `UsbStorage` 와 입출력 타입 4종.
|
|
4
4
|
|
|
5
5
|
## 사용 트리거 인덱스
|
|
6
6
|
|
|
7
|
-
- **UsbStorage** — USB 장치 접근의 진입점. 장치 목록 조회 → 권한
|
|
8
|
-
- **UsbDeviceInfo / UsbDeviceFilter / UsbFileInfo / UsbStoragePlugin** — 위 메서드의 입출력 타입. 장치 식별(vendorId/productId)
|
|
7
|
+
- **UsbStorage** — USB 저장 장치 접근의 진입점. "장치 목록 조회 → 권한 확인/요청 → readdir/readFile" 흐름을 정적 메서드로 호출할 때.
|
|
8
|
+
- **UsbDeviceInfo / UsbDeviceFilter / UsbFileInfo / UsbStoragePlugin** — 위 메서드의 입출력 타입. 장치 식별(vendorId/productId), 반환 항목(`name`/`isDirectory`) 형태를 다룰 때 참조.
|
|
9
9
|
|
|
10
10
|
## UsbStorage
|
|
11
11
|
|
|
12
|
-
`abstract class` 이며 모든 멤버가 `static
|
|
12
|
+
`abstract class` 이며 모든 멤버가 `static` — 인스턴스화하지 않고 `UsbStorage.메서드()` 로 호출한다. 내부적으로 `registerPlugin<UsbStoragePlugin>("UsbStorage")` 로 얻은 네이티브(Android)/웹 구현에 위임하고, 래퍼 객체(`{ devices }`·`{ granted }`·`{ files }`·`{ data }`)에서 값을 꺼내 평탄화해 반환한다. 대상 장치는 항상 `UsbDeviceFilter`(= `{ vendorId, productId }`) 로 지정하며 readdir/readFile 도 매 호출마다 filter 를 받는다(상태 없음).
|
|
13
13
|
|
|
14
|
-
- `static getDevices(): Promise<UsbDeviceInfo[]>` — 현재 연결된 USB 장치 목록 조회. 권한과 무관하게
|
|
15
|
-
- `static requestPermissions(filter: UsbDeviceFilter): Promise<boolean>` — 지정
|
|
16
|
-
- `static checkPermissions(filter: UsbDeviceFilter): Promise<boolean>` —
|
|
17
|
-
- `static readdir(filter: UsbDeviceFilter, dirPath: string): Promise<UsbFileInfo[]>` — 지정 장치의 `dirPath`(읽을 디렉토리 경로, 루트는 `"/"`) 바로 아래 항목 목록 조회. 각 항목은 `name
|
|
18
|
-
- `static readFile(filter: UsbDeviceFilter, filePath: string): Promise<Bytes | undefined>` — 지정 장치의 `filePath`(읽을 파일 경로) 내용을 `Bytes`(`@simplysm/core-common`) 로 읽음. 파일이 없거나 네이티브가 데이터
|
|
14
|
+
- `static getDevices(): Promise<UsbDeviceInfo[]>` — 현재 연결된 USB 장치 목록 조회. 권한과 무관하게 열거되며, 반환 항목의 `vendorId`/`productId` 를 추려 이후 호출의 filter 로 사용. 흐름의 첫 단계.
|
|
15
|
+
- `static requestPermissions(filter: UsbDeviceFilter): Promise<boolean>` — 지정 장치 접근 권한을 사용자에게 요청(다이얼로그). 반환 true=승인, false=거부(이때 읽기 중단). 권한이 없을 때 읽기 직전 호출. 브라우저 웹 구현은 항상 true 를 반환.
|
|
16
|
+
- `static checkPermissions(filter: UsbDeviceFilter): Promise<boolean>` — 다이얼로그 없이 현재 권한 보유 여부만 확인. true=이미 보유(requestPermissions 생략 가능), false=미보유(요청 필요). 권한이 이미 있을 때 요청을 건너뛰려는 분기 기준. 브라우저 웹 구현은 항상 true 를 반환.
|
|
17
|
+
- `static readdir(filter: UsbDeviceFilter, dirPath: string): Promise<UsbFileInfo[]>` — 지정 장치의 `dirPath`(읽을 디렉토리 경로, 루트는 `"/"`) 바로 아래 항목 목록 조회. 각 항목은 `name`+`isDirectory` 로 파일/폴더 구분. 트리를 순회하려면 `isDirectory === true` 인 항목을 다시 readdir. 웹 구현은 장치가 없거나 대상이 디렉토리가 아니면 빈 배열.
|
|
18
|
+
- `static readFile(filter: UsbDeviceFilter, filePath: string): Promise<Bytes | undefined>` — 지정 장치의 `filePath`(읽을 파일 경로) 내용을 `Bytes`(`@simplysm/core-common`) 로 읽음. 파일이 없거나 네이티브가 데이터 없음(`null`)을 주면 `undefined` 반환 — "빈 파일" 과 "없음" 을 구분하려면 이 `undefined` 를 그대로 검사(`""`·기본값 치환 금지). 내부에서 base64 응답을 `bytes.fromBase64` 로 복원.
|
|
19
19
|
|
|
20
20
|
사용 예:
|
|
21
21
|
|
|
@@ -30,9 +30,9 @@ if (!(await UsbStorage.checkPermissions(filter))) {
|
|
|
30
30
|
if (!(await UsbStorage.requestPermissions(filter))) return; // 거부 시 중단
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
const data = await UsbStorage.readFile(filter, `/${
|
|
33
|
+
for (const entry of await UsbStorage.readdir(filter, "/")) {
|
|
34
|
+
if (entry.isDirectory) continue; // 폴더면 하위 readdir 로 순회
|
|
35
|
+
const data = await UsbStorage.readFile(filter, `/${entry.name}`);
|
|
36
36
|
if (data === undefined) continue; // 파일 없음/데이터 없음
|
|
37
37
|
// data: Bytes 사용
|
|
38
38
|
}
|
|
@@ -40,21 +40,21 @@ for (const e of entries.filter((x) => !x.isDirectory)) {
|
|
|
40
40
|
|
|
41
41
|
## 입출력 타입
|
|
42
42
|
|
|
43
|
-
`UsbStoragePlugin` 은 Capacitor 가 `registerPlugin<UsbStoragePlugin>("UsbStorage")` 로 등록하는 네이티브 측 계약이며, 위 `UsbStorage` 정적 메서드가 이를 1:1 감싸
|
|
43
|
+
`UsbStoragePlugin` 은 Capacitor 가 `registerPlugin<UsbStoragePlugin>("UsbStorage")` 로 등록하는 네이티브 측 계약이며, 위 `UsbStorage` 정적 메서드가 이를 1:1 로 감싸 쓰기 쉬운 형태(배열·boolean·Bytes)로 변환한다. 보통 직접 호출하지 않고 타입 참조용으로만 본다.
|
|
44
44
|
|
|
45
45
|
- `UsbDeviceInfo` — `getDevices()` 가 돌려주는 장치 정보 1건.
|
|
46
46
|
- `deviceName: string` — OS 가 부여한 장치 시스템 이름. 화면 표시·로그용.
|
|
47
|
-
- `manufacturerName: string` — 제조사 이름. 사용자에게 장치를 식별시키거나 동일
|
|
47
|
+
- `manufacturerName: string` — 제조사 이름. 사용자에게 장치를 식별시키거나 동일 제품명을 구분할 때.
|
|
48
48
|
- `productName: string` — 제품 이름. 사용자에게 어떤 장치인지 보여줄 때.
|
|
49
|
-
- `vendorId: number` — USB 벤더 ID. 이후 filter 의 vendorId 로 그대로 사용.
|
|
50
|
-
- `productId: number` — USB 제품 ID. vendorId 와 조합해 장치를 유일하게 지정, 이후 filter 의 productId 로 그대로 사용.
|
|
49
|
+
- `vendorId: number` — USB 벤더 ID. 이후 filter 의 `vendorId` 로 그대로 사용.
|
|
50
|
+
- `productId: number` — USB 제품 ID. `vendorId` 와 조합해 장치를 유일하게 지정, 이후 filter 의 `productId` 로 그대로 사용.
|
|
51
51
|
- `UsbDeviceFilter` — 접근 대상 장치를 지정하는 키. 권한·읽기 메서드 모두 이 형태를 받음. 보통 `UsbDeviceInfo` 에서 두 ID 만 추려 만듦.
|
|
52
52
|
- `vendorId: number` — 대상 장치 벤더 ID. `UsbDeviceInfo.vendorId` 를 그대로 넘김.
|
|
53
53
|
- `productId: number` — 대상 장치 제품 ID. `UsbDeviceInfo.productId` 를 그대로 넘김.
|
|
54
54
|
- `UsbFileInfo` — `readdir()` 가 돌려주는 디렉토리 항목 1건.
|
|
55
|
-
- `name: string` — 파일/폴더 이름(
|
|
56
|
-
- `isDirectory: boolean` — 디렉토리 여부. true 면 폴더(다시 readdir 대상), false 면 파일(readFile 대상). 트리 순회·파일
|
|
57
|
-
- `UsbStoragePlugin` — Capacitor `registerPlugin` 대상 인터페이스. `UsbStorage` 가
|
|
55
|
+
- `name: string` — 파일/폴더 이름(경로가 아닌 단일 세그먼트). readFile/하위 readdir 경로를 만들 때 부모 경로에 이어붙임.
|
|
56
|
+
- `isDirectory: boolean` — 디렉토리 여부. true 면 폴더(다시 readdir 대상), false 면 파일(readFile 대상). 트리 순회·파일 필터링의 분기 기준.
|
|
57
|
+
- `UsbStoragePlugin` — Capacitor `registerPlugin` 대상 인터페이스. `UsbStorage` 가 평탄화하기 전의 원형 시그니처로, 메서드는 옵션 객체 입력 / 래퍼 객체 출력을 가짐.
|
|
58
58
|
- `getDevices(): Promise<{ devices: UsbDeviceInfo[] }>` — 장치 목록을 `devices` 키로 반환.
|
|
59
59
|
- `requestPermissions(options: UsbDeviceFilter): Promise<{ granted: boolean }>` — 권한 요청 결과를 `granted` 로 반환.
|
|
60
60
|
- `checkPermissions(options: UsbDeviceFilter): Promise<{ granted: boolean }>` — 권한 보유 여부를 `granted` 로 반환.
|