@screenly/edge-apps 0.0.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 +21 -0
- package/README.md +191 -0
- package/bin/edge-apps-scripts.ts +9 -0
- package/configs/playwright.ts +44 -0
- package/eslint.config.ts +43 -0
- package/package.json +111 -0
- package/scripts/cli.ts +293 -0
- package/scripts/copy-assets.ts +26 -0
- package/scripts/cors-proxy-server.ts +154 -0
- package/scripts/create.ts +118 -0
- package/src/assets/fonts/Inter-Medium.woff2 +0 -0
- package/src/assets/fonts/Inter-Regular.woff2 +0 -0
- package/src/assets/fonts/Inter-SemiBold.woff2 +0 -0
- package/src/assets/images/icons/chancesleet.svg +4 -0
- package/src/assets/images/icons/clear-night.svg +5 -0
- package/src/assets/images/icons/clear.svg +11 -0
- package/src/assets/images/icons/cloudy.svg +4 -0
- package/src/assets/images/icons/drizzle.svg +5 -0
- package/src/assets/images/icons/fewdrops.svg +4 -0
- package/src/assets/images/icons/fog.svg +6 -0
- package/src/assets/images/icons/haze.svg +6 -0
- package/src/assets/images/icons/mostly-cloudy-night.svg +7 -0
- package/src/assets/images/icons/mostly-cloudy.svg +13 -0
- package/src/assets/images/icons/partially-cloudy-night.svg +6 -0
- package/src/assets/images/icons/partially-cloudy.svg +12 -0
- package/src/assets/images/icons/partlysunny.svg +6 -0
- package/src/assets/images/icons/rain-night.svg +8 -0
- package/src/assets/images/icons/rainy.svg +6 -0
- package/src/assets/images/icons/sleet-night.svg +14 -0
- package/src/assets/images/icons/sleet.svg +4 -0
- package/src/assets/images/icons/snow.svg +19 -0
- package/src/assets/images/icons/thunderstorm-night.svg +9 -0
- package/src/assets/images/icons/thunderstorm.svg +7 -0
- package/src/assets/images/icons/windy.svg +6 -0
- package/src/assets/images/screenly.svg +10 -0
- package/src/styles/base/fonts.css +30 -0
- package/src/styles/base/index.css +7 -0
- package/src/styles/base/reset.css +37 -0
- package/src/styles/calendar-app.css +52 -0
- package/src/styles/index.css +10 -0
- package/src/styles/tokens/colors.css +4 -0
- package/src/styles/tokens/index.css +10 -0
- package/src/styles/tokens/shadows.css +8 -0
- package/src/styles/tokens/spacing.css +6 -0
- package/src/styles/tokens/typography.css +9 -0
- package/src/styles/tokens/z-index.css +12 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Screenly
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# @screenly/edge-apps
|
|
2
|
+
|
|
3
|
+
A TypeScript library for interfacing with the Screenly Edge Apps API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
> [!IMPORTANT]
|
|
8
|
+
> This package requires [Bun](https://bun.sh). The `edge-apps-scripts` CLI will not work with `npm` or `node` at this time.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
bun add @screenly/edge-apps
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Local Development Setup
|
|
15
|
+
|
|
16
|
+
When developing Edge Apps locally using the library from this repository, you should link the package.
|
|
17
|
+
|
|
18
|
+
First, in the root of this repository:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bun link
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Then in your Edge App directory:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cd /path/to/your-edge-app
|
|
28
|
+
bun link @screenly/edge-apps
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
To unlink the package when you're done with local development, run the following in your Edge App directory:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bun install --force
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Then in the root of this repository:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
bun unlink
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { setupTheme, signalReady, getMetadata } from '@screenly/edge-apps'
|
|
47
|
+
|
|
48
|
+
setupTheme()
|
|
49
|
+
const metadata = getMetadata()
|
|
50
|
+
signalReady()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Core Functions
|
|
54
|
+
|
|
55
|
+
### Theme & Branding
|
|
56
|
+
|
|
57
|
+
- `setupTheme()` - Apply theme colors to CSS custom properties
|
|
58
|
+
- `setupBrandingLogo()` - Fetch and process branding logo
|
|
59
|
+
- `setupBranding()` - Setup complete branding (colors and logo)
|
|
60
|
+
|
|
61
|
+
### Settings
|
|
62
|
+
|
|
63
|
+
- `getSettings()` - Get all settings
|
|
64
|
+
- `getSetting<T>(key)` - Get specific setting with type safety
|
|
65
|
+
- `getSettingWithDefault<T>(key, default)` - Get setting with fallback
|
|
66
|
+
- `signalReady()` - Signal app is ready for display
|
|
67
|
+
|
|
68
|
+
### Metadata
|
|
69
|
+
|
|
70
|
+
- `getMetadata()` - Get all screen metadata
|
|
71
|
+
- `getScreenName()`, `getHostname()`, `getLocation()`, `getScreenlyVersion()`, `getTags()`, `hasTag(tag)`, `getFormattedCoordinates()`
|
|
72
|
+
- `getHardware()` - Get hardware type as `Hardware` enum (`Anywhere`, `RaspberryPi`, or `ScreenlyPlayerMax`)
|
|
73
|
+
|
|
74
|
+
### Location & Localization
|
|
75
|
+
|
|
76
|
+
- `getTimeZone()` - Get timezone from GPS coordinates
|
|
77
|
+
- `getLocale()` - Get locale from location
|
|
78
|
+
- `formatCoordinates(coords)` - Format coordinates as string
|
|
79
|
+
- `formatLocalizedDate(date, locale)` - Format date for locale
|
|
80
|
+
- `formatTime(date, locale, timezone)` - Format time for locale
|
|
81
|
+
- `getLocalizedDayNames(locale)` - Get day names for locale
|
|
82
|
+
- `getLocalizedMonthNames(locale)` - Get month names for locale
|
|
83
|
+
- `detectHourFormat(locale)` - Detect 12h/24h format for locale
|
|
84
|
+
|
|
85
|
+
### UTM Tracking
|
|
86
|
+
|
|
87
|
+
- `addUTMParams(url, params?)` - Add UTM parameters to URL
|
|
88
|
+
- `addUTMParamsIf(url, enabled, params?)` - Conditionally add UTM parameters
|
|
89
|
+
|
|
90
|
+
## Edge Apps Scripts CLI
|
|
91
|
+
|
|
92
|
+
This package provides the `edge-apps-scripts` CLI tool for running shared development commands across all Edge Apps. It includes centralized ESLint configuration to avoid duplication.
|
|
93
|
+
|
|
94
|
+
### Available Commands
|
|
95
|
+
|
|
96
|
+
#### Development Server
|
|
97
|
+
|
|
98
|
+
Start the Vite development server with mock data from `screenly.yml` and `mock-data.yml`:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
bun run dev
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### Building
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
bun run build
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### Linting
|
|
111
|
+
|
|
112
|
+
To lint your Edge App:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
bun run lint
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
To lint and automatically fix issues:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
bun run lint -- --fix
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### Type Checking
|
|
125
|
+
|
|
126
|
+
Run TypeScript type checking:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
bun run type-check
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Command-Line Utilities for Edge Apps
|
|
133
|
+
|
|
134
|
+
- This library provides utilities to help with common Edge App tasks.
|
|
135
|
+
- The CLI uses the shared ESLint configuration from `@screenly/edge-apps`, so you don't need to maintain your own `eslint.config.ts`
|
|
136
|
+
- The build commands assume your Edge App has `index.html` as the entry point
|
|
137
|
+
- Build output will be generated in the `dist/` directory
|
|
138
|
+
|
|
139
|
+
It is recommended to add the following scripts to your Edge App's `package.json`:
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
{
|
|
143
|
+
"scripts": {
|
|
144
|
+
"dev": "edge-apps-scripts dev",
|
|
145
|
+
"build": "edge-apps-scripts build",
|
|
146
|
+
"build:dev": "edge-apps-scripts build:dev",
|
|
147
|
+
"lint": "edge-apps-scripts lint",
|
|
148
|
+
"type-check": "edge-apps-scripts type-check",
|
|
149
|
+
"deploy": "bun run build && screenly edge-app deploy --path=dist/"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
> [!NOTE]
|
|
155
|
+
> Feel free to customize the scripts as needed for your Edge App. You could also define your own configs like `eslint.config.ts`, `tsconfig.json`, or `vite.config.ts` if you need more control.
|
|
156
|
+
|
|
157
|
+
## Testing
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import { setupScreenlyMock, resetScreenlyMock } from '@screenly/edge-apps/test'
|
|
161
|
+
|
|
162
|
+
beforeEach(() => {
|
|
163
|
+
setupScreenlyMock({ screen_name: 'Test Screen' }, { theme: 'dark' })
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
afterEach(() => {
|
|
167
|
+
resetScreenlyMock()
|
|
168
|
+
})
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Types
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
import type {
|
|
175
|
+
Hardware,
|
|
176
|
+
ScreenlyMetadata,
|
|
177
|
+
ScreenlySettings,
|
|
178
|
+
ScreenlyObject,
|
|
179
|
+
ThemeColors,
|
|
180
|
+
BrandingConfig,
|
|
181
|
+
UTMParams,
|
|
182
|
+
} from '@screenly/edge-apps'
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Development
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
bun install # Install dependencies
|
|
189
|
+
bun test # Run tests
|
|
190
|
+
bun run build # Build library
|
|
191
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import { createRequire } from 'module'
|
|
3
|
+
import { fileURLToPath } from 'url'
|
|
4
|
+
|
|
5
|
+
const PREVIEW_PORT = 4173
|
|
6
|
+
|
|
7
|
+
// Resolve @playwright/test from the calling app's node_modules, not the library's
|
|
8
|
+
const appRequire = createRequire(path.join(process.cwd(), 'package.json'))
|
|
9
|
+
|
|
10
|
+
let defineConfig: typeof import('@playwright/test').defineConfig
|
|
11
|
+
let devices: typeof import('@playwright/test').devices
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const playwrightTest = appRequire('@playwright/test')
|
|
15
|
+
defineConfig = playwrightTest.defineConfig
|
|
16
|
+
devices = playwrightTest.devices
|
|
17
|
+
} catch {
|
|
18
|
+
throw new Error(
|
|
19
|
+
"Failed to resolve '@playwright/test' from the application. " +
|
|
20
|
+
"Please install it in your app (e.g. 'bun add -d @playwright/test') " +
|
|
21
|
+
'and try again.',
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
26
|
+
const libraryRoot = path.dirname(__dirname)
|
|
27
|
+
const viteBin = path.resolve(libraryRoot, 'node_modules', '.bin', 'vite')
|
|
28
|
+
const viteConfig = path.resolve(libraryRoot, 'vite.config.ts')
|
|
29
|
+
|
|
30
|
+
export default defineConfig({
|
|
31
|
+
testDir: path.join(process.cwd(), 'e2e'),
|
|
32
|
+
use: {
|
|
33
|
+
baseURL: `http://localhost:${PREVIEW_PORT}`,
|
|
34
|
+
...devices['Desktop Chrome'],
|
|
35
|
+
},
|
|
36
|
+
webServer: {
|
|
37
|
+
// Invoke vite directly so it always runs from the library's node_modules,
|
|
38
|
+
// ensuring packages like tailwindcss resolve correctly regardless of the app.
|
|
39
|
+
command: `"${viteBin}" build --config "${viteConfig}" && "${viteBin}" preview --config "${viteConfig}" --port ${PREVIEW_PORT} --strictPort`,
|
|
40
|
+
cwd: process.cwd(),
|
|
41
|
+
port: PREVIEW_PORT,
|
|
42
|
+
reuseExistingServer: false,
|
|
43
|
+
},
|
|
44
|
+
})
|
package/eslint.config.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import eslint from '@eslint/js'
|
|
2
|
+
import { defineConfig, globalIgnores } from 'eslint/config'
|
|
3
|
+
import tseslint from 'typescript-eslint'
|
|
4
|
+
|
|
5
|
+
export default defineConfig(
|
|
6
|
+
eslint.configs.recommended,
|
|
7
|
+
tseslint.configs.recommended,
|
|
8
|
+
globalIgnores([
|
|
9
|
+
'dist/',
|
|
10
|
+
'node_modules/',
|
|
11
|
+
'static/js/',
|
|
12
|
+
'build/',
|
|
13
|
+
'tailwind.config.js',
|
|
14
|
+
]),
|
|
15
|
+
{
|
|
16
|
+
rules: {
|
|
17
|
+
'@typescript-eslint/no-unused-vars': [
|
|
18
|
+
'error',
|
|
19
|
+
{
|
|
20
|
+
argsIgnorePattern: '^_',
|
|
21
|
+
varsIgnorePattern: '^_',
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
'complexity': ['error', { max: 20 }],
|
|
25
|
+
'max-lines-per-function': ['error', {
|
|
26
|
+
max: 70,
|
|
27
|
+
skipBlankLines: true,
|
|
28
|
+
skipComments: true,
|
|
29
|
+
}],
|
|
30
|
+
'max-lines': ['error', {
|
|
31
|
+
max: 300,
|
|
32
|
+
skipBlankLines: true,
|
|
33
|
+
skipComments: true,
|
|
34
|
+
}],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
files: ['**/*.test.ts', '**/*.spec.ts'],
|
|
39
|
+
rules: {
|
|
40
|
+
'max-lines': 'off',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
)
|
package/package.json
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@screenly/edge-apps",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "A TypeScript library for interfacing with Screenly Edge Apps API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"bin": {
|
|
10
|
+
"edge-apps-scripts": "./bin/edge-apps-scripts.ts"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./components": {
|
|
18
|
+
"import": "./dist/components/index.js",
|
|
19
|
+
"types": "./dist/components/index.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./core": {
|
|
22
|
+
"import": "./dist/core/index.js",
|
|
23
|
+
"types": "./dist/core/index.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"./styles": "./src/styles/index.css",
|
|
26
|
+
"./styles/*": "./src/styles/*",
|
|
27
|
+
"./utils": {
|
|
28
|
+
"import": "./dist/utils/index.js",
|
|
29
|
+
"types": "./dist/utils/index.d.ts"
|
|
30
|
+
},
|
|
31
|
+
"./types": {
|
|
32
|
+
"import": "./dist/types/index.js",
|
|
33
|
+
"types": "./dist/types/index.d.ts"
|
|
34
|
+
},
|
|
35
|
+
"./test": {
|
|
36
|
+
"import": "./dist/test/index.js",
|
|
37
|
+
"types": "./dist/test/index.d.ts"
|
|
38
|
+
},
|
|
39
|
+
"./test/screenshots": {
|
|
40
|
+
"import": "./dist/test/screenshots.js",
|
|
41
|
+
"types": "./dist/test/screenshots.d.ts"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"bin",
|
|
47
|
+
"configs",
|
|
48
|
+
"scripts",
|
|
49
|
+
"eslint.config.ts",
|
|
50
|
+
"src/styles",
|
|
51
|
+
"src/assets"
|
|
52
|
+
],
|
|
53
|
+
"scripts": {
|
|
54
|
+
"prebuild": "bun run type-check",
|
|
55
|
+
"build": "bun build:types && bun run copy:assets",
|
|
56
|
+
"build:types": "tsc",
|
|
57
|
+
"copy:assets": "bun run scripts/copy-assets.ts",
|
|
58
|
+
"test": "bun test --parallel",
|
|
59
|
+
"test:unit": "bun test --parallel",
|
|
60
|
+
"test:coverage": "bun test --coverage --parallel",
|
|
61
|
+
"lint": "eslint . --fix",
|
|
62
|
+
"format": "prettier --write src/ scripts/ vite-plugins/ README.md index.html",
|
|
63
|
+
"format:check": "prettier --check src/ scripts/ vite-plugins/ README.md index.html",
|
|
64
|
+
"type-check": "tsc --noEmit"
|
|
65
|
+
},
|
|
66
|
+
"prettier": "./.prettierrc.json",
|
|
67
|
+
"keywords": [
|
|
68
|
+
"screenly",
|
|
69
|
+
"edge-apps",
|
|
70
|
+
"digital-signage"
|
|
71
|
+
],
|
|
72
|
+
"author": "Screenly",
|
|
73
|
+
"license": "MIT",
|
|
74
|
+
"publishConfig": {
|
|
75
|
+
"access": "public"
|
|
76
|
+
},
|
|
77
|
+
"dependencies": {
|
|
78
|
+
"@photostructure/tz-lookup": "^11.5.0",
|
|
79
|
+
"dayjs": "^1.11.19",
|
|
80
|
+
"@tailwindcss/vite": "^4.2.1",
|
|
81
|
+
"country-locale-map": "^1.9.12",
|
|
82
|
+
"offline-geocode-city": "^1.0.2",
|
|
83
|
+
"panic-overlay": "^1.0.51",
|
|
84
|
+
"sharp": "^0.34.5",
|
|
85
|
+
"tailwindcss": "^4.2.1"
|
|
86
|
+
},
|
|
87
|
+
"peerDependencies": {
|
|
88
|
+
"@playwright/test": "^1.58.0"
|
|
89
|
+
},
|
|
90
|
+
"peerDependenciesMeta": {
|
|
91
|
+
"@playwright/test": {
|
|
92
|
+
"optional": true
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"devDependencies": {
|
|
96
|
+
"@eslint/js": "^10.0.1",
|
|
97
|
+
"@types/bun": "^1.3.10",
|
|
98
|
+
"@types/jsdom": "^28.0.0",
|
|
99
|
+
"@types/node": "^25.4.0",
|
|
100
|
+
"@types/sharp": "^0.32.0",
|
|
101
|
+
"bun-types": "^1.3.10",
|
|
102
|
+
"eslint": "^10.0.3",
|
|
103
|
+
"jiti": "^2.6.1",
|
|
104
|
+
"jsdom": "^28.1.0",
|
|
105
|
+
"prettier": "^3.8.1",
|
|
106
|
+
"typescript": "^5.9.3",
|
|
107
|
+
"typescript-eslint": "^8.57.0",
|
|
108
|
+
"vite": "^7.3.1",
|
|
109
|
+
"yaml": "^2.8.2"
|
|
110
|
+
}
|
|
111
|
+
}
|