@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.
- package/claude/references/sd-frontend-design.md +10 -9
- package/claude/references/sd-simplysm-v14/angular/README.md +497 -0
- package/claude/references/sd-simplysm-v14/angular/bootstrap/provide-sd-angular.md +37 -0
- package/claude/references/sd-simplysm-v14/angular/bootstrap/sd-angular-config-provider.md +16 -0
- package/claude/references/sd-simplysm-v14/angular/directives/sd-command-directive.md +27 -0
- package/claude/references/sd-simplysm-v14/angular/directives/sd-events.md +25 -0
- package/claude/references/sd-simplysm-v14/angular/directives/sd-intersection-directive.md +36 -0
- package/claude/references/sd-simplysm-v14/angular/directives/sd-invalid.md +24 -0
- package/claude/references/sd-simplysm-v14/angular/directives/sd-resize-directive.md +42 -0
- package/claude/references/sd-simplysm-v14/angular/directives/sd-ripple.md +23 -0
- package/claude/references/sd-simplysm-v14/angular/directives/sd-router-link.md +38 -0
- package/claude/references/sd-simplysm-v14/angular/directives/sd-show-effect.md +18 -0
- package/claude/references/sd-simplysm-v14/angular/directives/sd-typed-template.md +69 -0
- package/claude/references/sd-simplysm-v14/angular/features/sd-address-search-modal.md +50 -0
- package/claude/references/sd-simplysm-v14/angular/features/sd-permission-table.md +20 -0
- package/claude/references/sd-simplysm-v14/angular/features/sd-shared-data-components.md +158 -0
- package/claude/references/sd-simplysm-v14/angular/features/sd-tiptap-editor.md +26 -0
- package/claude/references/sd-simplysm-v14/angular/pipes/format-pipe.md +41 -0
- package/claude/references/sd-simplysm-v14/angular/plugins/sd-global-error-handler.md +23 -0
- package/claude/references/sd-simplysm-v14/angular/plugins/sd-option-event-plugin.md +34 -0
- package/claude/references/sd-simplysm-v14/angular/provider-types/sd-menu.md +65 -0
- package/claude/references/sd-simplysm-v14/angular/provider-types/sd-modal-content-def.md +148 -0
- package/claude/references/sd-simplysm-v14/angular/provider-types/sd-toast-content-def.md +73 -0
- package/claude/references/sd-simplysm-v14/angular/provider-types/shared-data-base.md +59 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-activated-modal-provider.md +34 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-app-structure-provider.md +81 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-busy-provider.md +18 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-file-dialog-provider.md +40 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-local-storage-provider.md +20 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-modal-provider.md +67 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-navigate-window-provider.md +18 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-print-provider.md +25 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-service-client-factory-provider.md +43 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-shared-data-provider.md +64 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-system-config-provider.md +46 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-system-log-provider.md +18 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-theme-provider.md +38 -0
- package/claude/references/sd-simplysm-v14/angular/providers/sd-toast-provider.md +65 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/_common-rules.md +336 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-a-edit-save.md +191 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-b-delete-restore.md +103 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-c-modal-view.md +198 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-d-control-view.md +109 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-e-auxiliary.md +87 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-f-complex-detail.md +202 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail.md +280 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-a-inline-edit.md +386 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-b-selection.md +215 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-c-inline-delete.md +64 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-d-select-modal.md +193 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-e-readonly-modal.md +140 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-f-modal-edit.md +123 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-g-excel.md +145 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/crud-list.md +377 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/data-select-button.md +368 -0
- package/claude/references/sd-simplysm-v14/angular/recipes/page-modal-container.md +238 -0
- package/claude/references/sd-simplysm-v14/angular/styling/classes.md +149 -0
- package/claude/references/sd-simplysm-v14/angular/styling/mixins.md +100 -0
- package/claude/references/sd-simplysm-v14/angular/styling/themes.md +35 -0
- package/claude/references/sd-simplysm-v14/angular/styling/variables.md +147 -0
- package/claude/references/sd-simplysm-v14/angular/type-utilities/directive-input-signals.md +232 -0
- package/claude/references/sd-simplysm-v14/angular/ui-data/sd-list.md +37 -0
- package/claude/references/sd-simplysm-v14/angular/ui-data/sd-sheet.md +212 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-additional-button.md +26 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-anchor.md +31 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-button.md +103 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-checkbox-group.md +39 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-checkbox.md +81 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-date-range-picker.md +27 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-form.md +89 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-modal-select-button.md +54 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-numpad.md +26 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-range.md +26 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-select.md +68 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-shared-data-select.md +52 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-state-preset.md +37 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-switch.md +27 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-textarea.md +33 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-textfield.md +145 -0
- package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-dock-container.md +64 -0
- package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-dock.md +37 -0
- package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-gap.md +26 -0
- package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-kanban-board.md +96 -0
- package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-kanban-lane.md +34 -0
- package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-kanban.md +29 -0
- package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-collapse.md +35 -0
- package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-pagination.md +26 -0
- package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-sidebar-container.md +49 -0
- package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-sidebar-menu.md +22 -0
- package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-sidebar-user.md +43 -0
- package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-tab.md +51 -0
- package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar-container.md +97 -0
- package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar-menu.md +23 -0
- package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar-user.md +38 -0
- package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar.md +30 -0
- package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-busy-container.md +69 -0
- package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-confirm-modal.md +30 -0
- package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-dropdown.md +40 -0
- package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-modal.md +34 -0
- package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-prompt-modal.md +30 -0
- package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-toast.md +35 -0
- package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-barcode.md +36 -0
- package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-calendar.md +34 -0
- package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-echarts.md +32 -0
- package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-label.md +24 -0
- package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-note.md +23 -0
- package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-progress.md +23 -0
- package/claude/references/sd-simplysm-v14/angular/utils/inject-routing-signals.md +161 -0
- package/claude/references/sd-simplysm-v14/angular/utils/inject-sd-system-config-resource.md +35 -0
- package/claude/references/sd-simplysm-v14/angular/utils/mark.md +43 -0
- package/claude/references/sd-simplysm-v14/angular/utils/selection-managers.md +96 -0
- package/claude/references/sd-simplysm-v14/angular/utils/set-safe-style.md +19 -0
- package/claude/references/sd-simplysm-v14/angular/utils/setup-functions.md +93 -0
- package/claude/references/sd-simplysm-v14/capacitor-plugin-auto-update/README.md +38 -0
- package/claude/references/sd-simplysm-v14/capacitor-plugin-auto-update/apk-installer/apk-installer.md +115 -0
- package/claude/references/sd-simplysm-v14/capacitor-plugin-auto-update/auto-update/auto-update.md +113 -0
- package/claude/references/sd-simplysm-v14/capacitor-plugin-file-system/README.md +197 -0
- package/claude/references/sd-simplysm-v14/capacitor-plugin-intent/README.md +235 -0
- package/claude/references/sd-simplysm-v14/capacitor-plugin-usb-storage/README.md +251 -0
- package/claude/references/sd-simplysm-v14/core-browser/README.md +52 -0
- package/claude/references/sd-simplysm-v14/core-browser/extensions/copy-paste.md +59 -0
- package/claude/references/sd-simplysm-v14/core-browser/extensions/element-prototype-extensions.md +137 -0
- package/claude/references/sd-simplysm-v14/core-browser/extensions/get-bounds.md +84 -0
- package/claude/references/sd-simplysm-v14/core-browser/utils/download-blob.md +59 -0
- package/claude/references/sd-simplysm-v14/core-browser/utils/fetch-url-bytes.md +91 -0
- package/claude/references/sd-simplysm-v14/core-browser/utils/indexed-db-store.md +131 -0
- package/claude/references/sd-simplysm-v14/core-browser/utils/indexed-db-virtual-fs.md +121 -0
- package/claude/references/sd-simplysm-v14/core-browser/utils/open-file-dialog.md +60 -0
- package/claude/references/sd-simplysm-v14/core-common/README.md +179 -0
- package/claude/references/sd-simplysm-v14/core-common/errors/argument-error.md +26 -0
- package/claude/references/sd-simplysm-v14/core-common/errors/not-implemented-error.md +33 -0
- package/claude/references/sd-simplysm-v14/core-common/errors/sd-error.md +38 -0
- package/claude/references/sd-simplysm-v14/core-common/errors/timeout-error.md +36 -0
- package/claude/references/sd-simplysm-v14/core-common/extensions/array.md +125 -0
- package/claude/references/sd-simplysm-v14/core-common/extensions/map.md +43 -0
- package/claude/references/sd-simplysm-v14/core-common/extensions/set.md +35 -0
- package/claude/references/sd-simplysm-v14/core-common/features/debounce-queue.md +48 -0
- package/claude/references/sd-simplysm-v14/core-common/features/event-emitter.md +52 -0
- package/claude/references/sd-simplysm-v14/core-common/features/serial-queue.md +44 -0
- package/claude/references/sd-simplysm-v14/core-common/type-utils/common-types.md +100 -0
- package/claude/references/sd-simplysm-v14/core-common/type-utils/env.md +42 -0
- package/claude/references/sd-simplysm-v14/core-common/types/date-only.md +86 -0
- package/claude/references/sd-simplysm-v14/core-common/types/date-time.md +106 -0
- package/claude/references/sd-simplysm-v14/core-common/types/lazy-gc-map.md +59 -0
- package/claude/references/sd-simplysm-v14/core-common/types/time.md +62 -0
- package/claude/references/sd-simplysm-v14/core-common/types/uuid.md +41 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/bytes.md +36 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/dt.md +60 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/err.md +26 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/json.md +58 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/num.md +56 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/obj.md +107 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/path.md +30 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/primitive.md +28 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/str.md +63 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/template-strings.md +49 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/transfer.md +35 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/wait.md +35 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/xml.md +49 -0
- package/claude/references/sd-simplysm-v14/core-common/utils/zip-archive.md +77 -0
- package/claude/references/sd-simplysm-v14/core-node/README.md +59 -0
- package/claude/references/sd-simplysm-v14/core-node/features/fs-watcher.md +110 -0
- package/claude/references/sd-simplysm-v14/core-node/logging/create-file-reporter.md +78 -0
- package/claude/references/sd-simplysm-v14/core-node/logging/pretty-reporter.md +38 -0
- package/claude/references/sd-simplysm-v14/core-node/logging/setup-consola.md +77 -0
- package/claude/references/sd-simplysm-v14/core-node/utils/cpx.md +128 -0
- package/claude/references/sd-simplysm-v14/core-node/utils/fsx.md +168 -0
- package/claude/references/sd-simplysm-v14/core-node/utils/pathx.md +73 -0
- package/claude/references/sd-simplysm-v14/core-node/worker/create-worker.md +85 -0
- package/claude/references/sd-simplysm-v14/core-node/worker/worker.md +160 -0
- package/claude/references/sd-simplysm-v14/excel/README.md +66 -0
- package/claude/references/sd-simplysm-v14/excel/core-classes/excel-cell.md +79 -0
- package/claude/references/sd-simplysm-v14/excel/core-classes/excel-col.md +36 -0
- package/claude/references/sd-simplysm-v14/excel/core-classes/excel-row.md +34 -0
- package/claude/references/sd-simplysm-v14/excel/core-classes/excel-workbook.md +93 -0
- package/claude/references/sd-simplysm-v14/excel/core-classes/excel-worksheet.md +147 -0
- package/claude/references/sd-simplysm-v14/excel/types/excel-address-point.md +33 -0
- package/claude/references/sd-simplysm-v14/excel/types/excel-style-options.md +57 -0
- package/claude/references/sd-simplysm-v14/excel/types/excel-value-type.md +28 -0
- package/claude/references/sd-simplysm-v14/excel/types/excel-xml-content-type-data.md +23 -0
- package/claude/references/sd-simplysm-v14/excel/types/excel-xml-drawing-data.md +29 -0
- package/claude/references/sd-simplysm-v14/excel/types/excel-xml-relationship-data.md +39 -0
- package/claude/references/sd-simplysm-v14/excel/types/excel-xml-shared-string-data.md +42 -0
- package/claude/references/sd-simplysm-v14/excel/types/excel-xml-style-data.md +97 -0
- package/claude/references/sd-simplysm-v14/excel/types/excel-xml-workbook-data.md +22 -0
- package/claude/references/sd-simplysm-v14/excel/types/excel-xml-worksheet-data.md +68 -0
- package/claude/references/sd-simplysm-v14/excel/types/excel-xml.md +15 -0
- package/claude/references/sd-simplysm-v14/excel/utilities/excel-utils.md +101 -0
- package/claude/references/sd-simplysm-v14/excel/wrapper/excel-wrapper.md +108 -0
- package/claude/references/sd-simplysm-v14/lint/README.md +183 -0
- package/claude/references/sd-simplysm-v14/orm-common/README.md +156 -0
- package/claude/references/sd-simplysm-v14/orm-common/core/db-context.md +208 -0
- package/claude/references/sd-simplysm-v14/orm-common/core/db-transaction-error.md +64 -0
- package/claude/references/sd-simplysm-v14/orm-common/expression/expr-unit.md +62 -0
- package/claude/references/sd-simplysm-v14/orm-common/expression/expr.md +198 -0
- package/claude/references/sd-simplysm-v14/orm-common/models/migration.md +37 -0
- package/claude/references/sd-simplysm-v14/orm-common/query-builder/create-query-builder.md +80 -0
- package/claude/references/sd-simplysm-v14/orm-common/queryable-executable/executable.md +54 -0
- package/claude/references/sd-simplysm-v14/orm-common/queryable-executable/parse-search-query.md +75 -0
- package/claude/references/sd-simplysm-v14/orm-common/queryable-executable/queryable.md +238 -0
- package/claude/references/sd-simplysm-v14/orm-common/schema-builders/column-builder.md +63 -0
- package/claude/references/sd-simplysm-v14/orm-common/schema-builders/foreign-key-builder.md +137 -0
- package/claude/references/sd-simplysm-v14/orm-common/schema-builders/index-builder.md +54 -0
- package/claude/references/sd-simplysm-v14/orm-common/schema-builders/procedure.md +67 -0
- package/claude/references/sd-simplysm-v14/orm-common/schema-builders/table.md +95 -0
- package/claude/references/sd-simplysm-v14/orm-common/schema-builders/view.md +71 -0
- package/claude/references/sd-simplysm-v14/orm-common/types/data-type.md +146 -0
- package/claude/references/sd-simplysm-v14/orm-common/types/dialect.md +151 -0
- package/claude/references/sd-simplysm-v14/orm-common/types/expr.md +175 -0
- package/claude/references/sd-simplysm-v14/orm-common/types/parse-query-result.md +58 -0
- package/claude/references/sd-simplysm-v14/orm-common/types/query-def.md +224 -0
- package/claude/references/sd-simplysm-v14/orm-node/README.md +65 -0
- package/claude/references/sd-simplysm-v14/orm-node/connections/mssql-db-conn.md +85 -0
- package/claude/references/sd-simplysm-v14/orm-node/connections/mysql-db-conn.md +83 -0
- package/claude/references/sd-simplysm-v14/orm-node/connections/postgresql-db-conn.md +86 -0
- package/claude/references/sd-simplysm-v14/orm-node/core/create-db-conn.md +62 -0
- package/claude/references/sd-simplysm-v14/orm-node/core/create-orm.md +107 -0
- package/claude/references/sd-simplysm-v14/orm-node/core/node-db-context-executor.md +50 -0
- package/claude/references/sd-simplysm-v14/orm-node/types/db-conn-config.md +91 -0
- package/claude/references/sd-simplysm-v14/orm-node/types/db-conn-constants.md +33 -0
- package/claude/references/sd-simplysm-v14/orm-node/types/db-conn.md +60 -0
- package/claude/references/sd-simplysm-v14/orm-node/types/get-dialect-from-config.md +17 -0
- package/{README.md → claude/references/sd-simplysm-v14/sd-claude/README.md} +85 -84
- package/{docs → claude/references/sd-simplysm-v14/sd-claude}/assets.md +2 -2
- package/{docs → claude/references/sd-simplysm-v14/sd-claude}/hooks.md +15 -1
- package/claude/references/sd-simplysm-v14/sd-cli/README.md +138 -0
- package/claude/references/sd-simplysm-v14/sd-cli/angular-vite-plugin/sd-angular-plugin.md +60 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/build-target.md +31 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/npm-config.md +27 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-browser-support-config.md +19 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-build-package-config.md +21 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-capacitor-config.md +109 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-client-package-config.md +33 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-config.md +78 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-electron-config.md +27 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-package-config.md +18 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-post-publish-script-config.md +19 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-publish-config.md +72 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-pwa-config.md +41 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-scripts-package-config.md +19 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-server-package-config.md +32 -0
- package/claude/references/sd-simplysm-v14/sd-cli/config/sd-watch-hook-config.md +19 -0
- package/claude/references/sd-simplysm-v14/sd-cli/ts-compiler/sd-ts-compiler.md +158 -0
- package/claude/references/sd-simplysm-v14/service-client/README.md +74 -0
- package/claude/references/sd-simplysm-v14/service-client/features/event-client.md +93 -0
- package/claude/references/sd-simplysm-v14/service-client/features/file-client.md +63 -0
- package/claude/references/sd-simplysm-v14/service-client/features/orm-client-connector.md +89 -0
- package/claude/references/sd-simplysm-v14/service-client/features/orm-client-db-context-executor.md +31 -0
- package/claude/references/sd-simplysm-v14/service-client/main/service-client.md +206 -0
- package/claude/references/sd-simplysm-v14/service-client/protocol/client-protocol-wrapper.md +64 -0
- package/claude/references/sd-simplysm-v14/service-client/transport/service-transport.md +68 -0
- package/claude/references/sd-simplysm-v14/service-client/transport/socket-provider.md +100 -0
- package/claude/references/sd-simplysm-v14/service-client/types/blob-input.md +7 -0
- package/claude/references/sd-simplysm-v14/service-client/types/browser-worker.md +47 -0
- package/claude/references/sd-simplysm-v14/service-client/types/file-collection.md +21 -0
- package/claude/references/sd-simplysm-v14/service-client/types/service-connection-options.md +22 -0
- package/claude/references/sd-simplysm-v14/service-client/types/service-progress.md +39 -0
- package/claude/references/sd-simplysm-v14/service-common/README.md +161 -0
- package/claude/references/sd-simplysm-v14/service-common/app-structure/app-structure-item.md +107 -0
- package/claude/references/sd-simplysm-v14/service-common/app-structure/get-flat-permissions.md +57 -0
- package/claude/references/sd-simplysm-v14/service-common/app-structure/is-usable-modules-chain.md +23 -0
- package/claude/references/sd-simplysm-v14/service-common/app-structure/is-usable-modules.md +42 -0
- package/claude/references/sd-simplysm-v14/service-common/events/define-event.md +68 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/create-service-protocol.md +93 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/protocol-config.md +21 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/service-add-event-listener-message.md +23 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/service-auth-message.md +17 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/service-emit-event-message.md +21 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/service-error-message.md +29 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/service-event-message.md +21 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/service-get-event-listener-infos-message.md +19 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/service-message.md +52 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/service-progress-message.md +21 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/service-remove-event-listener-message.md +19 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/service-request-message.md +17 -0
- package/claude/references/sd-simplysm-v14/service-common/protocol/service-response-message.md +17 -0
- package/claude/references/sd-simplysm-v14/service-common/service-types/app-structure-service.md +15 -0
- package/claude/references/sd-simplysm-v14/service-common/service-types/auto-update-service.md +20 -0
- package/claude/references/sd-simplysm-v14/service-common/service-types/orm-service.md +61 -0
- package/claude/references/sd-simplysm-v14/service-common/types/service-upload-result.md +19 -0
- package/claude/references/sd-simplysm-v14/service-server/README.md +162 -0
- package/claude/references/sd-simplysm-v14/service-server/auth/auth-token-payload.md +18 -0
- package/claude/references/sd-simplysm-v14/service-server/auth/sign-jwt.md +30 -0
- package/claude/references/sd-simplysm-v14/service-server/auth/verify-jwt.md +35 -0
- package/claude/references/sd-simplysm-v14/service-server/core/auth.md +64 -0
- package/claude/references/sd-simplysm-v14/service-server/core/define-service.md +81 -0
- package/claude/references/sd-simplysm-v14/service-server/core/execute-service-method.md +43 -0
- package/claude/references/sd-simplysm-v14/service-server/core/service-context.md +79 -0
- package/claude/references/sd-simplysm-v14/service-server/legacy/handle-v1-connection.md +25 -0
- package/claude/references/sd-simplysm-v14/service-server/main/create-service-server.md +32 -0
- package/claude/references/sd-simplysm-v14/service-server/main/service-server.md +113 -0
- package/claude/references/sd-simplysm-v14/service-server/protocol/server-protocol-wrapper.md +35 -0
- package/claude/references/sd-simplysm-v14/service-server/services/app-structure-service.md +59 -0
- package/claude/references/sd-simplysm-v14/service-server/services/auto-update-service.md +34 -0
- package/claude/references/sd-simplysm-v14/service-server/services/orm-service.md +43 -0
- package/claude/references/sd-simplysm-v14/service-server/transport-http/handle-http-request.md +33 -0
- package/claude/references/sd-simplysm-v14/service-server/transport-http/handle-static-file.md +29 -0
- package/claude/references/sd-simplysm-v14/service-server/transport-http/handle-upload.md +33 -0
- package/claude/references/sd-simplysm-v14/service-server/transport-socket/service-socket.md +64 -0
- package/claude/references/sd-simplysm-v14/service-server/transport-socket/websocket-handler.md +57 -0
- package/claude/references/sd-simplysm-v14/service-server/types/service-server-options.md +36 -0
- package/claude/references/sd-simplysm-v14/service-server/utils/get-config.md +29 -0
- package/claude/references/sd-simplysm-v14/storage/README.md +99 -0
- package/claude/references/sd-simplysm-v14/storage/clients/ftp-storage-client.md +99 -0
- package/claude/references/sd-simplysm-v14/storage/clients/sftp-storage-client.md +108 -0
- package/claude/references/sd-simplysm-v14/storage/factory/storage-factory.md +114 -0
- package/claude/references/sd-simplysm-v14/storage/types/file-info.md +32 -0
- package/claude/references/sd-simplysm-v14/storage/types/storage-client.md +55 -0
- package/claude/references/sd-simplysm-v14/storage/types/storage-conn-config.md +34 -0
- package/claude/rules/sd-claude-rules.md +8 -8
- package/claude/rules/sd-simplysm-v14.md +33 -0
- package/claude/skills/sd-claude-docs/SKILL.md +41 -24
- package/claude/skills/sd-claude-docs/references/package-docs.md +240 -116
- package/claude/skills/sd-inner-debug/SKILL.md +1 -1
- package/claude/skills/sd-inner-review/SKILL.md +4 -2
- package/package.json +2 -3
- /package/{docs → claude/references/sd-simplysm-v14/sd-claude}/cli.md +0 -0
- /package/{docs → claude/references/sd-simplysm-v14/sd-claude}/scripts.md +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# defineService
|
|
2
|
+
|
|
3
|
+
이름과 팩토리 함수로 서비스를 정의한다. 팩토리가 `auth()`로 래핑되어 있으면 자동으로 `authPermissions`를 추출한다.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- ✅ 서버에 등록할 서비스를 정의할 때
|
|
8
|
+
- ❌ 기존 내장 서비스(`OrmService`, `AutoUpdateService`)를 사용할 때는 직접 호출 불필요 — 이미 `defineService`로 정의되어 있다
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
function defineService<TMethods extends Record<string, (...args: any[]) => any>>(
|
|
12
|
+
name: string,
|
|
13
|
+
factory: (ctx: ServiceContext) => TMethods,
|
|
14
|
+
): ServiceDefinition<TMethods>;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Parameters
|
|
18
|
+
|
|
19
|
+
| Param | Type | Description |
|
|
20
|
+
|-------|------|-------------|
|
|
21
|
+
| `name` | `string` | 서비스 이름. HTTP에서 `/api/{name}/{method}`, WebSocket에서 `{name}.{method}`로 라우팅된다 |
|
|
22
|
+
| `factory` | `(ctx: ServiceContext) => TMethods` | 요청마다 호출되는 팩토리 함수. 메서드 객체를 반환한다 |
|
|
23
|
+
|
|
24
|
+
## Returns
|
|
25
|
+
|
|
26
|
+
[`ServiceDefinition<TMethods>`](#servicedefinition) — 서비스 정의 객체.
|
|
27
|
+
|
|
28
|
+
## Related Types
|
|
29
|
+
|
|
30
|
+
### `ServiceDefinition`
|
|
31
|
+
|
|
32
|
+
서비스 정의 구조체.
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
interface ServiceDefinition<TMethods = Record<string, (...args: any[]) => any>> {
|
|
36
|
+
name: string;
|
|
37
|
+
factory: (ctx: ServiceContext) => TMethods;
|
|
38
|
+
authPermissions?: string[];
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
| Field | Type | Description |
|
|
43
|
+
|-------|------|-------------|
|
|
44
|
+
| `name` | `string` | 서비스 이름 |
|
|
45
|
+
| `factory` | `(ctx: ServiceContext) => TMethods` | 요청마다 호출되는 팩토리 함수 |
|
|
46
|
+
| `authPermissions` | `string[]` (optional) | `auth()`로 래핑된 팩토리의 서비스 수준 권한 배열 |
|
|
47
|
+
|
|
48
|
+
### `ServiceMethods`
|
|
49
|
+
|
|
50
|
+
`ServiceDefinition`에서 메서드 시그니처를 추출하는 유틸리티 타입. 클라이언트 측 타입 공유에 사용한다.
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
type ServiceMethods<TDefinition> =
|
|
54
|
+
TDefinition extends ServiceDefinition<infer M> ? M : never;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
사용 예:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
export type UserServiceType = ServiceMethods<typeof UserService>;
|
|
61
|
+
// 클라이언트: client.getService<UserServiceType>("User");
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// 기본 서비스 (인증 불필요)
|
|
68
|
+
const HealthService = defineService("Health", (ctx) => ({
|
|
69
|
+
check: () => ({ status: "ok" }),
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
// 서비스 수준 인증 (모든 메서드에 로그인 필요)
|
|
73
|
+
const UserService = defineService("User", auth((ctx) => ({
|
|
74
|
+
getProfile: () => ctx.authInfo,
|
|
75
|
+
// 메서드 수준 인증 (admin 역할 필요)
|
|
76
|
+
deleteUser: auth(["admin"], (id: number) => { /* ... */ }),
|
|
77
|
+
})));
|
|
78
|
+
|
|
79
|
+
// 클라이언트에 타입 공유
|
|
80
|
+
export type UserServiceType = ServiceMethods<typeof UserService>;
|
|
81
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# executeServiceMethod
|
|
2
|
+
|
|
3
|
+
서비스 조회 → 컨텍스트 생성 → 인증 확인 → 메서드 실행 파이프라인을 수행한다.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- ✅ 커스텀 전송 계층에서 서비스 실행 파이프라인을 직접 호출할 때
|
|
8
|
+
- ❌ 일반적인 서버 사용 시에는 `ServiceServer`가 내부적으로 호출하므로 직접 사용할 필요가 없다
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
async function executeServiceMethod(
|
|
12
|
+
server: ServiceServer,
|
|
13
|
+
def: {
|
|
14
|
+
serviceName: string;
|
|
15
|
+
methodName: string;
|
|
16
|
+
params: unknown[];
|
|
17
|
+
socket?: ServiceSocket;
|
|
18
|
+
http?: { clientName: string; authTokenPayload?: AuthTokenPayload };
|
|
19
|
+
},
|
|
20
|
+
): Promise<unknown>;
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Parameters
|
|
24
|
+
|
|
25
|
+
| Param | Type | Description |
|
|
26
|
+
|-------|------|-------------|
|
|
27
|
+
| `server` | `ServiceServer` | 서버 인스턴스 |
|
|
28
|
+
| `def.serviceName` | `string` | 호출할 서비스 이름 |
|
|
29
|
+
| `def.methodName` | `string` | 호출할 메서드 이름 |
|
|
30
|
+
| `def.params` | `unknown[]` | 메서드 매개변수 배열 |
|
|
31
|
+
| `def.socket` | `ServiceSocket` (optional) | WebSocket 연결 (WebSocket 요청 시) |
|
|
32
|
+
| `def.http` | `{ clientName: string; authTokenPayload? }` (optional) | HTTP 요청 정보 |
|
|
33
|
+
|
|
34
|
+
## Returns
|
|
35
|
+
|
|
36
|
+
`Promise<unknown>` — 메서드 실행 결과.
|
|
37
|
+
|
|
38
|
+
인증 검사 로직:
|
|
39
|
+
|
|
40
|
+
1. 메서드 수준 `auth()` 권한이 있으면 이를 사용하고, 없으면 서비스 수준 `authPermissions`를 사용한다
|
|
41
|
+
2. 인증이 필요한데 `server.options.auth`가 `undefined`이면 설정 오류로 에러를 던진다
|
|
42
|
+
3. `server.options.auth`가 `false`이면 인증 검사를 스킵한다
|
|
43
|
+
4. 인증이 활성화되어 있으면 토큰 존재 여부를 확인하고, 역할 배열이 비어있지 않으면 역할 매칭을 수행한다
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# ServiceContext
|
|
2
|
+
|
|
3
|
+
서비스 팩토리 함수에 전달되는 컨텍스트 인터페이스. 전송 방식(WebSocket/HTTP)에 무관하게 동일한 인터페이스를 제공한다.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
interface ServiceContext<TAuthInfo = unknown> {
|
|
7
|
+
server: ServiceServer<TAuthInfo>;
|
|
8
|
+
socket?: ServiceSocket;
|
|
9
|
+
http?: {
|
|
10
|
+
clientName: string;
|
|
11
|
+
authTokenPayload?: AuthTokenPayload<TAuthInfo>;
|
|
12
|
+
};
|
|
13
|
+
legacy?: {
|
|
14
|
+
clientName?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
get authInfo(): TAuthInfo | undefined;
|
|
18
|
+
get clientName(): string | undefined;
|
|
19
|
+
get clientPath(): string | undefined;
|
|
20
|
+
getConfig<T>(section: string): Promise<T>;
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Members
|
|
25
|
+
|
|
26
|
+
| Member | Kind | Type | Description |
|
|
27
|
+
|--------|------|------|-------------|
|
|
28
|
+
| `server` | property | `ServiceServer<TAuthInfo>` | 서버 인스턴스 참조 |
|
|
29
|
+
| `socket` | property | `ServiceSocket` (optional) | WebSocket 요청일 때만 존재하는 소켓 객체 |
|
|
30
|
+
| `http` | property | `{ clientName: string; authTokenPayload?: AuthTokenPayload<TAuthInfo> }` (optional) | HTTP 요청일 때만 존재 |
|
|
31
|
+
| `legacy` | property | `{ clientName?: string }` (optional) | V1 레거시 컨텍스트 (자동 업데이트 전용) |
|
|
32
|
+
| `authInfo` | getter | `TAuthInfo \| undefined` | 토큰에서 추출한 사용자 데이터. WebSocket은 소켓의 `authTokenPayload.data`, HTTP는 헤더의 `authTokenPayload.data`에서 읽는다 |
|
|
33
|
+
| `clientName` | getter | `string \| undefined` | 클라이언트 앱 이름. `..`, `/`, `\`를 포함하면 에러를 던진다 (경로 탐색 공격 방지) |
|
|
34
|
+
| `clientPath` | getter | `string \| undefined` | `{rootPath}/www/{clientName}` 경로. `clientName`이 없으면 `undefined` |
|
|
35
|
+
| `getConfig<T>(section)` | method | `Promise<T>` | `.config.json`에서 섹션을 읽는다. 루트 설정을 먼저 읽고 클라이언트별 설정으로 덮어쓴다. 섹션이 없으면 에러를 던진다 |
|
|
36
|
+
|
|
37
|
+
## Related Types
|
|
38
|
+
|
|
39
|
+
### `createServiceContext`
|
|
40
|
+
|
|
41
|
+
`ServiceContext` 인스턴스를 생성한다.
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
function createServiceContext<TAuthInfo = unknown>(
|
|
45
|
+
server: ServiceServer<TAuthInfo>,
|
|
46
|
+
socket?: ServiceSocket,
|
|
47
|
+
http?: { clientName: string; authTokenPayload?: AuthTokenPayload<TAuthInfo> },
|
|
48
|
+
legacy?: { clientName?: string },
|
|
49
|
+
): ServiceContext<TAuthInfo>;
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
| Param | Type | Description |
|
|
53
|
+
|-------|------|-------------|
|
|
54
|
+
| `server` | `ServiceServer<TAuthInfo>` | 서버 인스턴스 |
|
|
55
|
+
| `socket` | `ServiceSocket` (optional) | WebSocket 연결 (WebSocket 요청 시) |
|
|
56
|
+
| `http` | `{ clientName: string; authTokenPayload? }` (optional) | HTTP 요청 정보 |
|
|
57
|
+
| `legacy` | `{ clientName?: string }` (optional) | V1 레거시 컨텍스트 |
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const MyService = defineService("My", (ctx) => ({
|
|
63
|
+
getProfile: () => {
|
|
64
|
+
// 인증 정보 접근
|
|
65
|
+
return ctx.authInfo;
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
readConfig: async () => {
|
|
69
|
+
// 설정 파일 읽기
|
|
70
|
+
const config = await ctx.getConfig<{ apiKey: string }>("myapp");
|
|
71
|
+
return config.apiKey;
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
socketOnly: () => {
|
|
75
|
+
if (ctx.socket == null) throw new Error("WebSocket만 허용");
|
|
76
|
+
return ctx.socket.clientName;
|
|
77
|
+
},
|
|
78
|
+
}));
|
|
79
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# handleV1Connection
|
|
2
|
+
|
|
3
|
+
V1 레거시 WebSocket 프로토콜 호환 레이어. 자동 업데이트(`SdAutoUpdateService.getLastVersion`)만 지원하고, 그 외 모든 요청은 업그레이드 필요 에러를 반환한다.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
function handleV1Connection(
|
|
7
|
+
socket: WebSocket,
|
|
8
|
+
autoUpdateMethods: { getLastVersion: (platform: string) => Promise<any> },
|
|
9
|
+
clientNameSetter?: (clientName: string | undefined) => void,
|
|
10
|
+
): void;
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Parameters
|
|
14
|
+
|
|
15
|
+
| Param | Type | Description |
|
|
16
|
+
|-------|------|-------------|
|
|
17
|
+
| `socket` | `WebSocket` | 기저 WebSocket 인스턴스 |
|
|
18
|
+
| `autoUpdateMethods` | `{ getLastVersion: (platform: string) => Promise<any> }` | AutoUpdateService의 메서드 객체 |
|
|
19
|
+
| `clientNameSetter` | `(clientName: string \| undefined) => void` (optional) | V1 요청의 `clientName`을 레거시 컨텍스트에 설정하는 콜백 |
|
|
20
|
+
|
|
21
|
+
V1 프로토콜:
|
|
22
|
+
- 연결 시 `{ name: "connected" }` 메시지를 전송한다
|
|
23
|
+
- 요청 형식: `{ uuid: string; command: string; params: unknown[]; clientName?: string }`
|
|
24
|
+
- 응답 형식: `{ name: "response"; reqUuid: string; state: "success" | "error"; body: unknown }`
|
|
25
|
+
- `command`가 `"SdAutoUpdateService.getLastVersion"`이면 처리하고, 그 외는 `UPGRADE_REQUIRED` 에러를 반환한다
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# createServiceServer
|
|
2
|
+
|
|
3
|
+
`ServiceServer` 인스턴스를 생성하는 팩토리 함수.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
function createServiceServer<TAuthInfo = unknown>(
|
|
7
|
+
options: ServiceServerOptions,
|
|
8
|
+
): ServiceServer<TAuthInfo>;
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Parameters
|
|
12
|
+
|
|
13
|
+
| Param | Type | Description |
|
|
14
|
+
|-------|------|-------------|
|
|
15
|
+
| `options` | [`ServiceServerOptions`](../types/service-server-options.md) | 서버 설정 옵션 |
|
|
16
|
+
|
|
17
|
+
## Returns
|
|
18
|
+
|
|
19
|
+
`ServiceServer<TAuthInfo>` — 생성된 서버 인스턴스. `listen()`을 호출해야 실제로 시작된다.
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
const server = createServiceServer<MyAuthInfo>({
|
|
25
|
+
rootPath: "/app",
|
|
26
|
+
port: 3000,
|
|
27
|
+
auth: { jwtSecret: "secret" },
|
|
28
|
+
services: [UserService, OrmService],
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
await server.listen();
|
|
32
|
+
```
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# ServiceServer
|
|
2
|
+
|
|
3
|
+
Fastify를 래핑한 서비스 서버 클래스. WebSocket/HTTP 이중 전송, JWT 인증, 이벤트 브로드캐스트, graceful shutdown을 처리한다. `EventEmitter<{ ready: void; close: void }>`를 확장한다.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- ✅ Fastify 기반 서비스 서버를 생성하고 시작할 때
|
|
8
|
+
- ✅ WebSocket/HTTP 이중 전송으로 서비스를 제공할 때
|
|
9
|
+
- ✅ 서버에서 클라이언트에 이벤트를 브로드캐스트할 때
|
|
10
|
+
- ❌ 브라우저에서 서버에 연결 → `@simplysm/service-client`
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
class ServiceServer<TAuthInfo = unknown> extends EventEmitter<{
|
|
14
|
+
ready: void;
|
|
15
|
+
close: void;
|
|
16
|
+
}> {
|
|
17
|
+
isOpen: boolean;
|
|
18
|
+
readonly fastify: FastifyInstance;
|
|
19
|
+
readonly options: ServiceServerOptions;
|
|
20
|
+
|
|
21
|
+
constructor(options: ServiceServerOptions);
|
|
22
|
+
|
|
23
|
+
async listen(): Promise<void>;
|
|
24
|
+
async close(): Promise<void>;
|
|
25
|
+
getEvent<TEventDef extends ServiceEventDef>(eventName: string): ServerEventProxy<TEventDef>;
|
|
26
|
+
async emitEvent<TEventDef extends ServiceEventDef>(
|
|
27
|
+
eventName: string,
|
|
28
|
+
infoSelector: (item: TEventDef["$info"]) => boolean,
|
|
29
|
+
data: TEventDef["$data"],
|
|
30
|
+
): Promise<void>;
|
|
31
|
+
async signAuthToken(payload: AuthTokenPayload<TAuthInfo>): Promise<string>;
|
|
32
|
+
async verifyAuthToken(token: string): Promise<AuthTokenPayload<TAuthInfo>>;
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Members
|
|
37
|
+
|
|
38
|
+
| Member | Kind | Type | Description |
|
|
39
|
+
|--------|------|------|-------------|
|
|
40
|
+
| `isOpen` | property | `boolean` | 서버가 리스닝 중인지 여부 |
|
|
41
|
+
| `fastify` | property | `FastifyInstance` | 내부 Fastify 인스턴스. 직접 접근이 필요할 때 사용 |
|
|
42
|
+
| `options` | property | `ServiceServerOptions` | 생성 시 전달된 옵션 |
|
|
43
|
+
| `listen()` | method | `Promise<void>` | 서버를 시작한다. 플러그인 등록, 라우트 설정, SIGINT/SIGTERM 핸들러 등록을 수행한다. 완료 시 `ready` 이벤트를 발생시킨다 |
|
|
44
|
+
| `close()` | method | `Promise<void>` | 모든 WebSocket 연결을 닫고 Fastify 서버를 종료한다. 완료 시 `close` 이벤트를 발생시킨다 |
|
|
45
|
+
| `getEvent(eventName)` | method | `ServerEventProxy<TEventDef>` | 타입 안전한 이벤트 프록시를 반환한다. `emit(infoSelector, data)` 메서드를 포함 |
|
|
46
|
+
| `emitEvent(eventName, infoSelector, data)` | method | `Promise<void>` | `infoSelector`에 매칭되는 WebSocket 클라이언트에 이벤트를 브로드캐스트한다 |
|
|
47
|
+
| `signAuthToken(payload)` | method | `Promise<string>` | JWT 토큰을 서명한다. `options.auth`가 설정되지 않으면 에러를 던진다 |
|
|
48
|
+
| `verifyAuthToken(token)` | method | `Promise<AuthTokenPayload<TAuthInfo>>` | JWT 토큰을 검증하고 페이로드를 반환한다. `options.auth`가 설정되지 않으면 에러를 던진다 |
|
|
49
|
+
|
|
50
|
+
`listen()` 시 등록되는 라우트:
|
|
51
|
+
|
|
52
|
+
| Route | Method | Handler |
|
|
53
|
+
|-------|--------|---------|
|
|
54
|
+
| `/api/:service/:method` | GET/POST | `handleHttpRequest` — 서비스 메서드 호출 |
|
|
55
|
+
| `/upload` | POST | `handleUpload` — multipart 파일 업로드 |
|
|
56
|
+
| `/`, `/ws` | WebSocket | WebSocket 핸들러. `ver=2` 쿼리 시 V2 프로토콜, 그 외 V1 레거시 |
|
|
57
|
+
| `/*` | GET/POST/PUT/DELETE/PATCH/HEAD | `handleStaticFile` — 정적 파일 서빙 |
|
|
58
|
+
|
|
59
|
+
`listen()` 시 Fastify 플러그인 등록 순서: `@fastify/websocket` → `@fastify/helmet` → `@fastify/multipart` → `@fastify/static` → `@fastify/cors`
|
|
60
|
+
|
|
61
|
+
Graceful shutdown: `SIGINT`/`SIGTERM` 시그널 수신 시 `close()`를 호출하고, 10초 내에 종료되지 않으면 `process.exit(1)`로 강제 종료한다.
|
|
62
|
+
|
|
63
|
+
## Related Types
|
|
64
|
+
|
|
65
|
+
### `ServerEventProxy`
|
|
66
|
+
|
|
67
|
+
`getEvent()`가 반환하는 타입 안전한 이벤트 프록시 인터페이스.
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
interface ServerEventProxy<TEventDef extends ServiceEventDef> {
|
|
71
|
+
emit(
|
|
72
|
+
infoSelector: (item: TEventDef["$info"]) => boolean,
|
|
73
|
+
data: TEventDef["$data"],
|
|
74
|
+
): Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
| Method | Description |
|
|
79
|
+
|--------|-------------|
|
|
80
|
+
| `emit(infoSelector, data)` | `infoSelector`에 매칭되는 이벤트 리스너를 가진 WebSocket 클라이언트에 이벤트를 브로드캐스트한다 |
|
|
81
|
+
|
|
82
|
+
## Usage
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { createServiceServer, defineService, auth } from "@simplysm/service-server";
|
|
86
|
+
|
|
87
|
+
const HealthService = defineService("Health", (ctx) => ({
|
|
88
|
+
check: () => ({ status: "ok" }),
|
|
89
|
+
}));
|
|
90
|
+
|
|
91
|
+
const UserService = defineService("User", auth((ctx) => ({
|
|
92
|
+
getProfile: () => ctx.authInfo,
|
|
93
|
+
})));
|
|
94
|
+
|
|
95
|
+
const server = createServiceServer<{ userId: string }>({
|
|
96
|
+
rootPath: "/app",
|
|
97
|
+
port: 3000,
|
|
98
|
+
auth: { jwtSecret: "my-secret" },
|
|
99
|
+
services: [HealthService, UserService],
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
await server.listen();
|
|
103
|
+
|
|
104
|
+
// JWT 토큰 발급
|
|
105
|
+
const token = await server.signAuthToken({
|
|
106
|
+
roles: ["admin"],
|
|
107
|
+
data: { userId: "123" },
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// 이벤트 브로드캐스트
|
|
111
|
+
const evt = server.getEvent<typeof MyEvent>("MyEvent");
|
|
112
|
+
await evt.emit((info) => info.userId === "123", { name: "새 이름" });
|
|
113
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# ServerProtocolWrapper
|
|
2
|
+
|
|
3
|
+
메시지 인코딩/디코딩 래퍼 인터페이스. 무거운 메시지는 worker 스레드에 자동으로 위임하고, 가벼운 작업은 메인 스레드에서 처리한다.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
interface ServerProtocolWrapper {
|
|
7
|
+
encode(uuid: string, message: ServiceMessage): Promise<{ chunks: Bytes[]; totalSize: number }>;
|
|
8
|
+
decode(bytes: Bytes): Promise<ServiceMessageDecodeResult<ServiceMessage>>;
|
|
9
|
+
dispose(): void;
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Members
|
|
14
|
+
|
|
15
|
+
| Member | Kind | Type | Description |
|
|
16
|
+
|--------|------|------|-------------|
|
|
17
|
+
| `encode(uuid, message)` | method | `Promise<{ chunks: Bytes[]; totalSize: number }>` | 메시지를 인코딩한다. 바이너리 데이터(Uint8Array)가 포함된 메시지는 worker 스레드에 위임한다 |
|
|
18
|
+
| `decode(bytes)` | method | `Promise<ServiceMessageDecodeResult<ServiceMessage>>` | 메시지를 디코딩한다. 30KB 초과 메시지는 worker 스레드에 위임한다 |
|
|
19
|
+
| `dispose()` | method | `void` | 내부 프로토콜 리소스를 해제한다 |
|
|
20
|
+
|
|
21
|
+
Worker 위임 기준:
|
|
22
|
+
- **encode**: 메시지 body가 `Uint8Array`이거나, 배열 내에 `Uint8Array` 요소가 있을 때 worker 사용
|
|
23
|
+
- **decode**: 메시지 크기가 30KB(30 * 1024 바이트)를 초과할 때 worker 사용
|
|
24
|
+
|
|
25
|
+
Worker는 지연 싱글턴으로 생성되며, `maxOldGenerationSizeMb: 4096`의 리소스 제한이 설정되어 있다.
|
|
26
|
+
|
|
27
|
+
## Related Types
|
|
28
|
+
|
|
29
|
+
### `createServerProtocolWrapper`
|
|
30
|
+
|
|
31
|
+
`ServerProtocolWrapper` 인스턴스를 생성한다. 내부적으로 `@simplysm/service-common`의 `createServiceProtocol()`을 사용한다.
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
function createServerProtocolWrapper(): ServerProtocolWrapper;
|
|
35
|
+
```
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# AppStructureService
|
|
2
|
+
|
|
3
|
+
앱 구조 정보 서비스를 생성하는 팩토리 함수. `defineService`를 래핑하여 `Record<string, AppStructureItem[]>` 맵을 받아 서비스 정의를 반환한다. 인증 불필요.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- ✅ 클라이언트에 앱의 메뉴/페이지 구조 정보를 제공할 때
|
|
8
|
+
- ❌ 동적으로 변하는 구조를 제공해야 할 때는 별도 서비스를 정의한다 — `AppStructureService`는 생성 시 전달된 정적 맵을 반환한다
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
function AppStructureService(
|
|
12
|
+
itemsMap: Record<string, AppStructureItem[]>,
|
|
13
|
+
): ServiceDefinition;
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Parameters
|
|
17
|
+
|
|
18
|
+
| Param | Type | Description |
|
|
19
|
+
|-------|------|-------------|
|
|
20
|
+
| `itemsMap` | `Record<string, AppStructureItem[]>` | 앱 구조 아이템 맵. `AppStructureItem`은 `@simplysm/service-common`에서 import한다 |
|
|
21
|
+
|
|
22
|
+
## Returns
|
|
23
|
+
|
|
24
|
+
`ServiceDefinition` — `defineService("AppStructure", ...)`로 생성된 서비스 정의.
|
|
25
|
+
|
|
26
|
+
제공 메서드:
|
|
27
|
+
|
|
28
|
+
| Method | Signature | Description |
|
|
29
|
+
|--------|-----------|-------------|
|
|
30
|
+
| `getItems` | `() => Record<string, AppStructureItem[]>` | 생성 시 전달된 `itemsMap`을 그대로 반환한다 |
|
|
31
|
+
|
|
32
|
+
## Related Types
|
|
33
|
+
|
|
34
|
+
### `AppStructureServiceType`
|
|
35
|
+
|
|
36
|
+
`AppStructureService`가 반환하는 서비스의 메서드 시그니처 타입.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
type AppStructureServiceType = ServiceMethods<ReturnType<typeof AppStructureService>>;
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { AppStructureService } from "@simplysm/service-server";
|
|
46
|
+
import type { AppStructureItem } from "@simplysm/service-common";
|
|
47
|
+
|
|
48
|
+
const itemsMap: Record<string, AppStructureItem[]> = {
|
|
49
|
+
"my-client": [
|
|
50
|
+
{ title: "홈", path: "/home" },
|
|
51
|
+
{ title: "설정", path: "/settings" },
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const server = createServiceServer({
|
|
56
|
+
services: [AppStructureService(itemsMap)],
|
|
57
|
+
// ...
|
|
58
|
+
});
|
|
59
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# AutoUpdateService
|
|
2
|
+
|
|
3
|
+
자동 업데이트 서비스 정의. `defineService("AutoUpdate", (ctx) => ...)`로 정의되어 있다. 인증 불필요.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- ✅ 클라이언트 앱(Android APK / Windows EXE)의 자동 업데이트를 서버에서 제공할 때
|
|
8
|
+
- ❌ 웹 클라이언트 업데이트에는 사용하지 않는다 — 웹은 브라우저 캐시/서비스 워커로 처리한다
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
const AutoUpdateService: ServiceDefinition;
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Members
|
|
15
|
+
|
|
16
|
+
| Method | Signature | Description |
|
|
17
|
+
|--------|-----------|-------------|
|
|
18
|
+
| `getLastVersion` | `(platform: string) => Promise<{ version: string; downloadPath: string } \| undefined>` | `{clientPath}/{platform}/updates/` 디렉토리에서 최신 버전 파일을 찾아 반환한다 |
|
|
19
|
+
|
|
20
|
+
`getLastVersion` 동작:
|
|
21
|
+
- `platform`이 `"android"`이면 `.apk` 파일을, 그 외에는 `.exe` 파일을 탐색한다
|
|
22
|
+
- 파일명이 `{version}.{ext}` 형식이어야 하며 (예: `1.2.3.apk`), `semver.maxSatisfying`으로 최대 버전을 결정한다
|
|
23
|
+
- `clientPath`가 없으면 에러를 던진다
|
|
24
|
+
- 업데이트 디렉토리나 매칭 파일이 없으면 `undefined`를 반환한다
|
|
25
|
+
|
|
26
|
+
## Related Types
|
|
27
|
+
|
|
28
|
+
### `AutoUpdateServiceType`
|
|
29
|
+
|
|
30
|
+
`AutoUpdateService`의 메서드 시그니처 타입.
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
type AutoUpdateServiceType = ServiceMethods<typeof AutoUpdateService>;
|
|
34
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# OrmService
|
|
2
|
+
|
|
3
|
+
ORM 브리지 서비스 정의. WebSocket 전용이며 `auth()`로 래핑되어 로그인이 필수다. `defineService("Orm", auth((ctx) => ...))`로 정의되어 있다.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- ✅ 클라이언트에서 WebSocket을 통해 DB 연결/쿼리를 수행해야 할 때
|
|
8
|
+
- ❌ HTTP API로 DB 작업을 수행하려면 별도 서비스를 정의한다 — OrmService는 WebSocket 전용이다
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
const OrmService: ServiceDefinition;
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
소켓별 DB 연결 관리:
|
|
15
|
+
- `WeakMap<ServiceSocket, Map<number, DbConn>>`으로 소켓별 연결 상태를 관리한다
|
|
16
|
+
- 소켓이 닫히면 해당 소켓의 열린 DB 연결을 모두 자동 종료한다
|
|
17
|
+
- `getConfig("orm")`에서 `configName`으로 DB 연결 설정을 읽는다
|
|
18
|
+
|
|
19
|
+
HTTP 요청 시 "WebSocket 연결이 필요합니다" 에러를 던진다.
|
|
20
|
+
|
|
21
|
+
## Members
|
|
22
|
+
|
|
23
|
+
| Method | Signature | Description |
|
|
24
|
+
|--------|-----------|-------------|
|
|
25
|
+
| `getInfo` | `(opt: DbConnOptions & { configName: string }) => Promise<{ dialect: Dialect; database?: string; schema?: string }>` | DB 연결 정보를 반환한다. `mssql-azure` dialect은 `mssql`로 변환된다 |
|
|
26
|
+
| `connect` | `(opt: DbConnOptions & { configName: string }) => Promise<number>` | DB에 연결하고 연결 ID를 반환한다 |
|
|
27
|
+
| `close` | `(connId: number) => Promise<void>` | DB 연결을 종료한다 |
|
|
28
|
+
| `beginTransaction` | `(connId: number, isolationLevel?: IsolationLevel) => Promise<void>` | 트랜잭션을 시작한다 |
|
|
29
|
+
| `commitTransaction` | `(connId: number) => Promise<void>` | 트랜잭션을 커밋한다 |
|
|
30
|
+
| `rollbackTransaction` | `(connId: number) => Promise<void>` | 트랜잭션을 롤백한다 |
|
|
31
|
+
| `executeParametrized` | `(connId: number, query: string, params?: unknown[]) => Promise<unknown[][]>` | 파라미터화된 쿼리를 실행한다 |
|
|
32
|
+
| `executeDefs` | `(connId: number, defs: QueryDef[], options?: (ResultMeta \| undefined)[]) => Promise<unknown[][]>` | QueryDef 배열을 SQL로 변환하여 실행한다. `options`가 모두 `undefined`이면 쿼리를 합쳐 한 번에 실행한다 |
|
|
33
|
+
| `bulkInsert` | `(connId: number, tableName: string, columnDefs: Record<string, ColumnMeta>, records: Record<string, unknown>[]) => Promise<void>` | 대량 삽입을 수행한다 |
|
|
34
|
+
|
|
35
|
+
## Related Types
|
|
36
|
+
|
|
37
|
+
### `OrmServiceType`
|
|
38
|
+
|
|
39
|
+
`OrmService`의 메서드 시그니처 타입. 클라이언트 측 타입 공유에 사용한다.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
type OrmServiceType = ServiceMethods<typeof OrmService>;
|
|
43
|
+
```
|
package/claude/references/sd-simplysm-v14/service-server/transport-http/handle-http-request.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# handleHttpRequest
|
|
2
|
+
|
|
3
|
+
GET/POST `/api/:service/:method` 경로의 HTTP 요청을 처리한다. `x-sd-client-name` 헤더가 필수이며, `Authorization` 헤더가 있으면 JWT 토큰을 검증한다.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
async function handleHttpRequest<TAuthInfo = unknown>(
|
|
7
|
+
req: FastifyRequest,
|
|
8
|
+
reply: FastifyReply,
|
|
9
|
+
jwtSecret: string | undefined,
|
|
10
|
+
runMethod: (def: {
|
|
11
|
+
serviceName: string;
|
|
12
|
+
methodName: string;
|
|
13
|
+
params: unknown[];
|
|
14
|
+
http: { clientName: string; authTokenPayload?: AuthTokenPayload<TAuthInfo> };
|
|
15
|
+
}) => Promise<unknown>,
|
|
16
|
+
): Promise<void>;
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Parameters
|
|
20
|
+
|
|
21
|
+
| Param | Type | Description |
|
|
22
|
+
|-------|------|-------------|
|
|
23
|
+
| `req` | `FastifyRequest` | Fastify 요청 객체 |
|
|
24
|
+
| `reply` | `FastifyReply` | Fastify 응답 객체 |
|
|
25
|
+
| `jwtSecret` | `string \| undefined` | JWT 시크릿. `Authorization` 헤더가 있는데 시크릿이 없으면 에러를 던진다 |
|
|
26
|
+
| `runMethod` | `(def) => Promise<unknown>` | 서비스 메서드 실행 콜백 |
|
|
27
|
+
|
|
28
|
+
요청 매개변수 파싱:
|
|
29
|
+
- **GET**: `?json=` 쿼리 파라미터에서 JSON 배열을 파싱한다
|
|
30
|
+
- **POST**: 요청 본문이 JSON 배열이어야 한다. 배열이 아니면 400을 반환한다
|
|
31
|
+
- **그 외**: 405 Method Not Allowed를 반환한다
|
|
32
|
+
|
|
33
|
+
인증 실패 시 401 응답을 반환한다.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# handleStaticFile
|
|
2
|
+
|
|
3
|
+
정적 파일 서빙을 처리한다. 경로 탐색 공격 방지와 숨김 파일 접근 차단이 포함되어 있다.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
async function handleStaticFile(
|
|
7
|
+
req: FastifyRequest,
|
|
8
|
+
reply: FastifyReply,
|
|
9
|
+
rootPath: string,
|
|
10
|
+
urlPath: string,
|
|
11
|
+
): Promise<void>;
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Parameters
|
|
15
|
+
|
|
16
|
+
| Param | Type | Description |
|
|
17
|
+
|-------|------|-------------|
|
|
18
|
+
| `req` | `FastifyRequest` | Fastify 요청 객체 |
|
|
19
|
+
| `reply` | `FastifyReply` | Fastify 응답 객체 |
|
|
20
|
+
| `rootPath` | `string` | 서버 루트 경로. `{rootPath}/www/` 하위에서 파일을 찾는다 |
|
|
21
|
+
| `urlPath` | `string` | 요청 URL 경로 (슬래시 제거됨) |
|
|
22
|
+
|
|
23
|
+
보안 처리:
|
|
24
|
+
- `{rootPath}/www/` 외부 경로 접근 시 에러를 던진다 (경로 탐색 공격 방지)
|
|
25
|
+
- `.`으로 시작하는 파일은 403 Forbidden을 반환한다
|
|
26
|
+
|
|
27
|
+
디렉토리 처리:
|
|
28
|
+
- 디렉토리 요청 시 끝에 슬래시가 없으면 슬래시를 추가하여 리다이렉트한다
|
|
29
|
+
- 디렉토리에 대해 `index.html`을 자동으로 서빙한다
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# handleUpload
|
|
2
|
+
|
|
3
|
+
`/upload` 경로의 multipart 파일 업로드를 처리한다. 인증 필수 (Authorization 헤더 필수).
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
async function handleUpload(
|
|
7
|
+
req: FastifyRequest,
|
|
8
|
+
reply: FastifyReply,
|
|
9
|
+
rootPath: string,
|
|
10
|
+
jwtSecret: string | undefined,
|
|
11
|
+
): Promise<void>;
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Parameters
|
|
15
|
+
|
|
16
|
+
| Param | Type | Description |
|
|
17
|
+
|-------|------|-------------|
|
|
18
|
+
| `req` | `FastifyRequest` | Fastify 요청 객체 |
|
|
19
|
+
| `reply` | `FastifyReply` | Fastify 응답 객체 |
|
|
20
|
+
| `rootPath` | `string` | 서버 루트 경로. 파일은 `{rootPath}/www/uploads/`에 저장된다 |
|
|
21
|
+
| `jwtSecret` | `string \| undefined` | JWT 시크릿 |
|
|
22
|
+
|
|
23
|
+
동작:
|
|
24
|
+
- 파일명은 UUID로 변환되고 원래 확장자를 유지한다
|
|
25
|
+
- 파일 크기 제한 초과 시 에러를 던진다
|
|
26
|
+
- 에러 발생 시 불완전한 파일과 이미 저장된 파일을 모두 정리한다
|
|
27
|
+
|
|
28
|
+
응답: `ServiceUploadResult[]` (from `@simplysm/service-common`)
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// ServiceUploadResult 구조
|
|
32
|
+
{ path: "uploads/{uuid}.ext", filename: "원본파일명.ext", size: number }
|
|
33
|
+
```
|