@simplysm/sd-claude 14.0.50 → 14.0.52

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 (318) hide show
  1. package/claude/references/sd-frontend-design.md +10 -9
  2. package/claude/references/sd-simplysm-v14/angular/README.md +497 -0
  3. package/claude/references/sd-simplysm-v14/angular/bootstrap/provide-sd-angular.md +37 -0
  4. package/claude/references/sd-simplysm-v14/angular/bootstrap/sd-angular-config-provider.md +16 -0
  5. package/claude/references/sd-simplysm-v14/angular/directives/sd-command-directive.md +27 -0
  6. package/claude/references/sd-simplysm-v14/angular/directives/sd-events.md +25 -0
  7. package/claude/references/sd-simplysm-v14/angular/directives/sd-intersection-directive.md +36 -0
  8. package/claude/references/sd-simplysm-v14/angular/directives/sd-invalid.md +24 -0
  9. package/claude/references/sd-simplysm-v14/angular/directives/sd-resize-directive.md +42 -0
  10. package/claude/references/sd-simplysm-v14/angular/directives/sd-ripple.md +23 -0
  11. package/claude/references/sd-simplysm-v14/angular/directives/sd-router-link.md +38 -0
  12. package/claude/references/sd-simplysm-v14/angular/directives/sd-show-effect.md +18 -0
  13. package/claude/references/sd-simplysm-v14/angular/directives/sd-typed-template.md +69 -0
  14. package/claude/references/sd-simplysm-v14/angular/features/sd-address-search-modal.md +50 -0
  15. package/claude/references/sd-simplysm-v14/angular/features/sd-permission-table.md +20 -0
  16. package/claude/references/sd-simplysm-v14/angular/features/sd-shared-data-components.md +158 -0
  17. package/claude/references/sd-simplysm-v14/angular/features/sd-tiptap-editor.md +26 -0
  18. package/claude/references/sd-simplysm-v14/angular/pipes/format-pipe.md +41 -0
  19. package/claude/references/sd-simplysm-v14/angular/plugins/sd-global-error-handler.md +23 -0
  20. package/claude/references/sd-simplysm-v14/angular/plugins/sd-option-event-plugin.md +34 -0
  21. package/claude/references/sd-simplysm-v14/angular/provider-types/sd-menu.md +65 -0
  22. package/claude/references/sd-simplysm-v14/angular/provider-types/sd-modal-content-def.md +148 -0
  23. package/claude/references/sd-simplysm-v14/angular/provider-types/sd-toast-content-def.md +73 -0
  24. package/claude/references/sd-simplysm-v14/angular/provider-types/shared-data-base.md +59 -0
  25. package/claude/references/sd-simplysm-v14/angular/providers/sd-activated-modal-provider.md +34 -0
  26. package/claude/references/sd-simplysm-v14/angular/providers/sd-app-structure-provider.md +81 -0
  27. package/claude/references/sd-simplysm-v14/angular/providers/sd-busy-provider.md +18 -0
  28. package/claude/references/sd-simplysm-v14/angular/providers/sd-file-dialog-provider.md +40 -0
  29. package/claude/references/sd-simplysm-v14/angular/providers/sd-local-storage-provider.md +20 -0
  30. package/claude/references/sd-simplysm-v14/angular/providers/sd-modal-provider.md +67 -0
  31. package/claude/references/sd-simplysm-v14/angular/providers/sd-navigate-window-provider.md +18 -0
  32. package/claude/references/sd-simplysm-v14/angular/providers/sd-print-provider.md +25 -0
  33. package/claude/references/sd-simplysm-v14/angular/providers/sd-service-client-factory-provider.md +43 -0
  34. package/claude/references/sd-simplysm-v14/angular/providers/sd-shared-data-provider.md +64 -0
  35. package/claude/references/sd-simplysm-v14/angular/providers/sd-system-config-provider.md +46 -0
  36. package/claude/references/sd-simplysm-v14/angular/providers/sd-system-log-provider.md +18 -0
  37. package/claude/references/sd-simplysm-v14/angular/providers/sd-theme-provider.md +38 -0
  38. package/claude/references/sd-simplysm-v14/angular/providers/sd-toast-provider.md +65 -0
  39. package/claude/references/sd-simplysm-v14/angular/recipes/_common-rules.md +336 -0
  40. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-a-edit-save.md +191 -0
  41. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-b-delete-restore.md +103 -0
  42. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-c-modal-view.md +198 -0
  43. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-d-control-view.md +109 -0
  44. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-e-auxiliary.md +87 -0
  45. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-f-complex-detail.md +202 -0
  46. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail.md +280 -0
  47. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-a-inline-edit.md +386 -0
  48. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-b-selection.md +215 -0
  49. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-c-inline-delete.md +64 -0
  50. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-d-select-modal.md +193 -0
  51. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-e-readonly-modal.md +140 -0
  52. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-f-modal-edit.md +123 -0
  53. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-g-excel.md +145 -0
  54. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list.md +377 -0
  55. package/claude/references/sd-simplysm-v14/angular/recipes/data-select-button.md +368 -0
  56. package/claude/references/sd-simplysm-v14/angular/recipes/page-modal-container.md +238 -0
  57. package/claude/references/sd-simplysm-v14/angular/styling/classes.md +149 -0
  58. package/claude/references/sd-simplysm-v14/angular/styling/mixins.md +100 -0
  59. package/claude/references/sd-simplysm-v14/angular/styling/themes.md +35 -0
  60. package/claude/references/sd-simplysm-v14/angular/styling/variables.md +147 -0
  61. package/claude/references/sd-simplysm-v14/angular/type-utilities/directive-input-signals.md +232 -0
  62. package/claude/references/sd-simplysm-v14/angular/ui-data/sd-list.md +37 -0
  63. package/claude/references/sd-simplysm-v14/angular/ui-data/sd-sheet.md +212 -0
  64. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-additional-button.md +26 -0
  65. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-anchor.md +31 -0
  66. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-button.md +103 -0
  67. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-checkbox-group.md +39 -0
  68. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-checkbox.md +81 -0
  69. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-date-range-picker.md +27 -0
  70. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-form.md +89 -0
  71. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-modal-select-button.md +54 -0
  72. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-numpad.md +26 -0
  73. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-range.md +26 -0
  74. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-select.md +68 -0
  75. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-shared-data-select.md +52 -0
  76. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-state-preset.md +37 -0
  77. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-switch.md +27 -0
  78. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-textarea.md +33 -0
  79. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-textfield.md +145 -0
  80. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-dock-container.md +64 -0
  81. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-dock.md +37 -0
  82. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-gap.md +26 -0
  83. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-kanban-board.md +96 -0
  84. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-kanban-lane.md +34 -0
  85. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-kanban.md +29 -0
  86. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-collapse.md +35 -0
  87. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-pagination.md +26 -0
  88. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-sidebar-container.md +49 -0
  89. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-sidebar-menu.md +22 -0
  90. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-sidebar-user.md +43 -0
  91. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-tab.md +51 -0
  92. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar-container.md +97 -0
  93. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar-menu.md +23 -0
  94. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar-user.md +38 -0
  95. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar.md +30 -0
  96. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-busy-container.md +69 -0
  97. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-confirm-modal.md +30 -0
  98. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-dropdown.md +40 -0
  99. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-modal.md +34 -0
  100. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-prompt-modal.md +30 -0
  101. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-toast.md +35 -0
  102. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-barcode.md +36 -0
  103. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-calendar.md +34 -0
  104. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-echarts.md +32 -0
  105. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-label.md +24 -0
  106. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-note.md +23 -0
  107. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-progress.md +23 -0
  108. package/claude/references/sd-simplysm-v14/angular/utils/inject-routing-signals.md +161 -0
  109. package/claude/references/sd-simplysm-v14/angular/utils/inject-sd-system-config-resource.md +35 -0
  110. package/claude/references/sd-simplysm-v14/angular/utils/mark.md +43 -0
  111. package/claude/references/sd-simplysm-v14/angular/utils/selection-managers.md +96 -0
  112. package/claude/references/sd-simplysm-v14/angular/utils/set-safe-style.md +19 -0
  113. package/claude/references/sd-simplysm-v14/angular/utils/setup-functions.md +93 -0
  114. package/claude/references/sd-simplysm-v14/capacitor-plugin-auto-update/README.md +38 -0
  115. package/claude/references/sd-simplysm-v14/capacitor-plugin-auto-update/apk-installer/apk-installer.md +115 -0
  116. package/claude/references/sd-simplysm-v14/capacitor-plugin-auto-update/auto-update/auto-update.md +113 -0
  117. package/claude/references/sd-simplysm-v14/capacitor-plugin-file-system/README.md +197 -0
  118. package/claude/references/sd-simplysm-v14/capacitor-plugin-intent/README.md +235 -0
  119. package/claude/references/sd-simplysm-v14/capacitor-plugin-usb-storage/README.md +251 -0
  120. package/claude/references/sd-simplysm-v14/core-browser/README.md +52 -0
  121. package/claude/references/sd-simplysm-v14/core-browser/extensions/copy-paste.md +59 -0
  122. package/claude/references/sd-simplysm-v14/core-browser/extensions/element-prototype-extensions.md +137 -0
  123. package/claude/references/sd-simplysm-v14/core-browser/extensions/get-bounds.md +84 -0
  124. package/claude/references/sd-simplysm-v14/core-browser/utils/download-blob.md +59 -0
  125. package/claude/references/sd-simplysm-v14/core-browser/utils/fetch-url-bytes.md +91 -0
  126. package/claude/references/sd-simplysm-v14/core-browser/utils/indexed-db-store.md +131 -0
  127. package/claude/references/sd-simplysm-v14/core-browser/utils/indexed-db-virtual-fs.md +121 -0
  128. package/claude/references/sd-simplysm-v14/core-browser/utils/open-file-dialog.md +60 -0
  129. package/claude/references/sd-simplysm-v14/core-common/README.md +179 -0
  130. package/claude/references/sd-simplysm-v14/core-common/errors/argument-error.md +26 -0
  131. package/claude/references/sd-simplysm-v14/core-common/errors/not-implemented-error.md +33 -0
  132. package/claude/references/sd-simplysm-v14/core-common/errors/sd-error.md +38 -0
  133. package/claude/references/sd-simplysm-v14/core-common/errors/timeout-error.md +36 -0
  134. package/claude/references/sd-simplysm-v14/core-common/extensions/array.md +125 -0
  135. package/claude/references/sd-simplysm-v14/core-common/extensions/map.md +43 -0
  136. package/claude/references/sd-simplysm-v14/core-common/extensions/set.md +35 -0
  137. package/claude/references/sd-simplysm-v14/core-common/features/debounce-queue.md +48 -0
  138. package/claude/references/sd-simplysm-v14/core-common/features/event-emitter.md +52 -0
  139. package/claude/references/sd-simplysm-v14/core-common/features/serial-queue.md +44 -0
  140. package/claude/references/sd-simplysm-v14/core-common/type-utils/common-types.md +100 -0
  141. package/claude/references/sd-simplysm-v14/core-common/type-utils/env.md +42 -0
  142. package/claude/references/sd-simplysm-v14/core-common/types/date-only.md +86 -0
  143. package/claude/references/sd-simplysm-v14/core-common/types/date-time.md +106 -0
  144. package/claude/references/sd-simplysm-v14/core-common/types/lazy-gc-map.md +59 -0
  145. package/claude/references/sd-simplysm-v14/core-common/types/time.md +62 -0
  146. package/claude/references/sd-simplysm-v14/core-common/types/uuid.md +41 -0
  147. package/claude/references/sd-simplysm-v14/core-common/utils/bytes.md +36 -0
  148. package/claude/references/sd-simplysm-v14/core-common/utils/dt.md +60 -0
  149. package/claude/references/sd-simplysm-v14/core-common/utils/err.md +26 -0
  150. package/claude/references/sd-simplysm-v14/core-common/utils/json.md +58 -0
  151. package/claude/references/sd-simplysm-v14/core-common/utils/num.md +56 -0
  152. package/claude/references/sd-simplysm-v14/core-common/utils/obj.md +107 -0
  153. package/claude/references/sd-simplysm-v14/core-common/utils/path.md +30 -0
  154. package/claude/references/sd-simplysm-v14/core-common/utils/primitive.md +28 -0
  155. package/claude/references/sd-simplysm-v14/core-common/utils/str.md +63 -0
  156. package/claude/references/sd-simplysm-v14/core-common/utils/template-strings.md +49 -0
  157. package/claude/references/sd-simplysm-v14/core-common/utils/transfer.md +35 -0
  158. package/claude/references/sd-simplysm-v14/core-common/utils/wait.md +35 -0
  159. package/claude/references/sd-simplysm-v14/core-common/utils/xml.md +49 -0
  160. package/claude/references/sd-simplysm-v14/core-common/utils/zip-archive.md +77 -0
  161. package/claude/references/sd-simplysm-v14/core-node/README.md +59 -0
  162. package/claude/references/sd-simplysm-v14/core-node/features/fs-watcher.md +110 -0
  163. package/claude/references/sd-simplysm-v14/core-node/logging/create-file-reporter.md +78 -0
  164. package/claude/references/sd-simplysm-v14/core-node/logging/pretty-reporter.md +38 -0
  165. package/claude/references/sd-simplysm-v14/core-node/logging/setup-consola.md +77 -0
  166. package/claude/references/sd-simplysm-v14/core-node/utils/cpx.md +128 -0
  167. package/claude/references/sd-simplysm-v14/core-node/utils/fsx.md +168 -0
  168. package/claude/references/sd-simplysm-v14/core-node/utils/pathx.md +73 -0
  169. package/claude/references/sd-simplysm-v14/core-node/worker/create-worker.md +85 -0
  170. package/claude/references/sd-simplysm-v14/core-node/worker/worker.md +160 -0
  171. package/claude/references/sd-simplysm-v14/excel/README.md +66 -0
  172. package/claude/references/sd-simplysm-v14/excel/core-classes/excel-cell.md +79 -0
  173. package/claude/references/sd-simplysm-v14/excel/core-classes/excel-col.md +36 -0
  174. package/claude/references/sd-simplysm-v14/excel/core-classes/excel-row.md +34 -0
  175. package/claude/references/sd-simplysm-v14/excel/core-classes/excel-workbook.md +93 -0
  176. package/claude/references/sd-simplysm-v14/excel/core-classes/excel-worksheet.md +147 -0
  177. package/claude/references/sd-simplysm-v14/excel/types/excel-address-point.md +33 -0
  178. package/claude/references/sd-simplysm-v14/excel/types/excel-style-options.md +57 -0
  179. package/claude/references/sd-simplysm-v14/excel/types/excel-value-type.md +28 -0
  180. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-content-type-data.md +23 -0
  181. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-drawing-data.md +29 -0
  182. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-relationship-data.md +39 -0
  183. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-shared-string-data.md +42 -0
  184. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-style-data.md +97 -0
  185. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-workbook-data.md +22 -0
  186. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-worksheet-data.md +68 -0
  187. package/claude/references/sd-simplysm-v14/excel/types/excel-xml.md +15 -0
  188. package/claude/references/sd-simplysm-v14/excel/utilities/excel-utils.md +101 -0
  189. package/claude/references/sd-simplysm-v14/excel/wrapper/excel-wrapper.md +108 -0
  190. package/claude/references/sd-simplysm-v14/lint/README.md +183 -0
  191. package/claude/references/sd-simplysm-v14/orm-common/README.md +156 -0
  192. package/claude/references/sd-simplysm-v14/orm-common/core/db-context.md +208 -0
  193. package/claude/references/sd-simplysm-v14/orm-common/core/db-transaction-error.md +64 -0
  194. package/claude/references/sd-simplysm-v14/orm-common/expression/expr-unit.md +62 -0
  195. package/claude/references/sd-simplysm-v14/orm-common/expression/expr.md +198 -0
  196. package/claude/references/sd-simplysm-v14/orm-common/models/migration.md +37 -0
  197. package/claude/references/sd-simplysm-v14/orm-common/query-builder/create-query-builder.md +80 -0
  198. package/claude/references/sd-simplysm-v14/orm-common/queryable-executable/executable.md +54 -0
  199. package/claude/references/sd-simplysm-v14/orm-common/queryable-executable/parse-search-query.md +75 -0
  200. package/claude/references/sd-simplysm-v14/orm-common/queryable-executable/queryable.md +238 -0
  201. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/column-builder.md +63 -0
  202. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/foreign-key-builder.md +137 -0
  203. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/index-builder.md +54 -0
  204. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/procedure.md +67 -0
  205. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/table.md +95 -0
  206. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/view.md +71 -0
  207. package/claude/references/sd-simplysm-v14/orm-common/types/data-type.md +146 -0
  208. package/claude/references/sd-simplysm-v14/orm-common/types/dialect.md +151 -0
  209. package/claude/references/sd-simplysm-v14/orm-common/types/expr.md +175 -0
  210. package/claude/references/sd-simplysm-v14/orm-common/types/parse-query-result.md +58 -0
  211. package/claude/references/sd-simplysm-v14/orm-common/types/query-def.md +224 -0
  212. package/claude/references/sd-simplysm-v14/orm-node/README.md +65 -0
  213. package/claude/references/sd-simplysm-v14/orm-node/connections/mssql-db-conn.md +85 -0
  214. package/claude/references/sd-simplysm-v14/orm-node/connections/mysql-db-conn.md +83 -0
  215. package/claude/references/sd-simplysm-v14/orm-node/connections/postgresql-db-conn.md +86 -0
  216. package/claude/references/sd-simplysm-v14/orm-node/core/create-db-conn.md +62 -0
  217. package/claude/references/sd-simplysm-v14/orm-node/core/create-orm.md +107 -0
  218. package/claude/references/sd-simplysm-v14/orm-node/core/node-db-context-executor.md +50 -0
  219. package/claude/references/sd-simplysm-v14/orm-node/types/db-conn-config.md +91 -0
  220. package/claude/references/sd-simplysm-v14/orm-node/types/db-conn-constants.md +33 -0
  221. package/claude/references/sd-simplysm-v14/orm-node/types/db-conn.md +60 -0
  222. package/claude/references/sd-simplysm-v14/orm-node/types/get-dialect-from-config.md +17 -0
  223. package/{README.md → claude/references/sd-simplysm-v14/sd-claude/README.md} +85 -84
  224. package/{docs → claude/references/sd-simplysm-v14/sd-claude}/assets.md +2 -2
  225. package/{docs → claude/references/sd-simplysm-v14/sd-claude}/hooks.md +15 -1
  226. package/claude/references/sd-simplysm-v14/sd-cli/README.md +138 -0
  227. package/claude/references/sd-simplysm-v14/sd-cli/angular-vite-plugin/sd-angular-plugin.md +60 -0
  228. package/claude/references/sd-simplysm-v14/sd-cli/config/build-target.md +31 -0
  229. package/claude/references/sd-simplysm-v14/sd-cli/config/npm-config.md +27 -0
  230. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-browser-support-config.md +19 -0
  231. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-build-package-config.md +21 -0
  232. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-capacitor-config.md +109 -0
  233. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-client-package-config.md +33 -0
  234. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-config.md +78 -0
  235. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-electron-config.md +27 -0
  236. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-package-config.md +18 -0
  237. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-post-publish-script-config.md +19 -0
  238. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-publish-config.md +72 -0
  239. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-pwa-config.md +41 -0
  240. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-scripts-package-config.md +19 -0
  241. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-server-package-config.md +32 -0
  242. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-watch-hook-config.md +19 -0
  243. package/claude/references/sd-simplysm-v14/sd-cli/ts-compiler/sd-ts-compiler.md +158 -0
  244. package/claude/references/sd-simplysm-v14/service-client/README.md +74 -0
  245. package/claude/references/sd-simplysm-v14/service-client/features/event-client.md +93 -0
  246. package/claude/references/sd-simplysm-v14/service-client/features/file-client.md +63 -0
  247. package/claude/references/sd-simplysm-v14/service-client/features/orm-client-connector.md +89 -0
  248. package/claude/references/sd-simplysm-v14/service-client/features/orm-client-db-context-executor.md +31 -0
  249. package/claude/references/sd-simplysm-v14/service-client/main/service-client.md +206 -0
  250. package/claude/references/sd-simplysm-v14/service-client/protocol/client-protocol-wrapper.md +64 -0
  251. package/claude/references/sd-simplysm-v14/service-client/transport/service-transport.md +68 -0
  252. package/claude/references/sd-simplysm-v14/service-client/transport/socket-provider.md +100 -0
  253. package/claude/references/sd-simplysm-v14/service-client/types/blob-input.md +7 -0
  254. package/claude/references/sd-simplysm-v14/service-client/types/browser-worker.md +47 -0
  255. package/claude/references/sd-simplysm-v14/service-client/types/file-collection.md +21 -0
  256. package/claude/references/sd-simplysm-v14/service-client/types/service-connection-options.md +22 -0
  257. package/claude/references/sd-simplysm-v14/service-client/types/service-progress.md +39 -0
  258. package/claude/references/sd-simplysm-v14/service-common/README.md +161 -0
  259. package/claude/references/sd-simplysm-v14/service-common/app-structure/app-structure-item.md +107 -0
  260. package/claude/references/sd-simplysm-v14/service-common/app-structure/get-flat-permissions.md +57 -0
  261. package/claude/references/sd-simplysm-v14/service-common/app-structure/is-usable-modules-chain.md +23 -0
  262. package/claude/references/sd-simplysm-v14/service-common/app-structure/is-usable-modules.md +42 -0
  263. package/claude/references/sd-simplysm-v14/service-common/events/define-event.md +68 -0
  264. package/claude/references/sd-simplysm-v14/service-common/protocol/create-service-protocol.md +93 -0
  265. package/claude/references/sd-simplysm-v14/service-common/protocol/protocol-config.md +21 -0
  266. package/claude/references/sd-simplysm-v14/service-common/protocol/service-add-event-listener-message.md +23 -0
  267. package/claude/references/sd-simplysm-v14/service-common/protocol/service-auth-message.md +17 -0
  268. package/claude/references/sd-simplysm-v14/service-common/protocol/service-emit-event-message.md +21 -0
  269. package/claude/references/sd-simplysm-v14/service-common/protocol/service-error-message.md +29 -0
  270. package/claude/references/sd-simplysm-v14/service-common/protocol/service-event-message.md +21 -0
  271. package/claude/references/sd-simplysm-v14/service-common/protocol/service-get-event-listener-infos-message.md +19 -0
  272. package/claude/references/sd-simplysm-v14/service-common/protocol/service-message.md +52 -0
  273. package/claude/references/sd-simplysm-v14/service-common/protocol/service-progress-message.md +21 -0
  274. package/claude/references/sd-simplysm-v14/service-common/protocol/service-remove-event-listener-message.md +19 -0
  275. package/claude/references/sd-simplysm-v14/service-common/protocol/service-request-message.md +17 -0
  276. package/claude/references/sd-simplysm-v14/service-common/protocol/service-response-message.md +17 -0
  277. package/claude/references/sd-simplysm-v14/service-common/service-types/app-structure-service.md +15 -0
  278. package/claude/references/sd-simplysm-v14/service-common/service-types/auto-update-service.md +20 -0
  279. package/claude/references/sd-simplysm-v14/service-common/service-types/orm-service.md +61 -0
  280. package/claude/references/sd-simplysm-v14/service-common/types/service-upload-result.md +19 -0
  281. package/claude/references/sd-simplysm-v14/service-server/README.md +162 -0
  282. package/claude/references/sd-simplysm-v14/service-server/auth/auth-token-payload.md +18 -0
  283. package/claude/references/sd-simplysm-v14/service-server/auth/sign-jwt.md +30 -0
  284. package/claude/references/sd-simplysm-v14/service-server/auth/verify-jwt.md +35 -0
  285. package/claude/references/sd-simplysm-v14/service-server/core/auth.md +64 -0
  286. package/claude/references/sd-simplysm-v14/service-server/core/define-service.md +81 -0
  287. package/claude/references/sd-simplysm-v14/service-server/core/execute-service-method.md +43 -0
  288. package/claude/references/sd-simplysm-v14/service-server/core/service-context.md +79 -0
  289. package/claude/references/sd-simplysm-v14/service-server/legacy/handle-v1-connection.md +25 -0
  290. package/claude/references/sd-simplysm-v14/service-server/main/create-service-server.md +32 -0
  291. package/claude/references/sd-simplysm-v14/service-server/main/service-server.md +113 -0
  292. package/claude/references/sd-simplysm-v14/service-server/protocol/server-protocol-wrapper.md +35 -0
  293. package/claude/references/sd-simplysm-v14/service-server/services/app-structure-service.md +59 -0
  294. package/claude/references/sd-simplysm-v14/service-server/services/auto-update-service.md +34 -0
  295. package/claude/references/sd-simplysm-v14/service-server/services/orm-service.md +43 -0
  296. package/claude/references/sd-simplysm-v14/service-server/transport-http/handle-http-request.md +33 -0
  297. package/claude/references/sd-simplysm-v14/service-server/transport-http/handle-static-file.md +29 -0
  298. package/claude/references/sd-simplysm-v14/service-server/transport-http/handle-upload.md +33 -0
  299. package/claude/references/sd-simplysm-v14/service-server/transport-socket/service-socket.md +64 -0
  300. package/claude/references/sd-simplysm-v14/service-server/transport-socket/websocket-handler.md +57 -0
  301. package/claude/references/sd-simplysm-v14/service-server/types/service-server-options.md +36 -0
  302. package/claude/references/sd-simplysm-v14/service-server/utils/get-config.md +29 -0
  303. package/claude/references/sd-simplysm-v14/storage/README.md +99 -0
  304. package/claude/references/sd-simplysm-v14/storage/clients/ftp-storage-client.md +99 -0
  305. package/claude/references/sd-simplysm-v14/storage/clients/sftp-storage-client.md +108 -0
  306. package/claude/references/sd-simplysm-v14/storage/factory/storage-factory.md +114 -0
  307. package/claude/references/sd-simplysm-v14/storage/types/file-info.md +32 -0
  308. package/claude/references/sd-simplysm-v14/storage/types/storage-client.md +55 -0
  309. package/claude/references/sd-simplysm-v14/storage/types/storage-conn-config.md +34 -0
  310. package/claude/rules/sd-claude-rules.md +8 -8
  311. package/claude/rules/sd-simplysm-v14.md +33 -0
  312. package/claude/skills/sd-claude-docs/SKILL.md +41 -24
  313. package/claude/skills/sd-claude-docs/references/package-docs.md +240 -116
  314. package/claude/skills/sd-inner-debug/SKILL.md +1 -1
  315. package/claude/skills/sd-inner-review/SKILL.md +4 -2
  316. package/package.json +2 -3
  317. /package/{docs → claude/references/sd-simplysm-v14/sd-claude}/cli.md +0 -0
  318. /package/{docs → claude/references/sd-simplysm-v14/sd-claude}/scripts.md +0 -0
