@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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +191 -0
  3. package/bin/edge-apps-scripts.ts +9 -0
  4. package/configs/playwright.ts +44 -0
  5. package/eslint.config.ts +43 -0
  6. package/package.json +111 -0
  7. package/scripts/cli.ts +293 -0
  8. package/scripts/copy-assets.ts +26 -0
  9. package/scripts/cors-proxy-server.ts +154 -0
  10. package/scripts/create.ts +118 -0
  11. package/src/assets/fonts/Inter-Medium.woff2 +0 -0
  12. package/src/assets/fonts/Inter-Regular.woff2 +0 -0
  13. package/src/assets/fonts/Inter-SemiBold.woff2 +0 -0
  14. package/src/assets/images/icons/chancesleet.svg +4 -0
  15. package/src/assets/images/icons/clear-night.svg +5 -0
  16. package/src/assets/images/icons/clear.svg +11 -0
  17. package/src/assets/images/icons/cloudy.svg +4 -0
  18. package/src/assets/images/icons/drizzle.svg +5 -0
  19. package/src/assets/images/icons/fewdrops.svg +4 -0
  20. package/src/assets/images/icons/fog.svg +6 -0
  21. package/src/assets/images/icons/haze.svg +6 -0
  22. package/src/assets/images/icons/mostly-cloudy-night.svg +7 -0
  23. package/src/assets/images/icons/mostly-cloudy.svg +13 -0
  24. package/src/assets/images/icons/partially-cloudy-night.svg +6 -0
  25. package/src/assets/images/icons/partially-cloudy.svg +12 -0
  26. package/src/assets/images/icons/partlysunny.svg +6 -0
  27. package/src/assets/images/icons/rain-night.svg +8 -0
  28. package/src/assets/images/icons/rainy.svg +6 -0
  29. package/src/assets/images/icons/sleet-night.svg +14 -0
  30. package/src/assets/images/icons/sleet.svg +4 -0
  31. package/src/assets/images/icons/snow.svg +19 -0
  32. package/src/assets/images/icons/thunderstorm-night.svg +9 -0
  33. package/src/assets/images/icons/thunderstorm.svg +7 -0
  34. package/src/assets/images/icons/windy.svg +6 -0
  35. package/src/assets/images/screenly.svg +10 -0
  36. package/src/styles/base/fonts.css +30 -0
  37. package/src/styles/base/index.css +7 -0
  38. package/src/styles/base/reset.css +37 -0
  39. package/src/styles/calendar-app.css +52 -0
  40. package/src/styles/index.css +10 -0
  41. package/src/styles/tokens/colors.css +4 -0
  42. package/src/styles/tokens/index.css +10 -0
  43. package/src/styles/tokens/shadows.css +8 -0
  44. package/src/styles/tokens/spacing.css +6 -0
  45. package/src/styles/tokens/typography.css +9 -0
  46. 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,9 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Edge Apps Scripts CLI
4
+ * Wrapper around build tools for Edge Apps
5
+ */
6
+
7
+ import { run } from '../scripts/cli'
8
+
9
+ run()
@@ -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
+ })
@@ -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
+ }