(sdk) add sdk projects

It includes a consumer project which is simply a demo app. The sdk
project includes the first version of the SDK, with a light React
implementation. The first version lays down the foundations of
the iframe sdk framework. The npm package logic is also already
ready to be published.
This commit is contained in:
Nathan Vasse
2025-02-10 16:34:55 +01:00
committed by NathanVss
parent 452dbe8bba
commit 183e8f6a72
50 changed files with 36130 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
# Changesets
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)

View File

@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}

View File

@@ -0,0 +1 @@
VITE_VISIO_SDK_URL=https://visio.numerique.gouv.fr/sdk

View File

@@ -0,0 +1,21 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
"plugin:@tanstack/eslint-plugin-query/recommended",
"plugin:jsx-a11y/recommended",
"prettier",
],
ignorePatterns: ["dist", ".eslintrc.cjs", "styled-system"],
parser: "@typescript-eslint/parser",
plugins: ["react-refresh"],
rules: {
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
};

24
src/sdk/library/.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -0,0 +1,5 @@
{
"semi": false,
"trailingComma": "es5",
"singleQuote": true
}

View File

@@ -0,0 +1,7 @@
# @gouvfr-lasuite/visio-sdk
## 0.0.1
### Major Changes
- Create library with VisioCreateButton

View File

@@ -0,0 +1,17 @@
# Contributing
## Release
1. Run `npm run build`
2. Update CHANGELOG.md according to the Major / Minor / Patch semver convention.
3. Based on semver upgrade the package version in `package.json`.
4. Commit the changes and create a PR named "🔖(release) version packages".
5. Run `npx @changesets/cli publish`. It will publish the new version of the package to NPM and create a git tag.
6. Run `git push origin tag @gouvfr-lasuite/visio-sdk@<VERSION>`
7. Tell everyone 🎉 !

42
src/sdk/library/README.md Normal file
View File

@@ -0,0 +1,42 @@
<div align="center">
# 🎥 Visio SDK
**Easily add a button to create visio link to your product**
<img src="docs/demo.gif" alt="" width="400" />
<br/>
<br/>
<strong>... that also handles seamless authentication out of the box</strong>
<br/>
<br/>
<img src="docs/demo_loggedout.gif" alt="" />
<br/>
<br/>
<strong>As simple as</strong>
<br/>
<br/>
</div>
```ts
import { VisioCreateButton } from "@gouvfr-lasuite/visio-sdk";
function App() {
const [roomUrl, setRoomUrl] = useState();
return <VisioCreateButton onRoomCreated={setRoomUrl} />;
}
```
## Installation
To install, you can use npm or yarn:
```
$ npm install --save @gouvfr-lasuite/visio-sdk
$ yarn add @gouvfr-lasuite/visio-sdk
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 KiB

View File

@@ -0,0 +1,52 @@
{
"name": "@gouvfr-lasuite/visio-sdk",
"private": false,
"publishConfig": {
"access": "public"
},
"version": "0.0.1",
"type": "module",
"main": "./dist/visio-sdk.umd.cjs",
"module": "./dist/visio-sdk.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/visio-sdk.js",
"require": "./dist/visio-sdk.umd.cjs"
}
},
"files": [
"dist/"
],
"scripts": {
"dev": "vite build -w --mode development",
"build": "tsc -b && vite build",
"lint": "eslint . --ext ts,tsx",
"format": "prettier --write ./src",
"check": "prettier --check ./src"
},
"dependencies": {
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"@tanstack/eslint-plugin-query": "5.64.2",
"@types/node": "20.14.2",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"@typescript-eslint/eslint-plugin": "7.15.0",
"@typescript-eslint/parser": "7.15.0",
"@vitejs/plugin-react-swc": "3.5.0",
"eslint": "8.57.0",
"eslint-config-prettier": "10.0.1",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-react-refresh": "0.4.7",
"eslint-plugin-jsx-a11y": "6.10.2",
"sass": "1.83.4",
"prettier": "3.4.2",
"typescript": "5.4.5",
"vite": "5.3.4",
"vite-plugin-dts": "3.9.1"
}
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,3 @@
export const DEFAULT_CONFIG = {
url: import.meta.env.VITE_VISIO_SDK_URL,
}

View File

@@ -0,0 +1,7 @@
import { DEFAULT_CONFIG } from '@/Config'
export type ConfigType = typeof DEFAULT_CONFIG
export enum ClientMessageType {
ROOM_CREATED = 'ROOM_CREATED',
}

View File

@@ -0,0 +1,41 @@
import { DEFAULT_CONFIG } from '@/Config'
import { ClientMessageType } from '@/Types'
import { useEffect } from 'react'
export const VisioCreateButton = ({
onRoomCreated,
}: {
onRoomCreated: (roomUrl: string) => void
}) => {
useEffect(() => {
const onMessage = (event: MessageEvent) => {
// Make sure it is the correct origin.
if (event.origin !== new URL(DEFAULT_CONFIG.url).origin) {
return
}
if (event.data.type === ClientMessageType.ROOM_CREATED) {
const data = event.data.data
const roomUrl = data.url
onRoomCreated(roomUrl)
}
}
window.addEventListener('message', onMessage)
return () => {
window.removeEventListener('message', onMessage)
}
}, [onRoomCreated])
return (
// eslint-disable-next-line jsx-a11y/iframe-has-title
<iframe
allow="clipboard-read; clipboard-write"
src={DEFAULT_CONFIG.url + '/create-button'}
style={{
width: '100%',
height: '52px',
border: 'none',
}}
></iframe>
)
}

View File

@@ -0,0 +1,3 @@
/* eslint-disable react-refresh/only-export-components */
export * from '@/Types'
export * from '@/create/VisioCreateButton'

9
src/sdk/library/src/vite-env.d.ts vendored Normal file
View File

@@ -0,0 +1,9 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_VISIO_SDK_URL: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}

View File

@@ -0,0 +1,36 @@
{
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable", "WebWorker"],
"module": "esnext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": false,
"resolveJsonModule": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
/* Local */
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"baseUrl": "./src",
"paths": {
"@/*": ["./*"]
}
},
"include": ["src"]
}

View File

@@ -0,0 +1,11 @@
{
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.node.json"
}
]
}

View File

@@ -0,0 +1,13 @@
{
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"strict": true,
"noEmit": true
},
"include": ["vite.config.ts"]
}

View File

@@ -0,0 +1,35 @@
import path, { resolve } from "path";
import react from "@vitejs/plugin-react-swc";
import { AliasOptions, defineConfig } from "vite";
import dts from "vite-plugin-dts";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
dts({ tsconfigPath: "./tsconfig.app.json", rollupTypes: true }),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
} as AliasOptions,
},
build: {
lib: {
entry: resolve(__dirname, "src/index.tsx"),
name: "visio-sdk",
fileName: "visio-sdk",
},
rollupOptions: {
external: ["react", "react-dom"],
output: {
globals: {
react: "React",
"react-dom": "ReactDOM",
},
},
},
copyPublicDir: false,
},
});