@pwfabric/runtime 0.0.0-stage → 1.0.0-rc.1
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/LICENSE +90 -0
- package/README.md +43 -2
- package/dist/a11y/announcer.d.ts +65 -0
- package/dist/a11y/announcer.js +140 -0
- package/dist/a11y/announcer.js.map +1 -0
- package/dist/a11y/contrast.d.ts +54 -0
- package/dist/a11y/contrast.js +93 -0
- package/dist/a11y/contrast.js.map +1 -0
- package/dist/a11y/focus.d.ts +123 -0
- package/dist/a11y/focus.js +282 -0
- package/dist/a11y/focus.js.map +1 -0
- package/dist/a11y/index.d.ts +21 -0
- package/dist/a11y/index.js +18 -0
- package/dist/a11y/index.js.map +1 -0
- package/dist/a11y/keyboard.d.ts +144 -0
- package/dist/a11y/keyboard.js +317 -0
- package/dist/a11y/keyboard.js.map +1 -0
- package/dist/adapters/default-image.d.ts +25 -0
- package/dist/adapters/default-image.js +37 -0
- package/dist/adapters/default-image.js.map +1 -0
- package/dist/adapters/index.d.ts +27 -0
- package/dist/adapters/index.js +28 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/next-image.d.ts +38 -0
- package/dist/adapters/next-image.js +124 -0
- package/dist/adapters/next-image.js.map +1 -0
- package/dist/adapters/types.d.ts +61 -0
- package/dist/adapters/types.js +11 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/analytics/index.d.ts +14 -0
- package/dist/analytics/index.js +15 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/tracker.d.ts +65 -0
- package/dist/analytics/tracker.js +251 -0
- package/dist/analytics/tracker.js.map +1 -0
- package/dist/analytics/types.d.ts +130 -0
- package/dist/analytics/types.js +11 -0
- package/dist/analytics/types.js.map +1 -0
- package/dist/auth/index.d.ts +15 -0
- package/dist/auth/index.js +14 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/provider.d.ts +132 -0
- package/dist/auth/provider.js +473 -0
- package/dist/auth/provider.js.map +1 -0
- package/dist/auth/types.d.ts +117 -0
- package/dist/auth/types.js +9 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/binding/collection.d.ts +190 -0
- package/dist/binding/collection.js +358 -0
- package/dist/binding/collection.js.map +1 -0
- package/dist/binding/datasource.d.ts +319 -0
- package/dist/binding/datasource.js +556 -0
- package/dist/binding/datasource.js.map +1 -0
- package/dist/binding/engine.d.ts +65 -0
- package/dist/binding/engine.js +268 -0
- package/dist/binding/engine.js.map +1 -0
- package/dist/binding/expression.d.ts +150 -0
- package/dist/binding/expression.js +787 -0
- package/dist/binding/expression.js.map +1 -0
- package/dist/binding/index.d.ts +19 -0
- package/dist/binding/index.js +14 -0
- package/dist/binding/index.js.map +1 -0
- package/dist/binding/two-way.d.ts +149 -0
- package/dist/binding/two-way.js +462 -0
- package/dist/binding/two-way.js.map +1 -0
- package/dist/binding/types.d.ts +119 -0
- package/dist/binding/types.js +9 -0
- package/dist/binding/types.js.map +1 -0
- package/dist/blocks/component-types.d.ts +81 -0
- package/dist/blocks/component-types.js +11 -0
- package/dist/blocks/component-types.js.map +1 -0
- package/dist/blocks/composition-rules.d.ts +168 -0
- package/dist/blocks/composition-rules.js +391 -0
- package/dist/blocks/composition-rules.js.map +1 -0
- package/dist/blocks/hooks.d.ts +31 -0
- package/dist/blocks/hooks.js +42 -0
- package/dist/blocks/hooks.js.map +1 -0
- package/dist/blocks/index.d.ts +14 -0
- package/dist/blocks/index.js +23 -0
- package/dist/blocks/index.js.map +1 -0
- package/dist/blocks/registry.d.ts +84 -0
- package/dist/blocks/registry.js +136 -0
- package/dist/blocks/registry.js.map +1 -0
- package/dist/blocks/rule-engine.d.ts +131 -0
- package/dist/blocks/rule-engine.js +321 -0
- package/dist/blocks/rule-engine.js.map +1 -0
- package/dist/blocks/surface-event-context.d.ts +13 -0
- package/dist/blocks/surface-event-context.js +14 -0
- package/dist/blocks/surface-event-context.js.map +1 -0
- package/dist/blocks/surface-id-context.d.ts +13 -0
- package/dist/blocks/surface-id-context.js +15 -0
- package/dist/blocks/surface-id-context.js.map +1 -0
- package/dist/bus.d.ts +41 -0
- package/dist/bus.js +158 -0
- package/dist/bus.js.map +1 -0
- package/dist/cache/index.d.ts +9 -0
- package/dist/cache/index.js +10 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/memory.d.ts +32 -0
- package/dist/cache/memory.js +138 -0
- package/dist/cache/memory.js.map +1 -0
- package/dist/cache/types.d.ts +62 -0
- package/dist/cache/types.js +9 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/capability/index.d.ts +72 -0
- package/dist/capability/index.js +87 -0
- package/dist/capability/index.js.map +1 -0
- package/dist/capability/kernel-capabilities.d.ts +31 -0
- package/dist/capability/kernel-capabilities.js +36 -0
- package/dist/capability/kernel-capabilities.js.map +1 -0
- package/dist/capability/platform-capabilities.d.ts +71 -0
- package/dist/capability/platform-capabilities.js +267 -0
- package/dist/capability/platform-capabilities.js.map +1 -0
- package/dist/capability/type-mapping.d.ts +70 -0
- package/dist/capability/type-mapping.js +107 -0
- package/dist/capability/type-mapping.js.map +1 -0
- package/dist/capability/validation.d.ts +46 -0
- package/dist/capability/validation.js +54 -0
- package/dist/capability/validation.js.map +1 -0
- package/dist/connectors/declared-connector.d.ts +48 -0
- package/dist/connectors/declared-connector.js +333 -0
- package/dist/connectors/declared-connector.js.map +1 -0
- package/dist/connectors/engine-registry.d.ts +50 -0
- package/dist/connectors/engine-registry.js +135 -0
- package/dist/connectors/engine-registry.js.map +1 -0
- package/dist/connectors/index.d.ts +14 -0
- package/dist/connectors/index.js +14 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/module-loader.d.ts +70 -0
- package/dist/connectors/module-loader.js +143 -0
- package/dist/connectors/module-loader.js.map +1 -0
- package/dist/connectors/types.d.ts +174 -0
- package/dist/connectors/types.js +23 -0
- package/dist/connectors/types.js.map +1 -0
- package/dist/context.d.ts +27 -0
- package/dist/context.js +38 -0
- package/dist/context.js.map +1 -0
- package/dist/data/DataCapabilityProvider.d.ts +39 -0
- package/dist/data/DataCapabilityProvider.js +58 -0
- package/dist/data/DataCapabilityProvider.js.map +1 -0
- package/dist/data/index.d.ts +17 -0
- package/dist/data/index.js +18 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data/manager.d.ts +40 -0
- package/dist/data/manager.js +442 -0
- package/dist/data/manager.js.map +1 -0
- package/dist/data/types.d.ts +218 -0
- package/dist/data/types.js +2 -0
- package/dist/data/types.js.map +1 -0
- package/dist/entity/aggregate.d.ts +8 -0
- package/dist/entity/aggregate.js +24 -0
- package/dist/entity/aggregate.js.map +1 -0
- package/dist/entity/apply-query.d.ts +58 -0
- package/dist/entity/apply-query.js +264 -0
- package/dist/entity/apply-query.js.map +1 -0
- package/dist/entity/behavior.d.ts +94 -0
- package/dist/entity/behavior.js +78 -0
- package/dist/entity/behavior.js.map +1 -0
- package/dist/entity/connector.d.ts +141 -0
- package/dist/entity/connector.js +89 -0
- package/dist/entity/connector.js.map +1 -0
- package/dist/entity/connectors/index.d.ts +12 -0
- package/dist/entity/connectors/index.js +11 -0
- package/dist/entity/connectors/index.js.map +1 -0
- package/dist/entity/connectors/static.d.ts +51 -0
- package/dist/entity/connectors/static.js +245 -0
- package/dist/entity/connectors/static.js.map +1 -0
- package/dist/entity/entity-datasource.d.ts +50 -0
- package/dist/entity/entity-datasource.js +33 -0
- package/dist/entity/entity-datasource.js.map +1 -0
- package/dist/entity/facade.d.ts +70 -0
- package/dist/entity/facade.js +70 -0
- package/dist/entity/facade.js.map +1 -0
- package/dist/entity/http-connector.d.ts +123 -0
- package/dist/entity/http-connector.js +295 -0
- package/dist/entity/http-connector.js.map +1 -0
- package/dist/entity/index.d.ts +38 -0
- package/dist/entity/index.js +31 -0
- package/dist/entity/index.js.map +1 -0
- package/dist/entity/postgres-connector.d.ts +64 -0
- package/dist/entity/postgres-connector.js +239 -0
- package/dist/entity/postgres-connector.js.map +1 -0
- package/dist/entity/registry.d.ts +59 -0
- package/dist/entity/registry.js +90 -0
- package/dist/entity/registry.js.map +1 -0
- package/dist/entity/store.d.ts +66 -0
- package/dist/entity/store.js +349 -0
- package/dist/entity/store.js.map +1 -0
- package/dist/entity/types.d.ts +180 -0
- package/dist/entity/types.js +10 -0
- package/dist/entity/types.js.map +1 -0
- package/dist/execution-context.d.ts +88 -0
- package/dist/execution-context.js +146 -0
- package/dist/execution-context.js.map +1 -0
- package/dist/executor.d.ts +27 -0
- package/dist/executor.js +33 -0
- package/dist/executor.js.map +1 -0
- package/dist/forms/form-entity-bridge.d.ts +94 -0
- package/dist/forms/form-entity-bridge.js +96 -0
- package/dist/forms/form-entity-bridge.js.map +1 -0
- package/dist/forms/form-write-target.d.ts +34 -0
- package/dist/forms/form-write-target.js +81 -0
- package/dist/forms/form-write-target.js.map +1 -0
- package/dist/forms/index.d.ts +22 -0
- package/dist/forms/index.js +25 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/forms/named-control-values.d.ts +27 -0
- package/dist/forms/named-control-values.js +42 -0
- package/dist/forms/named-control-values.js.map +1 -0
- package/dist/forms/processor.d.ts +55 -0
- package/dist/forms/processor.js +154 -0
- package/dist/forms/processor.js.map +1 -0
- package/dist/forms/types.d.ts +174 -0
- package/dist/forms/types.js +33 -0
- package/dist/forms/types.js.map +1 -0
- package/dist/forms/validator.d.ts +61 -0
- package/dist/forms/validator.js +218 -0
- package/dist/forms/validator.js.map +1 -0
- package/dist/graph/index.d.ts +10 -0
- package/dist/graph/index.js +9 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/resolver.d.ts +66 -0
- package/dist/graph/resolver.js +243 -0
- package/dist/graph/resolver.js.map +1 -0
- package/dist/graph/types.d.ts +125 -0
- package/dist/graph/types.js +9 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/hooks/useInstalledAtoms.d.ts +96 -0
- package/dist/hooks/useInstalledAtoms.js +92 -0
- package/dist/hooks/useInstalledAtoms.js.map +1 -0
- package/dist/i18n/index.d.ts +15 -0
- package/dist/i18n/index.js +14 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/translator.d.ts +76 -0
- package/dist/i18n/translator.js +357 -0
- package/dist/i18n/translator.js.map +1 -0
- package/dist/i18n/types.d.ts +93 -0
- package/dist/i18n/types.js +9 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel.d.ts +47 -0
- package/dist/kernel.js +258 -0
- package/dist/kernel.js.map +1 -0
- package/dist/perf/budget.d.ts +92 -0
- package/dist/perf/budget.js +122 -0
- package/dist/perf/budget.js.map +1 -0
- package/dist/perf/index.d.ts +16 -0
- package/dist/perf/index.js +13 -0
- package/dist/perf/index.js.map +1 -0
- package/dist/perf/render-timer.d.ts +90 -0
- package/dist/perf/render-timer.js +136 -0
- package/dist/perf/render-timer.js.map +1 -0
- package/dist/perf/reporter.d.ts +126 -0
- package/dist/perf/reporter.js +241 -0
- package/dist/perf/reporter.js.map +1 -0
- package/dist/perf/web-vitals.d.ts +111 -0
- package/dist/perf/web-vitals.js +268 -0
- package/dist/perf/web-vitals.js.map +1 -0
- package/dist/registry.d.ts +63 -0
- package/dist/registry.js +126 -0
- package/dist/registry.js.map +1 -0
- package/dist/render/BehaviorSurfaceProvider.d.ts +65 -0
- package/dist/render/BehaviorSurfaceProvider.js +185 -0
- package/dist/render/BehaviorSurfaceProvider.js.map +1 -0
- package/dist/render/BlockErrorBoundary.d.ts +26 -0
- package/dist/render/BlockErrorBoundary.js +41 -0
- package/dist/render/BlockErrorBoundary.js.map +1 -0
- package/dist/render/DataBoundSurfaceRenderer.d.ts +78 -0
- package/dist/render/DataBoundSurfaceRenderer.js +998 -0
- package/dist/render/DataBoundSurfaceRenderer.js.map +1 -0
- package/dist/render/DynamicBlockWrapper.d.ts +23 -0
- package/dist/render/DynamicBlockWrapper.js +117 -0
- package/dist/render/DynamicBlockWrapper.js.map +1 -0
- package/dist/render/appearance-resolver.d.ts +50 -0
- package/dist/render/appearance-resolver.js +78 -0
- package/dist/render/appearance-resolver.js.map +1 -0
- package/dist/render/capability-gate.d.ts +69 -0
- package/dist/render/capability-gate.js +94 -0
- package/dist/render/capability-gate.js.map +1 -0
- package/dist/render/conditional-states-css.d.ts +41 -0
- package/dist/render/conditional-states-css.js +82 -0
- package/dist/render/conditional-states-css.js.map +1 -0
- package/dist/render/connections-context.d.ts +31 -0
- package/dist/render/connections-context.js +34 -0
- package/dist/render/connections-context.js.map +1 -0
- package/dist/render/dark-theme-css.d.ts +36 -0
- package/dist/render/dark-theme-css.js +67 -0
- package/dist/render/dark-theme-css.js.map +1 -0
- package/dist/render/data-binding-types.d.ts +191 -0
- package/dist/render/data-binding-types.js +11 -0
- package/dist/render/data-binding-types.js.map +1 -0
- package/dist/render/data-cache.d.ts +30 -0
- package/dist/render/data-cache.js +37 -0
- package/dist/render/data-cache.js.map +1 -0
- package/dist/render/derive-dark-theme.d.ts +17 -0
- package/dist/render/derive-dark-theme.js +18 -0
- package/dist/render/derive-dark-theme.js.map +1 -0
- package/dist/render/dynamic-artifact-context.d.ts +77 -0
- package/dist/render/dynamic-artifact-context.js +89 -0
- package/dist/render/dynamic-artifact-context.js.map +1 -0
- package/dist/render/dynamic-block-loader.d.ts +80 -0
- package/dist/render/dynamic-block-loader.js +197 -0
- package/dist/render/dynamic-block-loader.js.map +1 -0
- package/dist/render/endpoint.d.ts +18 -0
- package/dist/render/endpoint.js +109 -0
- package/dist/render/endpoint.js.map +1 -0
- package/dist/render/entity-facade-context.d.ts +34 -0
- package/dist/render/entity-facade-context.js +37 -0
- package/dist/render/entity-facade-context.js.map +1 -0
- package/dist/render/group-states-css.d.ts +41 -0
- package/dist/render/group-states-css.js +73 -0
- package/dist/render/group-states-css.js.map +1 -0
- package/dist/render/hooks/useSurfaceEvents.d.ts +8 -0
- package/dist/render/hooks/useSurfaceEvents.js +9 -0
- package/dist/render/hooks/useSurfaceEvents.js.map +1 -0
- package/dist/render/hooks/useSurfaceId.d.ts +8 -0
- package/dist/render/hooks/useSurfaceId.js +9 -0
- package/dist/render/hooks/useSurfaceId.js.map +1 -0
- package/dist/render/index.d.ts +48 -0
- package/dist/render/index.js +61 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/interaction-rule-engine.d.ts +12 -0
- package/dist/render/interaction-rule-engine.js +47 -0
- package/dist/render/interaction-rule-engine.js.map +1 -0
- package/dist/render/keyframes-css.d.ts +31 -0
- package/dist/render/keyframes-css.js +44 -0
- package/dist/render/keyframes-css.js.map +1 -0
- package/dist/render/query-state.d.ts +3 -0
- package/dist/render/query-state.js +70 -0
- package/dist/render/query-state.js.map +1 -0
- package/dist/render/renderer.d.ts +44 -0
- package/dist/render/renderer.js +937 -0
- package/dist/render/renderer.js.map +1 -0
- package/dist/render/resolve-expressions.d.ts +37 -0
- package/dist/render/resolve-expressions.js +309 -0
- package/dist/render/resolve-expressions.js.map +1 -0
- package/dist/render/responsive-style-css.d.ts +42 -0
- package/dist/render/responsive-style-css.js +123 -0
- package/dist/render/responsive-style-css.js.map +1 -0
- package/dist/render/responsive.d.ts +49 -0
- package/dist/render/responsive.js +99 -0
- package/dist/render/responsive.js.map +1 -0
- package/dist/render/scoped-css.d.ts +71 -0
- package/dist/render/scoped-css.js +102 -0
- package/dist/render/scoped-css.js.map +1 -0
- package/dist/render/shell-selection.d.ts +69 -0
- package/dist/render/shell-selection.js +117 -0
- package/dist/render/shell-selection.js.map +1 -0
- package/dist/render/states-css.d.ts +32 -0
- package/dist/render/states-css.js +63 -0
- package/dist/render/states-css.js.map +1 -0
- package/dist/render/surface-data-context.d.ts +18 -0
- package/dist/render/surface-data-context.js +21 -0
- package/dist/render/surface-data-context.js.map +1 -0
- package/dist/render/surface-event-bus.d.ts +19 -0
- package/dist/render/surface-event-bus.js +68 -0
- package/dist/render/surface-event-bus.js.map +1 -0
- package/dist/render/surface-event-context.d.ts +11 -0
- package/dist/render/surface-event-context.js +12 -0
- package/dist/render/surface-event-context.js.map +1 -0
- package/dist/render/surface-id-context.d.ts +8 -0
- package/dist/render/surface-id-context.js +9 -0
- package/dist/render/surface-id-context.js.map +1 -0
- package/dist/render/theme-utils.d.ts +14 -0
- package/dist/render/theme-utils.js +15 -0
- package/dist/render/theme-utils.js.map +1 -0
- package/dist/render/types.d.ts +282 -0
- package/dist/render/types.js +9 -0
- package/dist/render/types.js.map +1 -0
- package/dist/render/visibility-css.d.ts +42 -0
- package/dist/render/visibility-css.js +119 -0
- package/dist/render/visibility-css.js.map +1 -0
- package/dist/render/width-scope.d.ts +34 -0
- package/dist/render/width-scope.js +44 -0
- package/dist/render/width-scope.js.map +1 -0
- package/dist/render/write-only-sources.d.ts +33 -0
- package/dist/render/write-only-sources.js +99 -0
- package/dist/render/write-only-sources.js.map +1 -0
- package/dist/routing/index.d.ts +14 -0
- package/dist/routing/index.js +15 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/router.d.ts +42 -0
- package/dist/routing/router.js +218 -0
- package/dist/routing/router.js.map +1 -0
- package/dist/routing/types.d.ts +124 -0
- package/dist/routing/types.js +9 -0
- package/dist/routing/types.js.map +1 -0
- package/dist/seo/generator.d.ts +39 -0
- package/dist/seo/generator.js +236 -0
- package/dist/seo/generator.js.map +1 -0
- package/dist/seo/index.d.ts +14 -0
- package/dist/seo/index.js +15 -0
- package/dist/seo/index.js.map +1 -0
- package/dist/seo/types.d.ts +181 -0
- package/dist/seo/types.js +9 -0
- package/dist/seo/types.js.map +1 -0
- package/dist/state/index.d.ts +15 -0
- package/dist/state/index.js +16 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/manager.d.ts +33 -0
- package/dist/state/manager.js +81 -0
- package/dist/state/manager.js.map +1 -0
- package/dist/state/store.d.ts +40 -0
- package/dist/state/store.js +145 -0
- package/dist/state/store.js.map +1 -0
- package/dist/state/types.d.ts +107 -0
- package/dist/state/types.js +9 -0
- package/dist/state/types.js.map +1 -0
- package/dist/surface/expression.d.ts +65 -0
- package/dist/surface/expression.js +179 -0
- package/dist/surface/expression.js.map +1 -0
- package/dist/surface/index.d.ts +32 -0
- package/dist/surface/index.js +25 -0
- package/dist/surface/index.js.map +1 -0
- package/dist/surface/interpreter.d.ts +96 -0
- package/dist/surface/interpreter.js +231 -0
- package/dist/surface/interpreter.js.map +1 -0
- package/dist/surface/layout.d.ts +54 -0
- package/dist/surface/layout.js +288 -0
- package/dist/surface/layout.js.map +1 -0
- package/dist/surface/output.d.ts +90 -0
- package/dist/surface/output.js +104 -0
- package/dist/surface/output.js.map +1 -0
- package/dist/surface/primitives.d.ts +180 -0
- package/dist/surface/primitives.js +339 -0
- package/dist/surface/primitives.js.map +1 -0
- package/dist/surface/renderer.d.ts +96 -0
- package/dist/surface/renderer.js +190 -0
- package/dist/surface/renderer.js.map +1 -0
- package/dist/surface/schemas.d.ts +181 -0
- package/dist/surface/schemas.js +142 -0
- package/dist/surface/schemas.js.map +1 -0
- package/dist/surface/transforms.d.ts +144 -0
- package/dist/surface/transforms.js +120 -0
- package/dist/surface/transforms.js.map +1 -0
- package/dist/surface/types.d.ts +160 -0
- package/dist/surface/types.js +51 -0
- package/dist/surface/types.js.map +1 -0
- package/dist/surface/validation.d.ts +123 -0
- package/dist/surface/validation.js +147 -0
- package/dist/surface/validation.js.map +1 -0
- package/dist/validator.d.ts +55 -0
- package/dist/validator.js +100 -0
- package/dist/validator.js.map +1 -0
- package/package.json +106 -3
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form Validator
|
|
3
|
+
*
|
|
4
|
+
* Form validation implementation
|
|
5
|
+
*
|
|
6
|
+
* @module @pwfabric/runtime/forms/validator
|
|
7
|
+
*/
|
|
8
|
+
import { z, type ZodType } from 'zod';
|
|
9
|
+
import type { FormValidator, FormField, FormValidationResult, ValidationMessages } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Default form validator implementation
|
|
12
|
+
*/
|
|
13
|
+
export declare class DefaultFormValidator implements FormValidator {
|
|
14
|
+
private readonly messages;
|
|
15
|
+
constructor(customMessages?: Partial<ValidationMessages>);
|
|
16
|
+
validateField(value: unknown, field: FormField): string[];
|
|
17
|
+
validateAll(values: Record<string, unknown>, fields: readonly FormField[]): FormValidationResult;
|
|
18
|
+
private validateRule;
|
|
19
|
+
private isEmpty;
|
|
20
|
+
private validateEmail;
|
|
21
|
+
private validateUrl;
|
|
22
|
+
private validateMinLength;
|
|
23
|
+
private validateMaxLength;
|
|
24
|
+
private validateMin;
|
|
25
|
+
private validateMax;
|
|
26
|
+
private validatePattern;
|
|
27
|
+
private formatMessage;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Validate values using a Zod schema
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateWithZod<T>(values: Record<string, unknown>, schema: ZodType<T>): FormValidationResult;
|
|
33
|
+
/**
|
|
34
|
+
* Common Zod schemas for form validation
|
|
35
|
+
*/
|
|
36
|
+
export declare const FormSchemas: {
|
|
37
|
+
/**
|
|
38
|
+
* Email validation schema
|
|
39
|
+
*/
|
|
40
|
+
email: z.ZodString;
|
|
41
|
+
/**
|
|
42
|
+
* Required string schema
|
|
43
|
+
*/
|
|
44
|
+
requiredString: z.ZodString;
|
|
45
|
+
/**
|
|
46
|
+
* URL validation schema
|
|
47
|
+
*/
|
|
48
|
+
url: z.ZodString;
|
|
49
|
+
/**
|
|
50
|
+
* Phone number schema (basic)
|
|
51
|
+
*/
|
|
52
|
+
phone: z.ZodString;
|
|
53
|
+
/**
|
|
54
|
+
* Password schema (min 8 chars, at least one number and letter)
|
|
55
|
+
*/
|
|
56
|
+
password: z.ZodString;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Create a form validator
|
|
60
|
+
*/
|
|
61
|
+
export declare function createFormValidator(customMessages?: Partial<ValidationMessages>): FormValidator;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form Validator
|
|
3
|
+
*
|
|
4
|
+
* Form validation implementation
|
|
5
|
+
*
|
|
6
|
+
* @module @pwfabric/runtime/forms/validator
|
|
7
|
+
*/
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import { DEFAULT_VALIDATION_MESSAGES } from './types.js';
|
|
10
|
+
// ============================================================
|
|
11
|
+
// DEFAULT FORM VALIDATOR
|
|
12
|
+
// ============================================================
|
|
13
|
+
/**
|
|
14
|
+
* Default form validator implementation
|
|
15
|
+
*/
|
|
16
|
+
export class DefaultFormValidator {
|
|
17
|
+
messages;
|
|
18
|
+
constructor(customMessages = {}) {
|
|
19
|
+
this.messages = { ...DEFAULT_VALIDATION_MESSAGES, ...customMessages };
|
|
20
|
+
}
|
|
21
|
+
validateField(value, field) {
|
|
22
|
+
const errors = [];
|
|
23
|
+
// Check required
|
|
24
|
+
if (field.required && this.isEmpty(value)) {
|
|
25
|
+
errors.push(this.messages.required);
|
|
26
|
+
return errors; // Return early if required and empty
|
|
27
|
+
}
|
|
28
|
+
// Skip other validations if value is empty and not required
|
|
29
|
+
if (this.isEmpty(value) && !field.required) {
|
|
30
|
+
return errors;
|
|
31
|
+
}
|
|
32
|
+
// Run custom validation rules
|
|
33
|
+
if (field.validation) {
|
|
34
|
+
for (const rule of field.validation) {
|
|
35
|
+
const error = this.validateRule(value, rule);
|
|
36
|
+
if (error) {
|
|
37
|
+
errors.push(error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return errors;
|
|
42
|
+
}
|
|
43
|
+
validateAll(values, fields) {
|
|
44
|
+
const errors = {};
|
|
45
|
+
let hasErrors = false;
|
|
46
|
+
for (const field of fields) {
|
|
47
|
+
const value = values[field.name];
|
|
48
|
+
const fieldErrors = this.validateField(value, field);
|
|
49
|
+
if (fieldErrors.length > 0) {
|
|
50
|
+
errors[field.name] = fieldErrors;
|
|
51
|
+
hasErrors = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
valid: !hasErrors,
|
|
56
|
+
errors,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
validateRule(value, rule) {
|
|
60
|
+
switch (rule.type) {
|
|
61
|
+
case 'required':
|
|
62
|
+
return this.isEmpty(value) ? rule.message : null;
|
|
63
|
+
case 'email':
|
|
64
|
+
return this.validateEmail(value, rule.message);
|
|
65
|
+
case 'url':
|
|
66
|
+
return this.validateUrl(value, rule.message);
|
|
67
|
+
case 'minLength':
|
|
68
|
+
return this.validateMinLength(value, rule.value, rule.message);
|
|
69
|
+
case 'maxLength':
|
|
70
|
+
return this.validateMaxLength(value, rule.value, rule.message);
|
|
71
|
+
case 'min':
|
|
72
|
+
return this.validateMin(value, rule.value, rule.message);
|
|
73
|
+
case 'max':
|
|
74
|
+
return this.validateMax(value, rule.value, rule.message);
|
|
75
|
+
case 'pattern':
|
|
76
|
+
return this.validatePattern(value, rule.value, rule.message);
|
|
77
|
+
case 'custom':
|
|
78
|
+
// Custom validation function is expected to be in rule.value
|
|
79
|
+
if (typeof rule.value === 'function') {
|
|
80
|
+
const isValid = rule.value(value);
|
|
81
|
+
return isValid ? null : rule.message;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
default:
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
isEmpty(value) {
|
|
89
|
+
if (value === null || value === undefined)
|
|
90
|
+
return true;
|
|
91
|
+
if (typeof value === 'string')
|
|
92
|
+
return value.trim() === '';
|
|
93
|
+
if (Array.isArray(value))
|
|
94
|
+
return value.length === 0;
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
validateEmail(value, message) {
|
|
98
|
+
if (typeof value !== 'string')
|
|
99
|
+
return message;
|
|
100
|
+
// Basic email regex - covers most common cases
|
|
101
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
102
|
+
return emailRegex.test(value) ? null : message;
|
|
103
|
+
}
|
|
104
|
+
validateUrl(value, message) {
|
|
105
|
+
if (typeof value !== 'string')
|
|
106
|
+
return message;
|
|
107
|
+
try {
|
|
108
|
+
new URL(value);
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return message;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
validateMinLength(value, minLength, message) {
|
|
116
|
+
if (typeof value !== 'string')
|
|
117
|
+
return message;
|
|
118
|
+
return value.length >= minLength ? null : this.formatMessage(message, minLength);
|
|
119
|
+
}
|
|
120
|
+
validateMaxLength(value, maxLength, message) {
|
|
121
|
+
if (typeof value !== 'string')
|
|
122
|
+
return message;
|
|
123
|
+
return value.length <= maxLength ? null : this.formatMessage(message, maxLength);
|
|
124
|
+
}
|
|
125
|
+
validateMin(value, min, message) {
|
|
126
|
+
const num = Number(value);
|
|
127
|
+
if (Number.isNaN(num))
|
|
128
|
+
return message;
|
|
129
|
+
return num >= min ? null : this.formatMessage(message, min);
|
|
130
|
+
}
|
|
131
|
+
validateMax(value, max, message) {
|
|
132
|
+
const num = Number(value);
|
|
133
|
+
if (Number.isNaN(num))
|
|
134
|
+
return message;
|
|
135
|
+
return num <= max ? null : this.formatMessage(message, max);
|
|
136
|
+
}
|
|
137
|
+
validatePattern(value, pattern, message) {
|
|
138
|
+
if (typeof value !== 'string')
|
|
139
|
+
return message;
|
|
140
|
+
const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;
|
|
141
|
+
return regex.test(value) ? null : message;
|
|
142
|
+
}
|
|
143
|
+
formatMessage(message, value) {
|
|
144
|
+
return message.replace('{value}', String(value));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// ============================================================
|
|
148
|
+
// ZOD SCHEMA VALIDATOR
|
|
149
|
+
// ============================================================
|
|
150
|
+
/**
|
|
151
|
+
* Validate values using a Zod schema
|
|
152
|
+
*/
|
|
153
|
+
export function validateWithZod(values, schema) {
|
|
154
|
+
const result = schema.safeParse(values);
|
|
155
|
+
if (result.success) {
|
|
156
|
+
return {
|
|
157
|
+
valid: true,
|
|
158
|
+
errors: {},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
valid: false,
|
|
163
|
+
errors: formatZodErrors(result.error),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Convert Zod errors to FormValidationResult format
|
|
168
|
+
*/
|
|
169
|
+
function formatZodErrors(error) {
|
|
170
|
+
const errors = {};
|
|
171
|
+
for (const issue of error.issues) {
|
|
172
|
+
const path = issue.path.join('.');
|
|
173
|
+
if (!errors[path]) {
|
|
174
|
+
errors[path] = [];
|
|
175
|
+
}
|
|
176
|
+
errors[path].push(issue.message);
|
|
177
|
+
}
|
|
178
|
+
return errors;
|
|
179
|
+
}
|
|
180
|
+
// ============================================================
|
|
181
|
+
// BUILT-IN ZOD SCHEMAS
|
|
182
|
+
// ============================================================
|
|
183
|
+
/**
|
|
184
|
+
* Common Zod schemas for form validation
|
|
185
|
+
*/
|
|
186
|
+
export const FormSchemas = {
|
|
187
|
+
/**
|
|
188
|
+
* Email validation schema
|
|
189
|
+
*/
|
|
190
|
+
email: z.string().email('Please enter a valid email address'),
|
|
191
|
+
/**
|
|
192
|
+
* Required string schema
|
|
193
|
+
*/
|
|
194
|
+
requiredString: z.string().min(1, 'This field is required'),
|
|
195
|
+
/**
|
|
196
|
+
* URL validation schema
|
|
197
|
+
*/
|
|
198
|
+
url: z.string().url('Please enter a valid URL'),
|
|
199
|
+
/**
|
|
200
|
+
* Phone number schema (basic)
|
|
201
|
+
*/
|
|
202
|
+
phone: z.string().regex(/^\+?[\d\s-()]+$/, 'Please enter a valid phone number'),
|
|
203
|
+
/**
|
|
204
|
+
* Password schema (min 8 chars, at least one number and letter)
|
|
205
|
+
*/
|
|
206
|
+
password: z
|
|
207
|
+
.string()
|
|
208
|
+
.min(8, 'Password must be at least 8 characters')
|
|
209
|
+
.regex(/[a-zA-Z]/, 'Password must contain at least one letter')
|
|
210
|
+
.regex(/[0-9]/, 'Password must contain at least one number'),
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* Create a form validator
|
|
214
|
+
*/
|
|
215
|
+
export function createFormValidator(customMessages) {
|
|
216
|
+
return new DefaultFormValidator(customMessages);
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/forms/validator.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Form Validator\n *\n * Form validation implementation\n *\n * @module @pwfabric/runtime/forms/validator\n */\n\nimport { z, type ZodType, type ZodError } from 'zod'\nimport type {\n FormValidator,\n FormField,\n ValidationRule,\n FormValidationResult,\n ValidationMessages,\n} from './types.js'\nimport { DEFAULT_VALIDATION_MESSAGES } from './types.js'\n\n// ============================================================\n// DEFAULT FORM VALIDATOR\n// ============================================================\n\n/**\n * Default form validator implementation\n */\nexport class DefaultFormValidator implements FormValidator {\n private readonly messages: ValidationMessages\n\n constructor(customMessages: Partial<ValidationMessages> = {}) {\n this.messages = { ...DEFAULT_VALIDATION_MESSAGES, ...customMessages }\n }\n\n validateField(value: unknown, field: FormField): string[] {\n const errors: string[] = []\n\n // Check required\n if (field.required && this.isEmpty(value)) {\n errors.push(this.messages.required)\n return errors // Return early if required and empty\n }\n\n // Skip other validations if value is empty and not required\n if (this.isEmpty(value) && !field.required) {\n return errors\n }\n\n // Run custom validation rules\n if (field.validation) {\n for (const rule of field.validation) {\n const error = this.validateRule(value, rule)\n if (error) {\n errors.push(error)\n }\n }\n }\n\n return errors\n }\n\n validateAll(values: Record<string, unknown>, fields: readonly FormField[]): FormValidationResult {\n const errors: Record<string, string[]> = {}\n let hasErrors = false\n\n for (const field of fields) {\n const value = values[field.name]\n const fieldErrors = this.validateField(value, field)\n\n if (fieldErrors.length > 0) {\n errors[field.name] = fieldErrors\n hasErrors = true\n }\n }\n\n return {\n valid: !hasErrors,\n errors,\n }\n }\n\n private validateRule(value: unknown, rule: ValidationRule): string | null {\n switch (rule.type) {\n case 'required':\n return this.isEmpty(value) ? rule.message : null\n\n case 'email':\n return this.validateEmail(value, rule.message)\n\n case 'url':\n return this.validateUrl(value, rule.message)\n\n case 'minLength':\n return this.validateMinLength(value, rule.value as number, rule.message)\n\n case 'maxLength':\n return this.validateMaxLength(value, rule.value as number, rule.message)\n\n case 'min':\n return this.validateMin(value, rule.value as number, rule.message)\n\n case 'max':\n return this.validateMax(value, rule.value as number, rule.message)\n\n case 'pattern':\n return this.validatePattern(value, rule.value as string | RegExp, rule.message)\n\n case 'custom':\n // Custom validation function is expected to be in rule.value\n if (typeof rule.value === 'function') {\n const isValid = (rule.value as (v: unknown) => boolean)(value)\n return isValid ? null : rule.message\n }\n return null\n\n default:\n return null\n }\n }\n\n private isEmpty(value: unknown): boolean {\n if (value === null || value === undefined) return true\n if (typeof value === 'string') return value.trim() === ''\n if (Array.isArray(value)) return value.length === 0\n return false\n }\n\n private validateEmail(value: unknown, message: string): string | null {\n if (typeof value !== 'string') return message\n\n // Basic email regex - covers most common cases\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n return emailRegex.test(value) ? null : message\n }\n\n private validateUrl(value: unknown, message: string): string | null {\n if (typeof value !== 'string') return message\n\n try {\n new URL(value)\n return null\n } catch {\n return message\n }\n }\n\n private validateMinLength(value: unknown, minLength: number, message: string): string | null {\n if (typeof value !== 'string') return message\n return value.length >= minLength ? null : this.formatMessage(message, minLength)\n }\n\n private validateMaxLength(value: unknown, maxLength: number, message: string): string | null {\n if (typeof value !== 'string') return message\n return value.length <= maxLength ? null : this.formatMessage(message, maxLength)\n }\n\n private validateMin(value: unknown, min: number, message: string): string | null {\n const num = Number(value)\n if (Number.isNaN(num)) return message\n return num >= min ? null : this.formatMessage(message, min)\n }\n\n private validateMax(value: unknown, max: number, message: string): string | null {\n const num = Number(value)\n if (Number.isNaN(num)) return message\n return num <= max ? null : this.formatMessage(message, max)\n }\n\n private validatePattern(\n value: unknown,\n pattern: string | RegExp,\n message: string\n ): string | null {\n if (typeof value !== 'string') return message\n\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern\n return regex.test(value) ? null : message\n }\n\n private formatMessage(message: string, value: unknown): string {\n return message.replace('{value}', String(value))\n }\n}\n\n// ============================================================\n// ZOD SCHEMA VALIDATOR\n// ============================================================\n\n/**\n * Validate values using a Zod schema\n */\nexport function validateWithZod<T>(\n values: Record<string, unknown>,\n schema: ZodType<T>\n): FormValidationResult {\n const result = schema.safeParse(values)\n\n if (result.success) {\n return {\n valid: true,\n errors: {},\n }\n }\n\n return {\n valid: false,\n errors: formatZodErrors(result.error),\n }\n}\n\n/**\n * Convert Zod errors to FormValidationResult format\n */\nfunction formatZodErrors(error: ZodError): Record<string, string[]> {\n const errors: Record<string, string[]> = {}\n\n for (const issue of error.issues) {\n const path = issue.path.join('.')\n if (!errors[path]) {\n errors[path] = []\n }\n errors[path].push(issue.message)\n }\n\n return errors\n}\n\n// ============================================================\n// BUILT-IN ZOD SCHEMAS\n// ============================================================\n\n/**\n * Common Zod schemas for form validation\n */\nexport const FormSchemas = {\n /**\n * Email validation schema\n */\n email: z.string().email('Please enter a valid email address'),\n\n /**\n * Required string schema\n */\n requiredString: z.string().min(1, 'This field is required'),\n\n /**\n * URL validation schema\n */\n url: z.string().url('Please enter a valid URL'),\n\n /**\n * Phone number schema (basic)\n */\n phone: z.string().regex(/^\\+?[\\d\\s-()]+$/, 'Please enter a valid phone number'),\n\n /**\n * Password schema (min 8 chars, at least one number and letter)\n */\n password: z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .regex(/[a-zA-Z]/, 'Password must contain at least one letter')\n .regex(/[0-9]/, 'Password must contain at least one number'),\n}\n\n/**\n * Create a form validator\n */\nexport function createFormValidator(customMessages?: Partial<ValidationMessages>): FormValidator {\n return new DefaultFormValidator(customMessages)\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph Module
|
|
3
|
+
*
|
|
4
|
+
* Microsoft Graph data resolution
|
|
5
|
+
*
|
|
6
|
+
* @module @pwfabric/runtime/graph
|
|
7
|
+
*/
|
|
8
|
+
export type { GraphResource, GraphQuery, GraphBatchRequest, GraphResponse, GraphCollectionResponse, GraphBatchResponse, GraphBatchResponseItem, GraphResult, GraphError, GraphUser, GraphGroup, GraphDriveItem, } from './types.js';
|
|
9
|
+
export type { GraphResolver, GraphResolverConfig } from './resolver.js';
|
|
10
|
+
export { RuntimeGraphResolver, createGraphResolver } from './resolver.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoBH,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA","sourcesContent":["/**\n * Graph Module\n *\n * Microsoft Graph data resolution\n *\n * @module @pwfabric/runtime/graph\n */\n\n// Types\nexport type {\n GraphResource,\n GraphQuery,\n GraphBatchRequest,\n GraphResponse,\n GraphCollectionResponse,\n GraphBatchResponse,\n GraphBatchResponseItem,\n GraphResult,\n GraphError,\n GraphUser,\n GraphGroup,\n GraphDriveItem,\n} from './types.js'\n\n// Resolver\nexport type { GraphResolver, GraphResolverConfig } from './resolver.js'\nexport { RuntimeGraphResolver, createGraphResolver } from './resolver.js'\n"]}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph Resolver
|
|
3
|
+
*
|
|
4
|
+
* Microsoft Graph data resolver
|
|
5
|
+
*
|
|
6
|
+
* @module @pwfabric/runtime/graph/resolver
|
|
7
|
+
*/
|
|
8
|
+
import type { AuthProvider } from '../auth/provider.js';
|
|
9
|
+
import type { GraphQuery, GraphResult, GraphBatchRequest, GraphBatchResponse } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Graph resolver interface
|
|
12
|
+
*/
|
|
13
|
+
export interface GraphResolver {
|
|
14
|
+
/**
|
|
15
|
+
* Execute a Graph query
|
|
16
|
+
*/
|
|
17
|
+
query<T>(query: GraphQuery): Promise<GraphResult<T>>;
|
|
18
|
+
/**
|
|
19
|
+
* Get a single resource
|
|
20
|
+
*/
|
|
21
|
+
get<T>(path: string): Promise<GraphResult<T>>;
|
|
22
|
+
/**
|
|
23
|
+
* Get a collection
|
|
24
|
+
*/
|
|
25
|
+
list<T>(path: string, query?: Partial<GraphQuery>): Promise<GraphResult<T[]>>;
|
|
26
|
+
/**
|
|
27
|
+
* Execute batch requests
|
|
28
|
+
*/
|
|
29
|
+
batch(requests: readonly GraphBatchRequest[]): Promise<GraphResult<GraphBatchResponse>>;
|
|
30
|
+
/**
|
|
31
|
+
* Get current user
|
|
32
|
+
*/
|
|
33
|
+
me<T>(): Promise<GraphResult<T>>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Graph resolver configuration
|
|
37
|
+
*/
|
|
38
|
+
export interface GraphResolverConfig {
|
|
39
|
+
readonly baseUrl?: string;
|
|
40
|
+
readonly version?: string;
|
|
41
|
+
readonly timeout?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Runtime Graph resolver implementation
|
|
45
|
+
*/
|
|
46
|
+
export declare class RuntimeGraphResolver implements GraphResolver {
|
|
47
|
+
private readonly authProvider;
|
|
48
|
+
private readonly config;
|
|
49
|
+
constructor(authProvider: AuthProvider, config?: GraphResolverConfig);
|
|
50
|
+
query<T>(query: GraphQuery): Promise<GraphResult<T>>;
|
|
51
|
+
get<T>(path: string): Promise<GraphResult<T>>;
|
|
52
|
+
list<T>(path: string, query?: Partial<GraphQuery>): Promise<GraphResult<T[]>>;
|
|
53
|
+
batch(requests: readonly GraphBatchRequest[]): Promise<GraphResult<GraphBatchResponse>>;
|
|
54
|
+
me<T>(): Promise<GraphResult<T>>;
|
|
55
|
+
private buildUrl;
|
|
56
|
+
private buildUrlWithParams;
|
|
57
|
+
private handleError;
|
|
58
|
+
/**
|
|
59
|
+
* Fetch wrapper for testability
|
|
60
|
+
*/
|
|
61
|
+
protected fetch(url: string, init: RequestInit): Promise<Response>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Create a Graph resolver
|
|
65
|
+
*/
|
|
66
|
+
export declare function createGraphResolver(authProvider: AuthProvider, config?: GraphResolverConfig): GraphResolver;
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph Resolver
|
|
3
|
+
*
|
|
4
|
+
* Microsoft Graph data resolver
|
|
5
|
+
*
|
|
6
|
+
* @module @pwfabric/runtime/graph/resolver
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================
|
|
9
|
+
// RUNTIME GRAPH RESOLVER
|
|
10
|
+
// ============================================================
|
|
11
|
+
/**
|
|
12
|
+
* Runtime Graph resolver implementation
|
|
13
|
+
*/
|
|
14
|
+
export class RuntimeGraphResolver {
|
|
15
|
+
authProvider;
|
|
16
|
+
config;
|
|
17
|
+
constructor(authProvider, config = {}) {
|
|
18
|
+
this.authProvider = authProvider;
|
|
19
|
+
this.config = {
|
|
20
|
+
baseUrl: config.baseUrl ?? 'https://graph.microsoft.com',
|
|
21
|
+
version: config.version ?? 'v1.0',
|
|
22
|
+
timeout: config.timeout ?? 30000,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
async query(query) {
|
|
26
|
+
const url = this.buildUrl(query);
|
|
27
|
+
return this.get(url);
|
|
28
|
+
}
|
|
29
|
+
async get(path) {
|
|
30
|
+
const tokenResult = await this.authProvider.acquireTokenSilent();
|
|
31
|
+
if (!tokenResult.success) {
|
|
32
|
+
return {
|
|
33
|
+
success: false,
|
|
34
|
+
error: {
|
|
35
|
+
type: 'auth_error',
|
|
36
|
+
message: tokenResult.error.message,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const fullUrl = path.startsWith('http')
|
|
42
|
+
? path
|
|
43
|
+
: `${this.config.baseUrl}/${this.config.version}/${path}`;
|
|
44
|
+
const response = await this.fetch(fullUrl, {
|
|
45
|
+
method: 'GET',
|
|
46
|
+
headers: {
|
|
47
|
+
Authorization: `Bearer ${tokenResult.token.accessToken}`,
|
|
48
|
+
'Content-Type': 'application/json',
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
return this.handleError(response);
|
|
53
|
+
}
|
|
54
|
+
const data = (await response.json());
|
|
55
|
+
const result = {
|
|
56
|
+
success: true,
|
|
57
|
+
data: (data.value ?? data),
|
|
58
|
+
};
|
|
59
|
+
if (data['@odata.nextLink'] !== undefined) {
|
|
60
|
+
return { ...result, nextLink: data['@odata.nextLink'] };
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
return {
|
|
66
|
+
success: false,
|
|
67
|
+
error: {
|
|
68
|
+
type: 'network_error',
|
|
69
|
+
message: `Request failed: ${e}`,
|
|
70
|
+
cause: e,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async list(path, query) {
|
|
76
|
+
const url = query ? this.buildUrlWithParams(path, query) : path;
|
|
77
|
+
const tokenResult = await this.authProvider.acquireTokenSilent();
|
|
78
|
+
if (!tokenResult.success) {
|
|
79
|
+
return {
|
|
80
|
+
success: false,
|
|
81
|
+
error: {
|
|
82
|
+
type: 'auth_error',
|
|
83
|
+
message: tokenResult.error.message,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const fullUrl = url.startsWith('http')
|
|
89
|
+
? url
|
|
90
|
+
: `${this.config.baseUrl}/${this.config.version}/${url}`;
|
|
91
|
+
const response = await this.fetch(fullUrl, {
|
|
92
|
+
method: 'GET',
|
|
93
|
+
headers: {
|
|
94
|
+
Authorization: `Bearer ${tokenResult.token.accessToken}`,
|
|
95
|
+
'Content-Type': 'application/json',
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
if (!response.ok) {
|
|
99
|
+
return this.handleError(response);
|
|
100
|
+
}
|
|
101
|
+
const data = (await response.json());
|
|
102
|
+
const result = {
|
|
103
|
+
success: true,
|
|
104
|
+
data: data.value ?? [],
|
|
105
|
+
};
|
|
106
|
+
if (data['@odata.nextLink'] !== undefined) {
|
|
107
|
+
return { ...result, nextLink: data['@odata.nextLink'] };
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
return {
|
|
113
|
+
success: false,
|
|
114
|
+
error: {
|
|
115
|
+
type: 'network_error',
|
|
116
|
+
message: `Request failed: ${e}`,
|
|
117
|
+
cause: e,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async batch(requests) {
|
|
123
|
+
const tokenResult = await this.authProvider.acquireTokenSilent();
|
|
124
|
+
if (!tokenResult.success) {
|
|
125
|
+
return {
|
|
126
|
+
success: false,
|
|
127
|
+
error: {
|
|
128
|
+
type: 'auth_error',
|
|
129
|
+
message: tokenResult.error.message,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
const response = await this.fetch(`${this.config.baseUrl}/${this.config.version}/$batch`, {
|
|
135
|
+
method: 'POST',
|
|
136
|
+
headers: {
|
|
137
|
+
Authorization: `Bearer ${tokenResult.token.accessToken}`,
|
|
138
|
+
'Content-Type': 'application/json',
|
|
139
|
+
},
|
|
140
|
+
body: JSON.stringify({ requests }),
|
|
141
|
+
});
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
return this.handleError(response);
|
|
144
|
+
}
|
|
145
|
+
const data = (await response.json());
|
|
146
|
+
return { success: true, data };
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
return {
|
|
150
|
+
success: false,
|
|
151
|
+
error: {
|
|
152
|
+
type: 'network_error',
|
|
153
|
+
message: `Batch request failed: ${e}`,
|
|
154
|
+
cause: e,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async me() {
|
|
160
|
+
return this.get('me');
|
|
161
|
+
}
|
|
162
|
+
buildUrl(query) {
|
|
163
|
+
let url = query.resource;
|
|
164
|
+
if (query.id) {
|
|
165
|
+
url += `/${query.id}`;
|
|
166
|
+
}
|
|
167
|
+
return this.buildUrlWithParams(url, query);
|
|
168
|
+
}
|
|
169
|
+
buildUrlWithParams(baseUrl, query) {
|
|
170
|
+
const params = new URLSearchParams();
|
|
171
|
+
if (query.select?.length) {
|
|
172
|
+
params.set('$select', query.select.join(','));
|
|
173
|
+
}
|
|
174
|
+
if (query.expand?.length) {
|
|
175
|
+
params.set('$expand', query.expand.join(','));
|
|
176
|
+
}
|
|
177
|
+
if (query.filter) {
|
|
178
|
+
params.set('$filter', query.filter);
|
|
179
|
+
}
|
|
180
|
+
if (query.orderBy) {
|
|
181
|
+
params.set('$orderby', query.orderBy);
|
|
182
|
+
}
|
|
183
|
+
if (query.top !== undefined) {
|
|
184
|
+
params.set('$top', String(query.top));
|
|
185
|
+
}
|
|
186
|
+
if (query.skip !== undefined) {
|
|
187
|
+
params.set('$skip', String(query.skip));
|
|
188
|
+
}
|
|
189
|
+
const queryString = params.toString();
|
|
190
|
+
return queryString ? `${baseUrl}?${queryString}` : baseUrl;
|
|
191
|
+
}
|
|
192
|
+
async handleError(response) {
|
|
193
|
+
let errorType = 'server_error';
|
|
194
|
+
switch (response.status) {
|
|
195
|
+
case 401:
|
|
196
|
+
errorType = 'auth_error';
|
|
197
|
+
break;
|
|
198
|
+
case 403:
|
|
199
|
+
errorType = 'forbidden';
|
|
200
|
+
break;
|
|
201
|
+
case 404:
|
|
202
|
+
errorType = 'not_found';
|
|
203
|
+
break;
|
|
204
|
+
case 429:
|
|
205
|
+
errorType = 'rate_limited';
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
let message = `HTTP ${response.status}`;
|
|
209
|
+
try {
|
|
210
|
+
const error = (await response.json());
|
|
211
|
+
if (error?.error?.message) {
|
|
212
|
+
message = error.error.message;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// Ignore JSON parse errors
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
success: false,
|
|
220
|
+
error: {
|
|
221
|
+
type: errorType,
|
|
222
|
+
message,
|
|
223
|
+
statusCode: response.status,
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Fetch wrapper for testability
|
|
229
|
+
*/
|
|
230
|
+
fetch(url, init) {
|
|
231
|
+
return fetch(url, {
|
|
232
|
+
...init,
|
|
233
|
+
signal: AbortSignal.timeout(this.config.timeout),
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Create a Graph resolver
|
|
239
|
+
*/
|
|
240
|
+
export function createGraphResolver(authProvider, config) {
|
|
241
|
+
return new RuntimeGraphResolver(authProvider, config);
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/graph/resolver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Graph Resolver\n *\n * Microsoft Graph data resolver\n *\n * @module @pwfabric/runtime/graph/resolver\n */\n\nimport type { AuthProvider } from '../auth/provider.js'\nimport type {\n GraphQuery,\n GraphResult,\n GraphError,\n GraphResponse,\n GraphCollectionResponse,\n GraphBatchRequest,\n GraphBatchResponse,\n} from './types.js'\n\n// ============================================================\n// GRAPH RESOLVER\n// ============================================================\n\n/**\n * Graph resolver interface\n */\nexport interface GraphResolver {\n /**\n * Execute a Graph query\n */\n query<T>(query: GraphQuery): Promise<GraphResult<T>>\n\n /**\n * Get a single resource\n */\n get<T>(path: string): Promise<GraphResult<T>>\n\n /**\n * Get a collection\n */\n list<T>(path: string, query?: Partial<GraphQuery>): Promise<GraphResult<T[]>>\n\n /**\n * Execute batch requests\n */\n batch(requests: readonly GraphBatchRequest[]): Promise<GraphResult<GraphBatchResponse>>\n\n /**\n * Get current user\n */\n me<T>(): Promise<GraphResult<T>>\n}\n\n/**\n * Graph resolver configuration\n */\nexport interface GraphResolverConfig {\n readonly baseUrl?: string\n readonly version?: string\n readonly timeout?: number\n}\n\n// ============================================================\n// RUNTIME GRAPH RESOLVER\n// ============================================================\n\n/**\n * Runtime Graph resolver implementation\n */\nexport class RuntimeGraphResolver implements GraphResolver {\n private readonly authProvider: AuthProvider\n private readonly config: Required<GraphResolverConfig>\n\n constructor(authProvider: AuthProvider, config: GraphResolverConfig = {}) {\n this.authProvider = authProvider\n this.config = {\n baseUrl: config.baseUrl ?? 'https://graph.microsoft.com',\n version: config.version ?? 'v1.0',\n timeout: config.timeout ?? 30000,\n }\n }\n\n async query<T>(query: GraphQuery): Promise<GraphResult<T>> {\n const url = this.buildUrl(query)\n return this.get<T>(url)\n }\n\n async get<T>(path: string): Promise<GraphResult<T>> {\n const tokenResult = await this.authProvider.acquireTokenSilent()\n if (!tokenResult.success) {\n return {\n success: false,\n error: {\n type: 'auth_error',\n message: tokenResult.error.message,\n },\n }\n }\n\n try {\n const fullUrl = path.startsWith('http')\n ? path\n : `${this.config.baseUrl}/${this.config.version}/${path}`\n\n const response = await this.fetch(fullUrl, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${tokenResult.token.accessToken}`,\n 'Content-Type': 'application/json',\n },\n })\n\n if (!response.ok) {\n return this.handleError(response)\n }\n\n const data = (await response.json()) as GraphResponse<T>\n const result: GraphResult<T> = {\n success: true,\n data: (data.value ?? data) as T,\n }\n if (data['@odata.nextLink'] !== undefined) {\n return { ...result, nextLink: data['@odata.nextLink'] }\n }\n return result\n } catch (e) {\n return {\n success: false,\n error: {\n type: 'network_error',\n message: `Request failed: ${e}`,\n cause: e,\n },\n }\n }\n }\n\n async list<T>(path: string, query?: Partial<GraphQuery>): Promise<GraphResult<T[]>> {\n const url = query ? this.buildUrlWithParams(path, query) : path\n\n const tokenResult = await this.authProvider.acquireTokenSilent()\n if (!tokenResult.success) {\n return {\n success: false,\n error: {\n type: 'auth_error',\n message: tokenResult.error.message,\n },\n }\n }\n\n try {\n const fullUrl = url.startsWith('http')\n ? url\n : `${this.config.baseUrl}/${this.config.version}/${url}`\n\n const response = await this.fetch(fullUrl, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${tokenResult.token.accessToken}`,\n 'Content-Type': 'application/json',\n },\n })\n\n if (!response.ok) {\n return this.handleError(response)\n }\n\n const data = (await response.json()) as GraphCollectionResponse<T>\n const result: GraphResult<T[]> = {\n success: true,\n data: data.value ?? [],\n }\n if (data['@odata.nextLink'] !== undefined) {\n return { ...result, nextLink: data['@odata.nextLink'] }\n }\n return result\n } catch (e) {\n return {\n success: false,\n error: {\n type: 'network_error',\n message: `Request failed: ${e}`,\n cause: e,\n },\n }\n }\n }\n\n async batch(requests: readonly GraphBatchRequest[]): Promise<GraphResult<GraphBatchResponse>> {\n const tokenResult = await this.authProvider.acquireTokenSilent()\n if (!tokenResult.success) {\n return {\n success: false,\n error: {\n type: 'auth_error',\n message: tokenResult.error.message,\n },\n }\n }\n\n try {\n const response = await this.fetch(`${this.config.baseUrl}/${this.config.version}/$batch`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${tokenResult.token.accessToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ requests }),\n })\n\n if (!response.ok) {\n return this.handleError(response)\n }\n\n const data = (await response.json()) as GraphBatchResponse\n return { success: true, data }\n } catch (e) {\n return {\n success: false,\n error: {\n type: 'network_error',\n message: `Batch request failed: ${e}`,\n cause: e,\n },\n }\n }\n }\n\n async me<T>(): Promise<GraphResult<T>> {\n return this.get<T>('me')\n }\n\n private buildUrl(query: GraphQuery): string {\n let url = query.resource\n if (query.id) {\n url += `/${query.id}`\n }\n return this.buildUrlWithParams(url, query)\n }\n\n private buildUrlWithParams(baseUrl: string, query: Partial<GraphQuery>): string {\n const params = new URLSearchParams()\n\n if (query.select?.length) {\n params.set('$select', query.select.join(','))\n }\n if (query.expand?.length) {\n params.set('$expand', query.expand.join(','))\n }\n if (query.filter) {\n params.set('$filter', query.filter)\n }\n if (query.orderBy) {\n params.set('$orderby', query.orderBy)\n }\n if (query.top !== undefined) {\n params.set('$top', String(query.top))\n }\n if (query.skip !== undefined) {\n params.set('$skip', String(query.skip))\n }\n\n const queryString = params.toString()\n return queryString ? `${baseUrl}?${queryString}` : baseUrl\n }\n\n private async handleError<T>(response: Response): Promise<GraphResult<T>> {\n let errorType: GraphError['type'] = 'server_error'\n\n switch (response.status) {\n case 401:\n errorType = 'auth_error'\n break\n case 403:\n errorType = 'forbidden'\n break\n case 404:\n errorType = 'not_found'\n break\n case 429:\n errorType = 'rate_limited'\n break\n }\n\n let message = `HTTP ${response.status}`\n try {\n const error = (await response.json()) as { error?: { message?: string; code?: string } }\n if (error?.error?.message) {\n message = error.error.message\n }\n } catch {\n // Ignore JSON parse errors\n }\n\n return {\n success: false,\n error: {\n type: errorType,\n message,\n statusCode: response.status,\n },\n }\n }\n\n /**\n * Fetch wrapper for testability\n */\n protected fetch(url: string, init: RequestInit): Promise<Response> {\n return fetch(url, {\n ...init,\n signal: AbortSignal.timeout(this.config.timeout),\n })\n }\n}\n\n/**\n * Create a Graph resolver\n */\nexport function createGraphResolver(\n authProvider: AuthProvider,\n config?: GraphResolverConfig\n): GraphResolver {\n return new RuntimeGraphResolver(authProvider, config)\n}\n"]}
|