@@ -0,0 +1,64 @@
1
+ # ServiceSocket
2
+
3
+ 프로토콜 인코딩/디코딩, ping/pong 연결 유지, 이벤트 리스너 추적이 포함된 단일 WebSocket 연결 인터페이스.
4
+
5
+ ```typescript
6
+ interface ServiceSocket {
7
+ readonly connectedAtDateTime: DateTime;
8
+ readonly clientName: string;
9
+ readonly connReq: FastifyRequest;
10
+ authTokenPayload?: AuthTokenPayload;
11
+
12
+ close(): void;
13
+ send(uuid: string, msg: ServiceServerMessage): Promise<number>;
14
+ addListener(key: string, eventName: string, info: unknown): void;
15
+ removeListener(key: string): void;
16
+ getEventListeners(eventName: string): Array<{ key: string; info: unknown }>;
17
+ filterEventTargetKeys(targetKeys: string[]): string[];
18
+ on(event: "error", handler: (err: Error) => void): void;
19
+ on(event: "close", handler: (code: number) => void): void;
20
+ on(event: "message", handler: (data: { uuid: string; msg: ServiceClientMessage }) => void): void;
21
+ }
22
+ ```
23
+
24
+ ## Members
25
+
26
+ | Member | Kind | Type | Description |
27
+ |--------|------|------|-------------|
28
+ | `connectedAtDateTime` | property | `DateTime` | 연결 시점의 DateTime 객체 |
29
+ | `clientName` | property | `string` | 클라이언트 앱 이름 |
30
+ | `connReq` | property | `FastifyRequest` | 연결 시점의 Fastify 요청 객체 |
31
+ | `authTokenPayload` | property | `AuthTokenPayload` (optional) | WebSocket `auth` 메시지로 검증된 토큰 페이로드 |
32
+ | `close()` | method | `void` | WebSocket 연결을 종료한다 (`socket.terminate()`) |
33
+ | `send(uuid, msg)` | method | `Promise<number>` | 메시지를 프로토콜 인코딩하여 전송한다. 전송된 바이트 수를 반환한다. 소켓이 닫혀있으면 0을 반환한다 |
34
+ | `addListener(key, eventName, info)` | method | `void` | key/name/info로 이벤트 리스너를 등록한다 |
35
+ | `removeListener(key)` | method | `void` | key로 이벤트 리스너를 제거한다 |
36
+ | `getEventListeners(eventName)` | method | `Array<{ key: string; info: unknown }>` | 특정 이벤트 이름에 해당하는 모든 리스너의 배열을 반환한다 |
37
+ | `filterEventTargetKeys(targetKeys)` | method | `string[]` | 이 소켓의 리스너에 존재하는 대상 키만 필터링하여 반환한다 |
38
+ | `on(event, handler)` | method | `void` | `"error"`, `"close"`, `"message"` 이벤트 핸들러를 등록한다 |
39
+
40
+ ping/pong: 5초 간격으로 ping을 전송하고, 클라이언트의 `0x01` 바이트(ping) 수신 시 `0x02` 바이트(pong)를 응답한다. pong 미수신 시 연결을 종료한다.
41
+
42
+ 프로토콜 메시지 처리: `createServerProtocolWrapper`를 사용하여 메시지를 인코딩/디코딩한다. 수신 메시지의 디코딩 결과가 `"progress"` 타입이면 진행률 메시지를 클라이언트에 전송한다.
43
+
44
+ ## Related Types
45
+
46
+ ### `createServiceSocket`
47
+
48
+ `ServiceSocket` 인스턴스를 생성한다.
49
+
50
+ ```typescript
51
+ function createServiceSocket(
52
+ socket: WebSocket,
53
+ clientId: string,
54
+ clientName: string,
55
+ connReq: FastifyRequest,
56
+ ): ServiceSocket;
57
+ ```
58
+
59
+ | Param | Type | Description |
60
+ |-------|------|-------------|
61
+ | `socket` | `WebSocket` | 기저 WebSocket 인스턴스 (`ws` 라이브러리) |
62
+ | `clientId` | `string` | 클라이언트 고유 식별자 |
63
+ | `clientName` | `string` | 클라이언트 앱 이름 |
64
+ | `connReq` | `FastifyRequest` | 연결 시점의 Fastify 요청 객체 |
@@ -0,0 +1,57 @@
1
+ # WebSocketHandler
2
+
3
+ 다중 WebSocket 연결을 관리하고, 메시지를 서비스로 라우팅하며, 이벤트 브로드캐스팅을 처리하는 인터페이스.
4
+
5
+ ```typescript
6
+ interface WebSocketHandler {
7
+ addSocket(socket: WebSocket, clientId: string, clientName: string, connReq: FastifyRequest): void;
8
+ closeAll(): void;
9
+ emit<TEventDef extends ServiceEventDef>(
10
+ eventName: string,
11
+ infoSelector: (item: TEventDef["$info"]) => boolean,
12
+ data: TEventDef["$data"],
13
+ ): Promise<void>;
14
+ }
15
+ ```
16
+
17
+ ## Members
18
+
19
+ | Member | Kind | Type | Description |
20
+ |--------|------|------|-------------|
21
+ | `addSocket(socket, clientId, clientName, connReq)` | method | `void` | 새 WebSocket 연결을 추가한다. 동일 `clientId`의 이전 연결이 있으면 해제한다 |
22
+ | `closeAll()` | method | `void` | 모든 활성 연결을 닫는다 |
23
+ | `emit(eventName, infoSelector, data)` | method | `Promise<void>` | `infoSelector`에 매칭되는 클라이언트에 이벤트를 브로드캐스트한다 |
24
+
25
+ 메시지 라우팅 (`processRequest` 내부):
26
+
27
+ | `message.name` | 처리 |
28
+ |-----------------|------|
29
+ | `"SvcName.methodName"` (`.` 포함) | `runMethod`로 서비스 메서드 실행 |
30
+ | `"evt:add"` | 이벤트 리스너 등록 (`key`, `name`, `info`) |
31
+ | `"evt:remove"` | 이벤트 리스너 제거 (`key`) |
32
+ | `"evt:gets"` | 전체 소켓의 특정 이벤트 리스너 조회 |
33
+ | `"evt:emit"` | 지정된 키 대상 이벤트 발송 |
34
+ | `"auth"` | JWT 토큰 검증 후 소켓에 `authTokenPayload` 저장 |
35
+
36
+ ## Related Types
37
+
38
+ ### `createWebSocketHandler`
39
+
40
+ `WebSocketHandler` 인스턴스를 생성한다.
41
+
42
+ ```typescript
43
+ function createWebSocketHandler(
44
+ runMethod: (def: {
45
+ serviceName: string;
46
+ methodName: string;
47
+ params: unknown[];
48
+ socket?: ServiceSocket;
49
+ }) => Promise<unknown>,
50
+ jwtSecret: string | undefined,
51
+ ): WebSocketHandler;
52
+ ```
53
+
54
+ | Param | Type | Description |
55
+ |-------|------|-------------|
56
+ | `runMethod` | `(def: { serviceName, methodName, params, socket? }) => Promise<unknown>` | 서비스 메서드 실행 콜백 |
57
+ | `jwtSecret` | `string \| undefined` | JWT 시크릿. `undefined`이면 `auth` 메시지 처리 시 에러를 던진다 |
@@ -0,0 +1,36 @@
1
+ # ServiceServerOptions
2
+
3
+ 서버 생성 시 전달하는 옵션 인터페이스.
4
+
5
+ ```typescript
6
+ interface ServiceServerOptions {
7
+ rootPath: string;
8
+ port: number;
9
+ ssl?: {
10
+ pfxBytes: Uint8Array;
11
+ passphrase: string;
12
+ };
13
+ auth?: {
14
+ jwtSecret: string;
15
+ } | false;
16
+ services: ServiceDefinition[];
17
+ }
18
+ ```
19
+
20
+ ## Fields
21
+
22
+ | Field | Type | Description |
23
+ |-------|------|-------------|
24
+ | `rootPath` | `string` | 서버 루트 경로. 정적 파일은 `{rootPath}/www/`에서 서빙되고, 설정 파일은 `{rootPath}/.config.json`에서 읽는다 |
25
+ | `port` | `number` | 리스닝 포트 번호 |
26
+ | `ssl` | `{ pfxBytes: Uint8Array; passphrase: string }` (optional) | HTTPS 설정. PFX 인증서 바이트와 비밀번호. 설정하지 않으면 HTTP로 동작한다 |
27
+ | `auth` | `{ jwtSecret: string } \| false` (optional) | JWT 인증 설정. 세 가지 상태가 있다 |
28
+ | `services` | `ServiceDefinition[]` | 등록할 서비스 정의 배열 |
29
+
30
+ `auth` 필드의 세 가지 상태:
31
+
32
+ | 값 | 의미 |
33
+ |----|------|
34
+ | `{ jwtSecret: "..." }` | 인증 활성화. `auth()`로 래핑된 서비스/메서드는 토큰 검증을 수행한다 |
35
+ | `false` | 인증 의도적 비활성화. `auth()`로 래핑된 서비스/메서드도 인증 검사를 스킵한다 |
36
+ | `undefined` (미설정) | 인증 미사용. `auth()`로 래핑된 서비스가 있으면 `listen()` 시 에러를 던진다 |
@@ -0,0 +1,29 @@
1
+ # getConfig
2
+
3
+ `.config.json` 파일을 읽고 캐싱한다. 파일 변경 시 자동 리로드되며, 캐시는 1시간 후 만료된다.
4
+
5
+ ## When to use
6
+
7
+ - ✅ 서비스에서 `.config.json` 설정 파일을 캐싱/자동 리로드로 읽을 때
8
+ - ❌ 일반적으로는 `ServiceContext.getConfig()`를 사용한다 — 이 함수는 내부적으로 `getConfig`를 호출하면서 루트/클라이언트별 설정 병합을 자동으로 처리한다
9
+
10
+ ```typescript
11
+ async function getConfig<TConfig>(filePath: string): Promise<TConfig | undefined>;
12
+ ```
13
+
14
+ ## Parameters
15
+
16
+ | Param | Type | Description |
17
+ |-------|------|-------------|
18
+ | `filePath` | `string` | `.config.json` 파일의 절대 경로 |
19
+
20
+ ## Returns
21
+
22
+ `Promise<TConfig | undefined>` — 파싱된 설정 객체. 파일이 존재하지 않으면 `undefined`.
23
+
24
+ 캐싱 동작:
25
+ - `LazyGcMap`을 사용하여 캐시를 관리한다 (10분 간격 GC, 1시간 후 만료)
26
+ - 캐시 히트 시 파일을 다시 읽지 않는다 (접근 시간이 자동 갱신됨)
27
+ - `FsWatcher`로 파일 변경을 감시하고, 변경 시 100ms 지연 후 리로드한다
28
+ - 파일이 삭제되면 캐시와 워처를 모두 해제한다
29
+ - 캐시 만료 시 워처도 함께 해제한다
@@ -0,0 +1,99 @@
1
+ # @simplysm/storage
2
+
3
+ > FTP/FTPS/SFTP 파일 저장소 클라이언트 라이브러리 (Node.js 전용). `StorageClient` 인터페이스로 프로토콜을 통일하고, `StorageFactory`로 연결 생명주기를 관리한다. 내부적으로 `basic-ftp`(FTP/FTPS)와 `ssh2-sftp-client`(SFTP)를 사용한다.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @simplysm/storage
9
+ ```
10
+
11
+ ## 하려는 작업 → 먼저 읽을 파일
12
+
13
+ | 작업 | 먼저 읽을 파일 |
14
+ |------|----------------|
15
+ | FTP/SFTP 서버에 파일 업로드/다운로드 | [`StorageFactory`](./factory/storage-factory.md) |
16
+ | 프로토콜별 구현 차이 확인 (FTP/FTPS) | [`FtpStorageClient`](./clients/ftp-storage-client.md) |
17
+ | SFTP 인증 방식 (패스워드/SSH 키) 확인 | [`SftpStorageClient`](./clients/sftp-storage-client.md) |
18
+ | 스토리지 작업을 추상화하는 함수 작성 | [`StorageClient`](./types/storage-client.md) |
19
+ | 연결 설정 타입 확인 | [`StorageConnConfig`](./types/storage-conn-config.md) |
20
+
21
+ ## API Overview
22
+
23
+ ### Factory
24
+
25
+ | Entry | Kind | 언제 쓰나 |
26
+ |-------|------|-----------|
27
+ | [`StorageFactory`](./factory/storage-factory.md) | class | 스토리지 서버에 연결하여 파일 작업을 수행할 때 (기본 진입점) |
28
+
29
+ ### Clients
30
+
31
+ | Entry | Kind | 언제 쓰나 |
32
+ |-------|------|-----------|
33
+ | [`FtpStorageClient`](./clients/ftp-storage-client.md) | class | FTP/FTPS 클라이언트를 직접 생명주기 관리해야 할 때 |
34
+ | [`SftpStorageClient`](./clients/sftp-storage-client.md) | class | SFTP 클라이언트를 직접 생명주기 관리해야 할 때 |
35
+
36
+ ### Types
37
+
38
+ | Entry | Kind | 언제 쓰나 |
39
+ |-------|------|-----------|
40
+ | [`StorageClient`](./types/storage-client.md) | interface | 스토리지 작업을 프로토콜 무관하게 추상화하는 함수 시그니처에 사용할 때 |
41
+ | [`StorageConnConfig`](./types/storage-conn-config.md) | interface | 연결 설정 객체를 타입으로 지정할 때 |
42
+ | [`FileInfo`](./types/file-info.md) | interface | `list()` 반환값을 처리할 때 |
43
+
44
+ ## Usage Examples
45
+
46
+ ### SFTP로 파일 업로드 (StorageFactory 사용 권장)
47
+
48
+ ```typescript
49
+ import { StorageFactory } from "@simplysm/storage";
50
+
51
+ await StorageFactory.connect(
52
+ "sftp",
53
+ { host: "sftp.example.com", user: "user", password: "pass" },
54
+ async (storage) => {
55
+ await storage.mkdir("/remote/dir");
56
+ await storage.put("/local/file.txt", "/remote/dir/file.txt");
57
+ },
58
+ );
59
+ ```
60
+
61
+ 콜백이 완료되거나 예외가 발생하면 자동으로 연결이 종료된다.
62
+
63
+ ### FTP로 파일 목록 조회 및 다운로드
64
+
65
+ ```typescript
66
+ import { StorageFactory } from "@simplysm/storage";
67
+
68
+ const files = await StorageFactory.connect(
69
+ "ftp",
70
+ { host: "ftp.example.com", port: 21, user: "user", password: "pass" },
71
+ async (storage) => {
72
+ const list = await storage.list("/data");
73
+ for (const file of list.filter((f) => f.isFile)) {
74
+ const content = await storage.readFile(`/data/${file.name}`);
75
+ // content는 Bytes (Uint8Array)
76
+ }
77
+ return list;
78
+ },
79
+ );
80
+ ```
81
+
82
+ ### SSH 키 인증으로 SFTP 연결 (비밀번호 생략)
83
+
84
+ ```typescript
85
+ import { StorageFactory } from "@simplysm/storage";
86
+
87
+ await StorageFactory.connect(
88
+ "sftp",
89
+ { host: "sftp.example.com", user: "user" }, // password 생략 → SSH agent/키 파일 인증
90
+ async (storage) => {
91
+ const list = await storage.list("/home/user");
92
+ },
93
+ );
94
+ ```
95
+
96
+ ## 이 패키지를 쓰지 말아야 할 때
97
+
98
+ - 브라우저 환경에서 파일 업로드/다운로드 → 이 패키지는 Node.js 전용이다
99
+ - HTTP/S3 등 FTP/SFTP 이외의 프로토콜 → 이 패키지는 FTP/FTPS/SFTP만 지원한다
@@ -0,0 +1,99 @@
1
+ # `FtpStorageClient`
2
+
3
+ FTP/FTPS 프로토콜을 사용하는 스토리지 클라이언트. `basic-ftp` 라이브러리 기반. [`StorageClient`](../types/storage-client.md) 인터페이스를 구현한다.
4
+
5
+ ## When to use
6
+
7
+ - ✅ FTP/FTPS 연결을 직접 생명주기 관리해야 할 때 (장시간 연결 유지 등)
8
+ - ❌ 단일 작업 단위로 연결/종료를 자동 관리하고 싶을 때 → [`StorageFactory.connect()`](../factory/storage-factory.md) 사용 권장
9
+
10
+ ## Signature
11
+
12
+ ```typescript
13
+ class FtpStorageClient implements StorageClient {
14
+ constructor(private readonly _secure: boolean = false);
15
+ }
16
+ ```
17
+
18
+ ## Constructor
19
+
20
+ | Parameter | Type | Default | Description |
21
+ |-----------|------|---------|-------------|
22
+ | `_secure` | `boolean` | `false` | `true`이면 FTPS (TLS/SSL 암호화), `false`이면 FTP |
23
+
24
+ ## Members
25
+
26
+ [`StorageClient`](../types/storage-client.md) 인터페이스의 모든 메서드를 구현한다. 구현 특이사항:
27
+
28
+ | Member | Kind | Description |
29
+ |--------|------|-------------|
30
+ | `connect` | method | 이미 연결된 상태에서 호출하면 `SdError` 발생. 연결 실패 시 내부 `ftp.Client`를 즉시 닫고 예외를 전파 |
31
+ | `mkdir` | method | `basic-ftp`의 `ensureDir()`을 사용하여 부모 디렉토리 포함 재귀 생성 |
32
+ | `exists` | method | 먼저 `size()` 명령으로 파일을 O(1) 성능으로 확인. 실패 시 부모 디렉토리 `list()`로 디렉토리 존재 여부 확인. 슬래시 없는 경로(예: `file.txt`)는 루트(`/`)에서 검색. 모든 예외는 `false` 반환 |
33
+ | `put` | method | `string`이면 파일 경로로, `Bytes`이면 `Readable` 스트림으로 변환하여 `uploadFrom()` 호출 |
34
+ | `close` | method | 동기적으로 내부 클라이언트를 정리하고 `Promise.resolve()` 반환. 이미 종료된 상태에서 호출해도 안전 |
35
+
36
+ ## Usage
37
+
38
+ ### 최소 예제
39
+
40
+ ```typescript
41
+ import { FtpStorageClient } from "@simplysm/storage";
42
+
43
+ const client = new FtpStorageClient();
44
+ try {
45
+ await client.connect({ host: "ftp.example.com", user: "user", password: "pass" });
46
+ await client.put("/local/file.txt", "/remote/file.txt");
47
+ } finally {
48
+ await client.close();
49
+ }
50
+ ```
51
+
52
+ ### 전형 예제
53
+
54
+ ```typescript
55
+ import { FtpStorageClient } from "@simplysm/storage";
56
+
57
+ // FTPS 사용
58
+ const client = new FtpStorageClient(true); // true = FTPS
59
+ try {
60
+ await client.connect({ host: "ftps.example.com", user: "user", password: "pass" });
61
+ const exists = await client.exists("/remote/file.txt");
62
+ if (exists) {
63
+ await client.rename("/remote/file.txt", "/remote/backup.txt");
64
+ }
65
+ await client.uploadDir("/local/dir", "/remote/dir");
66
+ } finally {
67
+ await client.close(); // 예외 발생 여부와 무관하게 반드시 종료
68
+ }
69
+ ```
70
+
71
+ ## 🚫 Anti-patterns
72
+
73
+ ### close() 없이 사용
74
+
75
+ ```typescript
76
+ // ❌ finally 없이 사용하면 예외 시 연결 누수
77
+ const client = new FtpStorageClient();
78
+ await client.connect(config);
79
+ await client.put("/local/file.txt", "/remote/file.txt");
80
+ await client.close();
81
+
82
+ // ✅ try/finally로 보장하거나 StorageFactory.connect() 사용
83
+ ```
84
+
85
+ **근거**: 예외 발생 시 `close()`가 호출되지 않아 FTP 연결이 누수된다.
86
+
87
+ ### 동일 인스턴스에서 connect() 중복 호출
88
+
89
+ ```typescript
90
+ // ❌ close() 없이 connect()를 다시 호출하면 SdError 발생
91
+ await client.connect(config);
92
+ await client.connect(config); // SdError: "FTP 서버에 이미 연결되어 있습니다"
93
+
94
+ // ✅ close() 후 재연결
95
+ await client.close();
96
+ await client.connect(config);
97
+ ```
98
+
99
+ **근거**: 내부 클라이언트가 이미 존재하면 `SdError`를 던진다.
@@ -0,0 +1,108 @@
1
+ # `SftpStorageClient`
2
+
3
+ SFTP 프로토콜을 사용하는 스토리지 클라이언트. `ssh2-sftp-client` 라이브러리 기반. [`StorageClient`](../types/storage-client.md) 인터페이스를 구현한다.
4
+
5
+ ## When to use
6
+
7
+ - ✅ SFTP 연결을 직접 생명주기 관리해야 할 때 (장시간 연결 유지 등)
8
+ - ❌ 단일 작업 단위로 연결/종료를 자동 관리하고 싶을 때 → [`StorageFactory.connect()`](../factory/storage-factory.md) 사용 권장
9
+
10
+ ## Signature
11
+
12
+ ```typescript
13
+ class SftpStorageClient implements StorageClient {
14
+ constructor();
15
+ }
16
+ ```
17
+
18
+ ## Members
19
+
20
+ [`StorageClient`](../types/storage-client.md) 인터페이스의 모든 메서드를 구현한다. 구현 특이사항:
21
+
22
+ | Member | Kind | Description |
23
+ |--------|------|-------------|
24
+ | `connect` | method | 이미 연결된 상태에서 호출하면 `SdError` 발생. `password` 유무에 따라 인증 방식이 달라짐 (아래 인증 메커니즘 참조). 연결 실패 시 `client.end()`를 호출하고 예외를 전파 |
25
+ | `mkdir` | method | `ssh2-sftp-client`의 `mkdir(path, true)`를 호출하여 부모 디렉토리 포함 재귀 생성 |
26
+ | `list` | method | `item.type === "-"`이면 파일(`isFile: true`), 아니면 디렉토리(`isFile: false`)로 변환 |
27
+ | `exists` | method | `ssh2-sftp-client`의 `exists()` 반환값(`false \| 'd' \| '-' \| 'l'`)을 검사. 문자열이면 존재. 모든 예외는 `false` 반환 |
28
+ | `readFile` | method | `ssh2-sftp-client`의 `get()` 반환값(`Buffer` 또는 `string`)을 `Bytes`(`Uint8Array`)로 변환 |
29
+ | `put` | method | `string`이면 `fastPut()`으로, `Bytes`이면 `Buffer.from()` 변환 후 `put()`으로 업로드 (`ssh2-sftp-client` 라이브러리 요구사항) |
30
+ | `close` | method | `client.end()`를 호출하여 연결 종료. 이미 종료된 상태에서 호출해도 안전 |
31
+
32
+ ## Authentication
33
+
34
+ `connect()` 호출 시 [`StorageConnConfig`](../types/storage-conn-config.md)의 `password` 유무에 따라 인증 방식이 결정된다:
35
+
36
+ **`password`가 있는 경우**: 패스워드 인증
37
+
38
+ **`password`가 없는 경우**: 다음 순서로 시도
39
+ 1. SSH agent (`SSH_AUTH_SOCK` 환경변수가 설정된 경우 `agent` 옵션 추가)
40
+ 2. `~/.ssh/id_ed25519` 개인키 파일 읽어 `privateKey` 옵션으로 인증 시도
41
+ 3. `privateKey` 파싱 실패 시 (암호화된 키 등) SSH agent만으로 재시도
42
+
43
+ ## Usage
44
+
45
+ ### 최소 예제
46
+
47
+ ```typescript
48
+ import { SftpStorageClient } from "@simplysm/storage";
49
+
50
+ const client = new SftpStorageClient();
51
+ try {
52
+ await client.connect({ host: "sftp.example.com", user: "user", password: "pass" });
53
+ await client.put("/local/file.txt", "/remote/file.txt");
54
+ } finally {
55
+ await client.close();
56
+ }
57
+ ```
58
+
59
+ ### 전형 예제
60
+
61
+ ```typescript
62
+ import { SftpStorageClient } from "@simplysm/storage";
63
+
64
+ // SSH 키 인증 (password 생략)
65
+ const client = new SftpStorageClient();
66
+ try {
67
+ await client.connect({ host: "sftp.example.com", user: "user" });
68
+ await client.mkdir("/remote/dir");
69
+ await client.put("/local/file.txt", "/remote/dir/file.txt");
70
+ const list = await client.list("/remote/dir");
71
+ for (const item of list.filter((f) => f.isFile)) {
72
+ const content = await client.readFile(`/remote/dir/${item.name}`);
73
+ // content는 Bytes (Uint8Array)
74
+ }
75
+ } finally {
76
+ await client.close(); // 예외 발생 여부와 무관하게 반드시 종료
77
+ }
78
+ ```
79
+
80
+ ## 🚫 Anti-patterns
81
+
82
+ ### close() 없이 사용
83
+
84
+ ```typescript
85
+ // ❌ finally 없이 사용하면 예외 시 연결 누수
86
+ const client = new SftpStorageClient();
87
+ await client.connect(config);
88
+ await client.put("/local/file.txt", "/remote/file.txt");
89
+ await client.close();
90
+
91
+ // ✅ try/finally로 보장하거나 StorageFactory.connect() 사용
92
+ ```
93
+
94
+ **근거**: 예외 발생 시 `close()`가 호출되지 않아 SFTP 연결이 누수된다.
95
+
96
+ ### 동일 인스턴스에서 connect() 중복 호출
97
+
98
+ ```typescript
99
+ // ❌ close() 없이 connect()를 다시 호출하면 SdError 발생
100
+ await client.connect(config);
101
+ await client.connect(config); // SdError: "SFTP 서버에 이미 연결되어 있습니다"
102
+
103
+ // ✅ close() 후 재연결
104
+ await client.close();
105
+ await client.connect(config);
106
+ ```
107
+
108
+ **근거**: 내부 클라이언트가 이미 존재하면 `SdError`를 던진다.
@@ -0,0 +1,114 @@
1
+ # `StorageFactory`
2
+
3
+ 스토리지 클라이언트 팩토리. 콜백 패턴으로 연결/종료를 자동 관리한다.
4
+
5
+ ## When to use
6
+
7
+ - ✅ FTP/FTPS/SFTP 서버에 파일 업로드, 다운로드, 목록 조회 등 작업을 수행할 때 — 기본 진입점
8
+ - ❌ 하나의 연결을 장시간 유지하면서 여러 작업 단위에 걸쳐 재사용해야 할 때 → [`FtpStorageClient`](../clients/ftp-storage-client.md) 또는 [`SftpStorageClient`](../clients/sftp-storage-client.md)를 직접 관리
9
+
10
+ ## Signature
11
+
12
+ ```typescript
13
+ class StorageFactory {
14
+ static async connect<R>(
15
+ type: StorageProtocol,
16
+ config: StorageConnConfig,
17
+ fn: (storage: StorageClient) => R | Promise<R>,
18
+ ): Promise<R>;
19
+ }
20
+ ```
21
+
22
+ ## Members
23
+
24
+ | Member | Kind | Type | Description |
25
+ |--------|------|------|-------------|
26
+ | `connect` | static method | `<R>(type: StorageProtocol, config: StorageConnConfig, fn: (storage: StorageClient) => R \| Promise<R>) => Promise<R>` | 프로토콜에 맞는 클라이언트를 생성하고, 연결 후 콜백을 실행하며, 완료/예외 시 자동으로 연결을 종료 |
27
+
28
+ ### `connect<R>()` 파라미터
29
+
30
+ | Parameter | Type | Description |
31
+ |-----------|------|-------------|
32
+ | `type` | `StorageProtocol` | 프로토콜 타입 |
33
+ | `config` | [`StorageConnConfig`](../types/storage-conn-config.md) | 연결 설정 |
34
+ | `fn` | `(storage: StorageClient) => R \| Promise<R>` | 연결된 클라이언트로 작업을 수행하는 콜백 |
35
+
36
+ **반환**: `Promise<R>` — 콜백의 반환값
37
+
38
+ **동작**:
39
+ - `type`에 따라 [`FtpStorageClient`](../clients/ftp-storage-client.md) 또는 [`SftpStorageClient`](../clients/sftp-storage-client.md)를 생성
40
+ - `client.connect(config)` 후 `fn(client)` 실행
41
+ - `fn` 완료 또는 예외 발생 여부와 무관하게 `finally`에서 `client.close()` 호출
42
+ - `fn`에서 발생한 예외는 그대로 전파
43
+
44
+ ## Related Types
45
+
46
+ ### `StorageProtocol`
47
+
48
+ `StorageFactory.connect()`의 `type` 파라미터 타입.
49
+
50
+ ```typescript
51
+ type StorageProtocol = "ftp" | "ftps" | "sftp";
52
+ ```
53
+
54
+ | Variant | Description |
55
+ |---------|-------------|
56
+ | `"ftp"` | 일반 FTP. `FtpStorageClient(false)` 생성 |
57
+ | `"ftps"` | TLS/SSL 암호화 FTP. `FtpStorageClient(true)` 생성 |
58
+ | `"sftp"` | SSH 기반 SFTP. `SftpStorageClient()` 생성 |
59
+
60
+ ## Usage
61
+
62
+ ### 최소 예제
63
+
64
+ ```typescript
65
+ import { StorageFactory } from "@simplysm/storage";
66
+
67
+ // 파일 업로드
68
+ await StorageFactory.connect(
69
+ "sftp",
70
+ { host: "sftp.example.com", user: "user", password: "pass" },
71
+ async (storage) => {
72
+ await storage.put("/local/file.txt", "/remote/file.txt");
73
+ },
74
+ );
75
+ ```
76
+
77
+ ### 전형 예제
78
+
79
+ ```typescript
80
+ import { StorageFactory } from "@simplysm/storage";
81
+
82
+ // 파일 목록 조회 후 반환값 활용
83
+ const list = await StorageFactory.connect(
84
+ "ftp",
85
+ { host: "ftp.example.com", port: 21, user: "user", password: "pass" },
86
+ (storage) => storage.list("/data"),
87
+ );
88
+
89
+ // 바이트 데이터로 업로드
90
+ const data = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]);
91
+ await StorageFactory.connect(
92
+ "ftps",
93
+ { host: "ftps.example.com", user: "user", password: "pass" },
94
+ (storage) => storage.put(data, "/remote/file.bin"),
95
+ );
96
+ ```
97
+
98
+ ## 🚫 Anti-patterns
99
+
100
+ ### 콜백 밖에서 클라이언트 참조 유지
101
+
102
+ ```typescript
103
+ // ❌ 콜백이 끝나면 연결이 종료되므로 외부에서 클라이언트를 사용할 수 없다
104
+ let savedClient: StorageClient;
105
+ await StorageFactory.connect("sftp", config, (storage) => {
106
+ savedClient = storage;
107
+ });
108
+ await savedClient.list("/"); // 이미 close()된 상태
109
+
110
+ // ✅ 필요한 작업을 모두 콜백 안에서 수행
111
+ const list = await StorageFactory.connect("sftp", config, (storage) => storage.list("/"));
112
+ ```
113
+
114
+ **근거**: `connect()`는 `finally`에서 `close()`를 호출하므로 콜백 종료 후 클라이언트는 사용 불가 상태다.
@@ -0,0 +1,32 @@
1
+ # FileInfo
2
+
3
+ 파일 또는 디렉토리 정보를 담는 인터페이스. [`StorageClient.list()`](./storage-client.md)의 반환 타입이다.
4
+
5
+ ```typescript
6
+ interface FileInfo {
7
+ name: string;
8
+ isFile: boolean;
9
+ }
10
+ ```
11
+
12
+ ## Fields
13
+
14
+ | Field | Type | Description |
15
+ |-------|------|-------------|
16
+ | `name` | `string` | 파일 또는 디렉토리의 이름 (경로 아님, 이름만) |
17
+ | `isFile` | `boolean` | `true`이면 파일, `false`이면 디렉토리 |
18
+
19
+ ## Usage
20
+
21
+ ```typescript
22
+ import { StorageFactory } from "@simplysm/storage";
23
+
24
+ const items = await StorageFactory.connect(
25
+ "sftp",
26
+ { host: "sftp.example.com", user: "user", password: "pass" },
27
+ async (storage) => storage.list("/remote/dir"),
28
+ );
29
+
30
+ const files = items.filter((item) => item.isFile);
31
+ const dirs = items.filter((item) => !item.isFile);
32
+ ```