sp2react 0.1.0__tar.gz
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.
- sp2react-0.1.0/CHANGELOG.md +19 -0
- sp2react-0.1.0/LICENSE +21 -0
- sp2react-0.1.0/MANIFEST.in +10 -0
- sp2react-0.1.0/PKG-INFO +238 -0
- sp2react-0.1.0/README.md +190 -0
- sp2react-0.1.0/SECURITY.md +47 -0
- sp2react-0.1.0/pyproject.toml +62 -0
- sp2react-0.1.0/setup.cfg +4 -0
- sp2react-0.1.0/src/sp2react/__init__.py +18 -0
- sp2react-0.1.0/src/sp2react/agents/__init__.py +0 -0
- sp2react-0.1.0/src/sp2react/agents/core.py +146 -0
- sp2react-0.1.0/src/sp2react/agents/prompts/dbmap.md +28 -0
- sp2react-0.1.0/src/sp2react/agents/prompts/fix.md +11 -0
- sp2react-0.1.0/src/sp2react/agents/prompts/handler.md +22 -0
- sp2react-0.1.0/src/sp2react/agents/prompts/page.md +40 -0
- sp2react-0.1.0/src/sp2react/agents/prompts/review.md +21 -0
- sp2react-0.1.0/src/sp2react/agents/prompts/spec.md +79 -0
- sp2react-0.1.0/src/sp2react/agents/tasks.py +374 -0
- sp2react-0.1.0/src/sp2react/analysis/__init__.py +0 -0
- sp2react-0.1.0/src/sp2react/analysis/aspx.py +254 -0
- sp2react-0.1.0/src/sp2react/analysis/behaviors.py +357 -0
- sp2react-0.1.0/src/sp2react/analysis/fields.py +152 -0
- sp2react-0.1.0/src/sp2react/analysis/inventory.py +314 -0
- sp2react-0.1.0/src/sp2react/analysis/jsscan.py +330 -0
- sp2react-0.1.0/src/sp2react/checks.py +105 -0
- sp2react-0.1.0/src/sp2react/cli.py +188 -0
- sp2react-0.1.0/src/sp2react/config.py +172 -0
- sp2react-0.1.0/src/sp2react/dbmap.py +245 -0
- sp2react-0.1.0/src/sp2react/llm/__init__.py +0 -0
- sp2react-0.1.0/src/sp2react/llm/providers.py +219 -0
- sp2react-0.1.0/src/sp2react/migrate.py +255 -0
- sp2react-0.1.0/src/sp2react/net.py +60 -0
- sp2react-0.1.0/src/sp2react/pipeline.py +583 -0
- sp2react-0.1.0/src/sp2react/scaffold/__init__.py +0 -0
- sp2react-0.1.0/src/sp2react/scaffold/generate.py +279 -0
- sp2react-0.1.0/src/sp2react/scaffold/rule_vectors.json +3826 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/__init__.py +0 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/api.py +293 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/auth.py +33 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/custom/__init__.py +22 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/main.py +47 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/odata.py +185 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/rules.py +256 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/sp_repo.py +159 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/sql_repo.py +437 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/store.py +224 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/requirements.txt +8 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/tests/conftest.py +10 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/backend/tests/test_rule_vectors.py +38 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/index.html +12 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/package.json +24 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/scripts/check-rules.ts +23 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/api.ts +88 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/Banner.tsx +4 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/DataTable.tsx +38 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/Form.tsx +252 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/GenericPage.tsx +28 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/Layout.tsx +54 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/LegacyHtml.tsx +9 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/ListView.tsx +59 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/Tiles.tsx +21 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/fields.tsx +132 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/custom/types.ts +10 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/main.tsx +14 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/runtime/format.ts +36 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/runtime/rules.ts +225 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/runtime/spec.ts +102 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/runtime/user.tsx +21 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/screens/LegacyRedirect.tsx +27 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/screens/ListFormScreen.tsx +33 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/styles/sp.css +95 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/vite-env.d.ts +1 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/tsconfig.json +18 -0
- sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/vite.config.ts +7 -0
- sp2react-0.1.0/src/sp2react/sharepoint/__init__.py +0 -0
- sp2react-0.1.0/src/sp2react/sharepoint/client.py +210 -0
- sp2react-0.1.0/src/sp2react/sharepoint/extract.py +217 -0
- sp2react-0.1.0/src/sp2react/spec/__init__.py +0 -0
- sp2react-0.1.0/src/sp2react/spec/base.py +80 -0
- sp2react-0.1.0/src/sp2react/spec/coverage.py +191 -0
- sp2react-0.1.0/src/sp2react/spec/model.py +133 -0
- sp2react-0.1.0/src/sp2react.egg-info/PKG-INFO +238 -0
- sp2react-0.1.0/src/sp2react.egg-info/SOURCES.txt +124 -0
- sp2react-0.1.0/src/sp2react.egg-info/dependency_links.txt +1 -0
- sp2react-0.1.0/src/sp2react.egg-info/entry_points.txt +2 -0
- sp2react-0.1.0/src/sp2react.egg-info/requires.txt +24 -0
- sp2react-0.1.0/src/sp2react.egg-info/top_level.txt +1 -0
- sp2react-0.1.0/tests/conftest.py +4 -0
- sp2react-0.1.0/tests/fixtures/agent_responses/dbmap/mapping.json +96 -0
- sp2react-0.1.0/tests/fixtures/agent_responses/page/Dashboard.txt +158 -0
- sp2react-0.1.0/tests/fixtures/agent_responses/spec/Dashboard.json +59 -0
- sp2react-0.1.0/tests/fixtures/agent_responses/spec/VendorRequests-form.json +97 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/files/Lists/VendorRequests/Attachments/2/customs-bond.pdf +5 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/css/dashboard.css +9 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/css/vendor-request.css +4 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/html/review-instructions.html +4 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/js/dashboard.js +112 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/js/jquery-1.12.4.min.js +2 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/js/jquery.SPServices-2014.02.min.js +6 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/js/vendor-request-form.js +214 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/lists/ComplianceAlerts/fields.json +299 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/lists/ComplianceAlerts/items.json +5 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/lists/CostCenters/fields.json +276 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/lists/CostCenters/items.json +104 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/lists/Countries/fields.json +285 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/lists/Countries/items.json +188 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/lists/Departments/fields.json +251 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/lists/Departments/items.json +58 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/lists/VendorRequests/fields.json +672 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/lists/VendorRequests/items.json +93 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/pages/Lists/VendorRequests/DispForm.aspx +105 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/pages/Lists/VendorRequests/EditForm.aspx +102 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/pages/Lists/VendorRequests/NewForm.aspx +90 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/pages/SitePages/Dashboard.aspx +21 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/pages/SitePages/Dashboard.aspx.webparts.json +77 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/rendered/SitePages/Dashboard.html +22 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/site.json +66 -0
- sp2react-0.1.0/tests/fixtures/legacy-site/siteusers.json +30 -0
- sp2react-0.1.0/tests/migrated_db.py +80 -0
- sp2react-0.1.0/tests/mock_sharepoint.py +171 -0
- sp2react-0.1.0/tests/scripted_agents.py +37 -0
- sp2react-0.1.0/tests/test_agents.py +140 -0
- sp2react-0.1.0/tests/test_extract_inventory.py +111 -0
- sp2react-0.1.0/tests/test_network.py +87 -0
- sp2react-0.1.0/tests/test_pipeline.py +203 -0
- sp2react-0.1.0/tests/ui_walkthrough.py +147 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `sp2react` are documented here.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] - 2026-10-29
|
|
6
|
+
|
|
7
|
+
First public release.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- Ten-stage pipeline (inputs, extract, inventory, spec, approve spec, convert, review, test, fix, approve) with gating: a stage only starts when the one before it is done
|
|
11
|
+
- Read-only SharePoint extraction: `.aspx` source, browser-added web parts, Script Editor / Content Editor content and links, JSLink, custom scripts and CSS, list schemas, views, forms, groups, navigation
|
|
12
|
+
- Inventory of jQuery / SPServices behaviour with file:line references (show/hide, read-only, defaults, cascades, PreSaveAction validation, group checks, redirects, REST and SPServices calls)
|
|
13
|
+
- Spec model, deterministic base spec and a coverage gate that blocks approval until every required behaviour is covered and legacy texts are verbatim
|
|
14
|
+
- AI agents (Claude through GitHub Copilot Bridger by default; Anthropic, OpenAI and Azure OpenAI also supported) for spec, page, custom handler, review, fix and database mapping, each validated before its output is accepted
|
|
15
|
+
- Generated React (Vite + TypeScript) + FastAPI app: shared list-form engine driven by the spec, the same rule engine in the browser and the API (checked by shared test vectors), legacy URL redirects, SharePoint groups as roles
|
|
16
|
+
- `data_source: database`: the generated API reads and writes your existing tables (MySQL, SQL Server, PostgreSQL via SQLAlchemy) through a reviewed list-to-table mapping drafted by `sp2react map-db`; filters, sorting and paging run as SQL
|
|
17
|
+
- `data_source: sqlite`: full paged export of list items and attachments, loaded into a SQLite copy
|
|
18
|
+
- Field-by-field reconciliation report between SharePoint lists and the app's data (opt-in in database mode)
|
|
19
|
+
- Network policy: every request is checked against the configured SharePoint and model hosts, including redirects; list items, attachments, people and rendered pages are never read in database mode
|
sp2react-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Karthikeyan Balasundaram
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
include README.md
|
|
2
|
+
include LICENSE
|
|
3
|
+
include CHANGELOG.md
|
|
4
|
+
include SECURITY.md
|
|
5
|
+
recursive-include src/sp2react/agents/prompts *.md
|
|
6
|
+
recursive-include src/sp2react/scaffold *
|
|
7
|
+
recursive-include tests *
|
|
8
|
+
prune examples
|
|
9
|
+
global-exclude __pycache__ *.py[cod] *.db
|
|
10
|
+
exclude CLAUDE.md
|
sp2react-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sp2react
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI-agent pipeline that converts classic SharePoint ASPX/jQuery list forms and pages into a React + FastAPI app on your existing database
|
|
5
|
+
Author: Karthikeyan Balasundaram
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/karthikbd/sp2react
|
|
8
|
+
Project-URL: Source Code, https://github.com/karthikbd/sp2react
|
|
9
|
+
Project-URL: Repository, https://github.com/karthikbd/sp2react
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/karthikbd/sp2react/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/karthikbd/sp2react/blob/main/CHANGELOG.md
|
|
12
|
+
Project-URL: Documentation, https://github.com/karthikbd/sp2react#readme
|
|
13
|
+
Keywords: sharepoint,sharepoint migration,react,fastapi,jquery,spservices,aspx,list forms,migration,code conversion,ai agents,claude
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
24
|
+
Classifier: Operating System :: OS Independent
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: pydantic>=2.5
|
|
29
|
+
Requires-Dist: pyyaml>=6.0
|
|
30
|
+
Requires-Dist: requests>=2.31
|
|
31
|
+
Provides-Extra: ntlm
|
|
32
|
+
Requires-Dist: requests-ntlm>=1.2; extra == "ntlm"
|
|
33
|
+
Provides-Extra: db
|
|
34
|
+
Requires-Dist: sqlalchemy>=2.0; extra == "db"
|
|
35
|
+
Provides-Extra: mysql
|
|
36
|
+
Requires-Dist: sqlalchemy>=2.0; extra == "mysql"
|
|
37
|
+
Requires-Dist: pymysql>=1.1; extra == "mysql"
|
|
38
|
+
Provides-Extra: mssql
|
|
39
|
+
Requires-Dist: sqlalchemy>=2.0; extra == "mssql"
|
|
40
|
+
Requires-Dist: pyodbc>=5.0; extra == "mssql"
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
43
|
+
Requires-Dist: fastapi>=0.110; extra == "dev"
|
|
44
|
+
Requires-Dist: httpx>=0.27; extra == "dev"
|
|
45
|
+
Requires-Dist: uvicorn>=0.27; extra == "dev"
|
|
46
|
+
Requires-Dist: sqlalchemy>=2.0; extra == "dev"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# sp2react
|
|
50
|
+
|
|
51
|
+
[](https://pypi.org/project/sp2react/)
|
|
52
|
+
[](https://pypi.org/project/sp2react/)
|
|
53
|
+
[](LICENSE)
|
|
54
|
+
[](https://securityscorecards.dev/viewer/?uri=github.com/karthikbd/sp2react)
|
|
55
|
+
|
|
56
|
+
Convert classic SharePoint (2013 / 2016 / 2019 / Subscription Edition) list forms and pages built with **ASPX, jQuery and SPServices** into a **React + FastAPI** app that runs on **your existing database**.
|
|
57
|
+
|
|
58
|
+
Plain code does everything mechanical. AI agents (Claude through your GitHub Copilot **Bridger** by default) do the parts that need judgement. Nothing an agent writes is accepted until it passes automatic checks.
|
|
59
|
+
|
|
60
|
+
**No business data over HTTP:** in the default `database` mode, list items, attachments and people are never read from SharePoint, and every request is checked against the hosts in your config.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Table of Contents
|
|
65
|
+
|
|
66
|
+
- [Installation](#installation)
|
|
67
|
+
- [Quick Start](#quick-start)
|
|
68
|
+
- [Configuration](#configuration)
|
|
69
|
+
- [The ten stages](#the-ten-stages)
|
|
70
|
+
- [Your existing database](#your-existing-database)
|
|
71
|
+
- [The generated app](#the-generated-app)
|
|
72
|
+
- [Use it from your own tool](#use-it-from-your-own-tool)
|
|
73
|
+
- [What converts and what does not](#what-converts-and-what-does-not)
|
|
74
|
+
- [Running Tests](#running-tests)
|
|
75
|
+
- [CI / CD](#ci--cd)
|
|
76
|
+
- [Security](#security)
|
|
77
|
+
- [Changelog](#changelog)
|
|
78
|
+
- [License](#license)
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Installation
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install "sp2react[mysql]" # MySQL / MariaDB tables
|
|
86
|
+
pip install "sp2react[mssql]" # SQL Server tables
|
|
87
|
+
pip install "sp2react[ntlm]" # add for on-premises Windows authentication
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Python 3.10+. Node.js 20+ is needed to build the generated React app.
|
|
91
|
+
|
|
92
|
+
## Quick Start
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
sp2react init # writes sp2react.yaml
|
|
96
|
+
export SP_USERNAME='CORP\me' SP_PASSWORD='...' # or SP_COOKIE / SP_TOKEN
|
|
97
|
+
export BRIDGER_TOKEN='...' # only if Bridger needs one
|
|
98
|
+
export SP2REACT_DB_URL='mysql+pymysql://user:password@db-host:3306/sea'
|
|
99
|
+
|
|
100
|
+
sp2react doctor # checks SharePoint, lists Bridger's Claude models
|
|
101
|
+
sp2react run --page /sites/SEA/SitePages/Dashboard.aspx --until spec
|
|
102
|
+
# review sp2react-work/specs/<screen>.coverage.md, then:
|
|
103
|
+
sp2react approve Dashboard
|
|
104
|
+
sp2react map-db # drafts db-mapping.json; review db-mapping.md
|
|
105
|
+
sp2react run --page /sites/SEA/SitePages/Dashboard.aspx --offline
|
|
106
|
+
sp2react status
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Configuration
|
|
110
|
+
|
|
111
|
+
```yaml
|
|
112
|
+
sharepoint:
|
|
113
|
+
site_url: https://sharepoint.example.com/sites/SEA
|
|
114
|
+
auth: ntlm # ntlm | cookie | bearer | none ; secrets come from environment variables
|
|
115
|
+
llm:
|
|
116
|
+
provider: bridger # bridger | anthropic | openai | azure_openai
|
|
117
|
+
api_format: anthropic # how Bridger serves Claude: anthropic (/v1/messages) or openai (/v1/chat/completions)
|
|
118
|
+
base_url: http://localhost:4141
|
|
119
|
+
model: claude-sonnet-4 # exact id from `sp2react doctor`
|
|
120
|
+
api_key_env: BRIDGER_TOKEN
|
|
121
|
+
pipeline:
|
|
122
|
+
data_source: database # database | sqlite | sharepoint
|
|
123
|
+
max_concurrency: 4
|
|
124
|
+
max_fix_iterations: 5
|
|
125
|
+
database:
|
|
126
|
+
url_env: SP2REACT_DB_URL
|
|
127
|
+
mapping: ./db-mapping.json
|
|
128
|
+
security:
|
|
129
|
+
allowed_hosts: []
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## The ten stages
|
|
133
|
+
|
|
134
|
+
Each stage starts only after the previous one has finished.
|
|
135
|
+
|
|
136
|
+
| # | Stage | Who | What happens | Checked by |
|
|
137
|
+
|---|---|---|---|---|
|
|
138
|
+
| 1 | inputs | code | config and connectivity | |
|
|
139
|
+
| 2 | extract | code | `.aspx` source, browser-added web parts, Script Editor / Content Editor content, JSLink, custom JS/CSS, list schemas, views, forms, group names, navigation. GET only | manifest of fetched files and errors |
|
|
140
|
+
| 3 | inventory | code | groups each list's New/Edit/Display forms into one screen and finds every jQuery behaviour and data call, with file:line | deterministic |
|
|
141
|
+
| 4 | spec | **agent** | builds the base spec from the schema, then the agent adds the rules that need interpretation | **coverage gate**: every required behaviour covered, legacy texts verbatim, rules valid |
|
|
142
|
+
| 5 | approve_spec | you | read `specs/<screen>.coverage.md` | |
|
|
143
|
+
| 6 | convert | code + **agents** | writes the fixed scaffold in seconds. List forms are rendered by the shared form engine from the spec; agents write only page components and custom handlers, in parallel | import whitelist, no fetch/jQuery/innerHTML, legacy texts present, `tsc` |
|
|
144
|
+
| 7 | review | **agent** | independent parity review | findings fed to fix |
|
|
145
|
+
| 8 | test | code | generated API tests, rule vectors (browser and API engines must agree), `tsc` + `vite build`, data reconciliation | |
|
|
146
|
+
| 9 | fix | **agent** | gets the real compiler and test output and edits only agent-owned files; up to N rounds | re-test |
|
|
147
|
+
| 10 | approve | you | | |
|
|
148
|
+
|
|
149
|
+
## Your existing database
|
|
150
|
+
|
|
151
|
+
If your team has already moved the list data into MySQL or SQL Server, the generated FastAPI app reads and writes those tables directly.
|
|
152
|
+
|
|
153
|
+
1. `sp2react map-db` reads the database **schema only** (tables, columns, types, keys).
|
|
154
|
+
2. It drafts the mapping: each list to a table, each field to a column, lookups to foreign keys, people to a users table or login column, plus created/modified/author/editor/version columns and attachments.
|
|
155
|
+
3. The `dbmap` agent resolves what the draft could not, for example `Countries.Title` migrated as `countries.country_name`.
|
|
156
|
+
4. Validation blocks code generation until every table and column exists and every required field is mapped.
|
|
157
|
+
5. You review `db-mapping.md`, and can edit `db-mapping.json` directly.
|
|
158
|
+
|
|
159
|
+
At runtime, OData-style queries from the forms and pages (`$filter`, `$orderby`, `$top`, lookup paths such as `Country/Title`) are translated to SQL. Optimistic concurrency uses your version column if you have one, otherwise the modified timestamp.
|
|
160
|
+
|
|
161
|
+
To check the earlier migration, set `security.sharepoint_item_reads: true`. `reconciliation.md` then compares every list item with its row, field by field, including orphaned lookups and attachment checksums.
|
|
162
|
+
|
|
163
|
+
## The generated app
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
cd converted-app/backend && pip install -r requirements.txt pymysql && cp .env.example .env && uvicorn app.main:app
|
|
167
|
+
cd converted-app/frontend && npm install && npm run dev
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
- Behaviour comes from the spec at runtime. `runtime/rules.ts` (browser) and `app/rules.py` (API) interpret the same rules, and shared vectors keep them in agreement, so a direct API call cannot bypass a rule.
|
|
171
|
+
- The form uses SharePoint's layout, labels and control titles, the legacy site CSS is carried over, and old URLs (`/Lists/X/EditForm.aspx?ID=3&Source=...`) redirect to the new routes.
|
|
172
|
+
- SharePoint groups become roles. Membership comes from your users/groups tables or `data/roles.json`.
|
|
173
|
+
- Authentication: `AUTH_MODE=dev` for local work; `header` behind your gateway, or Entra ID in `app/auth.py`.
|
|
174
|
+
|
|
175
|
+
## Use it from your own tool
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from sp2react import Pipeline, load_config
|
|
179
|
+
|
|
180
|
+
p = Pipeline(load_config("sp2react.yaml"), progress=print)
|
|
181
|
+
p.stage_inputs(offline=False)
|
|
182
|
+
p.stage_extract(pages=["SitePages/Dashboard.aspx"], offline=False)
|
|
183
|
+
screens = [s["id"] for s in p.stage_inventory(["SitePages/Dashboard.aspx"])]
|
|
184
|
+
p.stage_spec(screens)
|
|
185
|
+
p.approve("Dashboard", "spec", by="reviewer")
|
|
186
|
+
p.stage_map_db([p.load_spec(s) for s in p.approved_sids()])
|
|
187
|
+
p.stage_convert(screens)
|
|
188
|
+
p.stage_review(screens)
|
|
189
|
+
p.stage_test_and_fix(screens)
|
|
190
|
+
p.state # also written to sp2react-work/state.json
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## What converts and what does not
|
|
194
|
+
|
|
195
|
+
| Converts | Needs your input, or is not converted yet |
|
|
196
|
+
|---|---|
|
|
197
|
+
| List forms (New/Edit/Display) and their jQuery/SPServices behaviour | Workflows, event receivers, compiled solutions: their code is not reachable over REST. They are flagged; export the definitions or source to convert them |
|
|
198
|
+
| Web part pages (SitePages) with Script Editor / Content Editor JavaScript | InfoPath and Power Apps forms: reported, not converted |
|
|
199
|
+
| Basic list views (columns, sort, row limit) | Views with filters and grouping, document libraries, custom master-page branding, rich grids (sort/search/select/export), modal dialogs: planned |
|
|
200
|
+
| SharePoint groups as roles, old URL redirects | Calculated columns are shown but not recomputed; managed metadata, item-level permissions, alert emails |
|
|
201
|
+
|
|
202
|
+
Run the inventory on your site first. It shows which pages and scripts were found and what each one does, before you commit to a conversion.
|
|
203
|
+
|
|
204
|
+
## Running Tests
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
pip install -e ".[dev]"
|
|
208
|
+
python -m pytest tests/ -v
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
The suite runs against `tests/fixtures/legacy-site`, a fictional Contoso procurement site with jQuery 1.12 / SPServices list forms and a REST-driven dashboard. It covers:
|
|
212
|
+
- a mock SharePoint server that rejects writes,
|
|
213
|
+
- a scripted stand-in for the model, including retry-on-feedback and give-up,
|
|
214
|
+
- a renamed-schema database standing in for an earlier migration,
|
|
215
|
+
- the network policy,
|
|
216
|
+
- all ten stages including the fix loop,
|
|
217
|
+
- a real `npm install` + `tsc` + `vite build` of the generated app.
|
|
218
|
+
|
|
219
|
+
## CI / CD
|
|
220
|
+
|
|
221
|
+
- `tests.yml`: runs the test suite on Python 3.10–3.13 on every push and pull request.
|
|
222
|
+
- `python-publish.yml`: on a `v*` tag or a published release, tests, builds and publishes to PyPI through **Trusted Publishing** (OIDC, no stored token).
|
|
223
|
+
- `scorecard.yml`: runs the OpenSSF Scorecard weekly and on every push to `main`.
|
|
224
|
+
|
|
225
|
+
## Security
|
|
226
|
+
|
|
227
|
+
See [SECURITY.md](SECURITY.md). In short:
|
|
228
|
+
- Requests go only to the configured SharePoint and model hosts, and SharePoint is read-only.
|
|
229
|
+
- In database mode no list data is read over HTTP and no business data is sent to the model.
|
|
230
|
+
- Secrets come from environment variables only.
|
|
231
|
+
|
|
232
|
+
## Changelog
|
|
233
|
+
|
|
234
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
|
235
|
+
|
|
236
|
+
## License
|
|
237
|
+
|
|
238
|
+
MIT. See [LICENSE](LICENSE).
|
sp2react-0.1.0/README.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# sp2react
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/sp2react/)
|
|
4
|
+
[](https://pypi.org/project/sp2react/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://securityscorecards.dev/viewer/?uri=github.com/karthikbd/sp2react)
|
|
7
|
+
|
|
8
|
+
Convert classic SharePoint (2013 / 2016 / 2019 / Subscription Edition) list forms and pages built with **ASPX, jQuery and SPServices** into a **React + FastAPI** app that runs on **your existing database**.
|
|
9
|
+
|
|
10
|
+
Plain code does everything mechanical. AI agents (Claude through your GitHub Copilot **Bridger** by default) do the parts that need judgement. Nothing an agent writes is accepted until it passes automatic checks.
|
|
11
|
+
|
|
12
|
+
**No business data over HTTP:** in the default `database` mode, list items, attachments and people are never read from SharePoint, and every request is checked against the hosts in your config.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Table of Contents
|
|
17
|
+
|
|
18
|
+
- [Installation](#installation)
|
|
19
|
+
- [Quick Start](#quick-start)
|
|
20
|
+
- [Configuration](#configuration)
|
|
21
|
+
- [The ten stages](#the-ten-stages)
|
|
22
|
+
- [Your existing database](#your-existing-database)
|
|
23
|
+
- [The generated app](#the-generated-app)
|
|
24
|
+
- [Use it from your own tool](#use-it-from-your-own-tool)
|
|
25
|
+
- [What converts and what does not](#what-converts-and-what-does-not)
|
|
26
|
+
- [Running Tests](#running-tests)
|
|
27
|
+
- [CI / CD](#ci--cd)
|
|
28
|
+
- [Security](#security)
|
|
29
|
+
- [Changelog](#changelog)
|
|
30
|
+
- [License](#license)
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install "sp2react[mysql]" # MySQL / MariaDB tables
|
|
38
|
+
pip install "sp2react[mssql]" # SQL Server tables
|
|
39
|
+
pip install "sp2react[ntlm]" # add for on-premises Windows authentication
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Python 3.10+. Node.js 20+ is needed to build the generated React app.
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
sp2react init # writes sp2react.yaml
|
|
48
|
+
export SP_USERNAME='CORP\me' SP_PASSWORD='...' # or SP_COOKIE / SP_TOKEN
|
|
49
|
+
export BRIDGER_TOKEN='...' # only if Bridger needs one
|
|
50
|
+
export SP2REACT_DB_URL='mysql+pymysql://user:password@db-host:3306/sea'
|
|
51
|
+
|
|
52
|
+
sp2react doctor # checks SharePoint, lists Bridger's Claude models
|
|
53
|
+
sp2react run --page /sites/SEA/SitePages/Dashboard.aspx --until spec
|
|
54
|
+
# review sp2react-work/specs/<screen>.coverage.md, then:
|
|
55
|
+
sp2react approve Dashboard
|
|
56
|
+
sp2react map-db # drafts db-mapping.json; review db-mapping.md
|
|
57
|
+
sp2react run --page /sites/SEA/SitePages/Dashboard.aspx --offline
|
|
58
|
+
sp2react status
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Configuration
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
sharepoint:
|
|
65
|
+
site_url: https://sharepoint.example.com/sites/SEA
|
|
66
|
+
auth: ntlm # ntlm | cookie | bearer | none ; secrets come from environment variables
|
|
67
|
+
llm:
|
|
68
|
+
provider: bridger # bridger | anthropic | openai | azure_openai
|
|
69
|
+
api_format: anthropic # how Bridger serves Claude: anthropic (/v1/messages) or openai (/v1/chat/completions)
|
|
70
|
+
base_url: http://localhost:4141
|
|
71
|
+
model: claude-sonnet-4 # exact id from `sp2react doctor`
|
|
72
|
+
api_key_env: BRIDGER_TOKEN
|
|
73
|
+
pipeline:
|
|
74
|
+
data_source: database # database | sqlite | sharepoint
|
|
75
|
+
max_concurrency: 4
|
|
76
|
+
max_fix_iterations: 5
|
|
77
|
+
database:
|
|
78
|
+
url_env: SP2REACT_DB_URL
|
|
79
|
+
mapping: ./db-mapping.json
|
|
80
|
+
security:
|
|
81
|
+
allowed_hosts: []
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## The ten stages
|
|
85
|
+
|
|
86
|
+
Each stage starts only after the previous one has finished.
|
|
87
|
+
|
|
88
|
+
| # | Stage | Who | What happens | Checked by |
|
|
89
|
+
|---|---|---|---|---|
|
|
90
|
+
| 1 | inputs | code | config and connectivity | |
|
|
91
|
+
| 2 | extract | code | `.aspx` source, browser-added web parts, Script Editor / Content Editor content, JSLink, custom JS/CSS, list schemas, views, forms, group names, navigation. GET only | manifest of fetched files and errors |
|
|
92
|
+
| 3 | inventory | code | groups each list's New/Edit/Display forms into one screen and finds every jQuery behaviour and data call, with file:line | deterministic |
|
|
93
|
+
| 4 | spec | **agent** | builds the base spec from the schema, then the agent adds the rules that need interpretation | **coverage gate**: every required behaviour covered, legacy texts verbatim, rules valid |
|
|
94
|
+
| 5 | approve_spec | you | read `specs/<screen>.coverage.md` | |
|
|
95
|
+
| 6 | convert | code + **agents** | writes the fixed scaffold in seconds. List forms are rendered by the shared form engine from the spec; agents write only page components and custom handlers, in parallel | import whitelist, no fetch/jQuery/innerHTML, legacy texts present, `tsc` |
|
|
96
|
+
| 7 | review | **agent** | independent parity review | findings fed to fix |
|
|
97
|
+
| 8 | test | code | generated API tests, rule vectors (browser and API engines must agree), `tsc` + `vite build`, data reconciliation | |
|
|
98
|
+
| 9 | fix | **agent** | gets the real compiler and test output and edits only agent-owned files; up to N rounds | re-test |
|
|
99
|
+
| 10 | approve | you | | |
|
|
100
|
+
|
|
101
|
+
## Your existing database
|
|
102
|
+
|
|
103
|
+
If your team has already moved the list data into MySQL or SQL Server, the generated FastAPI app reads and writes those tables directly.
|
|
104
|
+
|
|
105
|
+
1. `sp2react map-db` reads the database **schema only** (tables, columns, types, keys).
|
|
106
|
+
2. It drafts the mapping: each list to a table, each field to a column, lookups to foreign keys, people to a users table or login column, plus created/modified/author/editor/version columns and attachments.
|
|
107
|
+
3. The `dbmap` agent resolves what the draft could not, for example `Countries.Title` migrated as `countries.country_name`.
|
|
108
|
+
4. Validation blocks code generation until every table and column exists and every required field is mapped.
|
|
109
|
+
5. You review `db-mapping.md`, and can edit `db-mapping.json` directly.
|
|
110
|
+
|
|
111
|
+
At runtime, OData-style queries from the forms and pages (`$filter`, `$orderby`, `$top`, lookup paths such as `Country/Title`) are translated to SQL. Optimistic concurrency uses your version column if you have one, otherwise the modified timestamp.
|
|
112
|
+
|
|
113
|
+
To check the earlier migration, set `security.sharepoint_item_reads: true`. `reconciliation.md` then compares every list item with its row, field by field, including orphaned lookups and attachment checksums.
|
|
114
|
+
|
|
115
|
+
## The generated app
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
cd converted-app/backend && pip install -r requirements.txt pymysql && cp .env.example .env && uvicorn app.main:app
|
|
119
|
+
cd converted-app/frontend && npm install && npm run dev
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
- Behaviour comes from the spec at runtime. `runtime/rules.ts` (browser) and `app/rules.py` (API) interpret the same rules, and shared vectors keep them in agreement, so a direct API call cannot bypass a rule.
|
|
123
|
+
- The form uses SharePoint's layout, labels and control titles, the legacy site CSS is carried over, and old URLs (`/Lists/X/EditForm.aspx?ID=3&Source=...`) redirect to the new routes.
|
|
124
|
+
- SharePoint groups become roles. Membership comes from your users/groups tables or `data/roles.json`.
|
|
125
|
+
- Authentication: `AUTH_MODE=dev` for local work; `header` behind your gateway, or Entra ID in `app/auth.py`.
|
|
126
|
+
|
|
127
|
+
## Use it from your own tool
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from sp2react import Pipeline, load_config
|
|
131
|
+
|
|
132
|
+
p = Pipeline(load_config("sp2react.yaml"), progress=print)
|
|
133
|
+
p.stage_inputs(offline=False)
|
|
134
|
+
p.stage_extract(pages=["SitePages/Dashboard.aspx"], offline=False)
|
|
135
|
+
screens = [s["id"] for s in p.stage_inventory(["SitePages/Dashboard.aspx"])]
|
|
136
|
+
p.stage_spec(screens)
|
|
137
|
+
p.approve("Dashboard", "spec", by="reviewer")
|
|
138
|
+
p.stage_map_db([p.load_spec(s) for s in p.approved_sids()])
|
|
139
|
+
p.stage_convert(screens)
|
|
140
|
+
p.stage_review(screens)
|
|
141
|
+
p.stage_test_and_fix(screens)
|
|
142
|
+
p.state # also written to sp2react-work/state.json
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## What converts and what does not
|
|
146
|
+
|
|
147
|
+
| Converts | Needs your input, or is not converted yet |
|
|
148
|
+
|---|---|
|
|
149
|
+
| List forms (New/Edit/Display) and their jQuery/SPServices behaviour | Workflows, event receivers, compiled solutions: their code is not reachable over REST. They are flagged; export the definitions or source to convert them |
|
|
150
|
+
| Web part pages (SitePages) with Script Editor / Content Editor JavaScript | InfoPath and Power Apps forms: reported, not converted |
|
|
151
|
+
| Basic list views (columns, sort, row limit) | Views with filters and grouping, document libraries, custom master-page branding, rich grids (sort/search/select/export), modal dialogs: planned |
|
|
152
|
+
| SharePoint groups as roles, old URL redirects | Calculated columns are shown but not recomputed; managed metadata, item-level permissions, alert emails |
|
|
153
|
+
|
|
154
|
+
Run the inventory on your site first. It shows which pages and scripts were found and what each one does, before you commit to a conversion.
|
|
155
|
+
|
|
156
|
+
## Running Tests
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
pip install -e ".[dev]"
|
|
160
|
+
python -m pytest tests/ -v
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The suite runs against `tests/fixtures/legacy-site`, a fictional Contoso procurement site with jQuery 1.12 / SPServices list forms and a REST-driven dashboard. It covers:
|
|
164
|
+
- a mock SharePoint server that rejects writes,
|
|
165
|
+
- a scripted stand-in for the model, including retry-on-feedback and give-up,
|
|
166
|
+
- a renamed-schema database standing in for an earlier migration,
|
|
167
|
+
- the network policy,
|
|
168
|
+
- all ten stages including the fix loop,
|
|
169
|
+
- a real `npm install` + `tsc` + `vite build` of the generated app.
|
|
170
|
+
|
|
171
|
+
## CI / CD
|
|
172
|
+
|
|
173
|
+
- `tests.yml`: runs the test suite on Python 3.10–3.13 on every push and pull request.
|
|
174
|
+
- `python-publish.yml`: on a `v*` tag or a published release, tests, builds and publishes to PyPI through **Trusted Publishing** (OIDC, no stored token).
|
|
175
|
+
- `scorecard.yml`: runs the OpenSSF Scorecard weekly and on every push to `main`.
|
|
176
|
+
|
|
177
|
+
## Security
|
|
178
|
+
|
|
179
|
+
See [SECURITY.md](SECURITY.md). In short:
|
|
180
|
+
- Requests go only to the configured SharePoint and model hosts, and SharePoint is read-only.
|
|
181
|
+
- In database mode no list data is read over HTTP and no business data is sent to the model.
|
|
182
|
+
- Secrets come from environment variables only.
|
|
183
|
+
|
|
184
|
+
## Changelog
|
|
185
|
+
|
|
186
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
|
187
|
+
|
|
188
|
+
## License
|
|
189
|
+
|
|
190
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
|---------|-----------|
|
|
7
|
+
| 0.1.x | ✅ Active |
|
|
8
|
+
|
|
9
|
+
## Reporting a Vulnerability
|
|
10
|
+
|
|
11
|
+
**Please do not open a public GitHub issue for security vulnerabilities.**
|
|
12
|
+
|
|
13
|
+
Report vulnerabilities privately via GitHub's [Security Advisories](https://github.com/karthikbd/sp2react/security/advisories/new).
|
|
14
|
+
|
|
15
|
+
You can expect:
|
|
16
|
+
- **Acknowledgement** within 48 hours
|
|
17
|
+
- **Status update** within 7 days
|
|
18
|
+
- **Fix or mitigation** as soon as reasonably possible, coordinated with a disclosure date
|
|
19
|
+
|
|
20
|
+
## Network access
|
|
21
|
+
|
|
22
|
+
`sp2react` has no telemetry, no update check and no third-party calls. It opens HTTP connections to exactly two kinds of host, both named in your `sp2react.yaml`:
|
|
23
|
+
|
|
24
|
+
| Host | Why | What is sent / received |
|
|
25
|
+
|------|-----|-------------------------|
|
|
26
|
+
| `sharepoint.site_url` | Read the site being converted | GET requests only (the client refuses any other verb). Page source, web part definitions, custom scripts/CSS, list schemas, views, group names, navigation |
|
|
27
|
+
| `llm.base_url` (Bridger, or the provider you chose) | AI agent calls | Page source, scripts, list schemas and the draft spec or code under review |
|
|
28
|
+
|
|
29
|
+
Every request, and every redirect hop, is checked against that allowlist before it is sent (`sp2react/net.py`); anything else raises `NetworkPolicyError`. Extra hosts must be added explicitly under `security.allowed_hosts`.
|
|
30
|
+
|
|
31
|
+
## Business data
|
|
32
|
+
|
|
33
|
+
With `pipeline.data_source: database` (the default):
|
|
34
|
+
- list items, attachments, site users and rendered pages are **never read** from SharePoint; the client raises `ItemReadBlocked` if anything tries
|
|
35
|
+
- group membership is not read (group names only)
|
|
36
|
+
- no business data is sent to the model; prompts contain code and schema only
|
|
37
|
+
- `sp2react map-db` reads your database **schema** (tables, columns, types, keys) over the database driver; it does not read rows
|
|
38
|
+
|
|
39
|
+
Item reads over HTTP happen only when you set `data_source: sqlite` (sp2react migrates the data itself) or explicitly enable `security.sharepoint_item_reads: true` to reconcile the lists with your tables.
|
|
40
|
+
|
|
41
|
+
## Secrets
|
|
42
|
+
|
|
43
|
+
Credentials are read from environment variables named in the config (`SP_USERNAME`/`SP_PASSWORD`, `SP_COOKIE`, `SP_TOKEN`, the model token, the database URL). They are never written to the workspace, the generated app or agent transcripts.
|
|
44
|
+
|
|
45
|
+
## Generated application
|
|
46
|
+
|
|
47
|
+
The generated FastAPI app ships with `AUTH_MODE=dev` (an `X-User` header) for local testing only. Before deployment, use `AUTH_MODE=header` behind an authenticating gateway, or replace `app/auth.py` with Entra ID token validation.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "sp2react"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
authors = [{name = "Karthikeyan Balasundaram"}]
|
|
9
|
+
description = "AI-agent pipeline that converts classic SharePoint ASPX/jQuery list forms and pages into a React + FastAPI app on your existing database"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
license = {text = "MIT"}
|
|
13
|
+
keywords = [
|
|
14
|
+
"sharepoint", "sharepoint migration", "react", "fastapi", "jquery", "spservices",
|
|
15
|
+
"aspx", "list forms", "migration", "code conversion", "ai agents", "claude",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Topic :: Software Development :: Code Generators",
|
|
21
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"License :: OSI Approved :: MIT License",
|
|
28
|
+
"Operating System :: OS Independent",
|
|
29
|
+
]
|
|
30
|
+
dependencies = [
|
|
31
|
+
"pydantic>=2.5",
|
|
32
|
+
"pyyaml>=6.0",
|
|
33
|
+
"requests>=2.31",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
ntlm = ["requests-ntlm>=1.2"]
|
|
38
|
+
db = ["sqlalchemy>=2.0"]
|
|
39
|
+
mysql = ["sqlalchemy>=2.0", "pymysql>=1.1"]
|
|
40
|
+
mssql = ["sqlalchemy>=2.0", "pyodbc>=5.0"]
|
|
41
|
+
dev = ["pytest>=8", "fastapi>=0.110", "httpx>=0.27", "uvicorn>=0.27", "sqlalchemy>=2.0"]
|
|
42
|
+
|
|
43
|
+
[project.scripts]
|
|
44
|
+
sp2react = "sp2react.cli:main"
|
|
45
|
+
|
|
46
|
+
[project.urls]
|
|
47
|
+
Homepage = "https://github.com/karthikbd/sp2react"
|
|
48
|
+
"Source Code" = "https://github.com/karthikbd/sp2react"
|
|
49
|
+
Repository = "https://github.com/karthikbd/sp2react"
|
|
50
|
+
"Bug Tracker" = "https://github.com/karthikbd/sp2react/issues"
|
|
51
|
+
Changelog = "https://github.com/karthikbd/sp2react/blob/main/CHANGELOG.md"
|
|
52
|
+
Documentation = "https://github.com/karthikbd/sp2react#readme"
|
|
53
|
+
|
|
54
|
+
[tool.setuptools.packages.find]
|
|
55
|
+
where = ["src"]
|
|
56
|
+
include = ["sp2react*"]
|
|
57
|
+
|
|
58
|
+
[tool.setuptools.package-data]
|
|
59
|
+
sp2react = ["agents/prompts/*.md", "scaffold/*.json", "scaffold/templates/**/*"]
|
|
60
|
+
|
|
61
|
+
[tool.pytest.ini_options]
|
|
62
|
+
testpaths = ["tests"]
|
sp2react-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""sp2react: convert classic SharePoint ASPX/jQuery list forms and pages into React + FastAPI with AI agents.
|
|
2
|
+
|
|
3
|
+
Python API:
|
|
4
|
+
from sp2react import Pipeline, load_config
|
|
5
|
+
p = Pipeline(load_config("sp2react.yaml"))
|
|
6
|
+
p.run(pages=["SitePages/Dashboard.aspx"])
|
|
7
|
+
"""
|
|
8
|
+
__version__ = "0.1.0"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def __getattr__(name):
|
|
12
|
+
if name == "Pipeline":
|
|
13
|
+
from .pipeline import Pipeline
|
|
14
|
+
return Pipeline
|
|
15
|
+
if name == "load_config":
|
|
16
|
+
from .config import load_config
|
|
17
|
+
return load_config
|
|
18
|
+
raise AttributeError(name)
|
|
File without changes
|