@sequencemedia/minimserver 0.1.24 → 1.1.27

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.
@@ -1,23 +1,29 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- require('dotenv/config')
3
+ import 'dotenv/config'
4
4
 
5
- const debug = require('debug')
5
+ import debug from 'debug'
6
6
 
7
- const psList = require('ps-list')
7
+ import {
8
+ readFile
9
+ } from 'fs/promises'
8
10
 
9
- const {
10
- execute
11
- } = require('./lib')
11
+ import psList from 'ps-list'
12
12
 
13
- const commander = require('commander')
13
+ import commander from 'commander'
14
14
 
15
- const PACKAGE = require('./package')
15
+ import execute from '#minimserver'
16
+
17
+ const log = debug('@sequencemedia/minimserver')
18
+
19
+ log('`minimserver` is awake')
16
20
 
17
21
  const NAME = 'ms.App'
18
22
  process.title = NAME
19
23
 
20
24
  async function app () {
25
+ const PACKAGE = JSON.parse(await readFile('./package.json', 'utf8'))
26
+
21
27
  const {
22
28
  name
23
29
  } = PACKAGE
@@ -38,21 +44,19 @@ async function app () {
38
44
  pid
39
45
  } = a.find(({ pid }) => pid !== PID)
40
46
 
41
- const log = debug('minimserver:process:log')
47
+ const log = debug('@sequencemedia/minimserver:process:log')
42
48
 
43
49
  log(`Killing application "${name}" in process ${pid}.`)
44
50
 
45
51
  process.kill(pid)
46
52
  }
47
53
  } catch ({ message }) {
48
- const error = debug('minimserver:process:error')
54
+ const error = debug('@sequencemedia/minimserver:process:error')
49
55
 
50
56
  error(message)
51
57
  return
52
58
  }
53
59
 
54
- const log = debug('minimserver:log')
55
-
56
60
  const {
57
61
  pid,
58
62
  argv,
@@ -86,7 +90,7 @@ async function app () {
86
90
  code
87
91
  } = e
88
92
 
89
- const error = debug('minimserver:commander:error')
93
+ const error = debug('@sequencemedia/minimserver:commander:error')
90
94
 
91
95
  if (code !== 'commander.missingMandatoryOptionValue') error(e)
92
96
 
@@ -113,10 +117,10 @@ async function app () {
113
117
  try {
114
118
  await execute(origin, destination, server, ignore, bounce)
115
119
  } catch ({ message }) {
116
- const error = debug('minimserver:execute:error')
120
+ const error = debug('@sequencemedia/minimserver:execute:error')
117
121
 
118
122
  error(message)
119
123
  }
120
124
  }
121
125
 
122
- module.exports = app()
126
+ export default app()
@@ -0,0 +1,21 @@
1
+ const presets = [
2
+ [
3
+ '@babel/env',
4
+ {
5
+ targets: {
6
+ node: 'current'
7
+ },
8
+ useBuiltIns: 'usage',
9
+ corejs: 3
10
+ }
11
+ ]
12
+ ]
13
+
14
+ const plugins = []
15
+
16
+ module.exports = {
17
+ compact: true,
18
+ comments: false,
19
+ presets,
20
+ plugins
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sequencemedia/minimserver",
3
- "version": "0.1.24",
3
+ "version": "1.1.27",
4
4
  "description": "Watch for changes to M3Us and rescan MinimServer",
5
5
  "keywords": [
6
6
  "minimserver",
@@ -14,11 +14,11 @@
14
14
  "m3u",
15
15
  "m3u8"
16
16
  ],
17
- "main": "./app.js",
17
+ "main": "./app.mjs",
18
18
  "author": "Jonathan Perry for Sequence Media Limited <sequencemedia@sequencemedia.net>",
19
19
  "license": "MIT",
20
20
  "engines": {
21
- "node": ">=12.19.0"
21
+ "node": ">=16.13.0"
22
22
  },
23
23
  "repository": {
24
24
  "type": "git",
@@ -29,46 +29,36 @@
29
29
  "url": "https://github.com/sequencemedia/minimserver/issues"
30
30
  },
31
31
  "scripts": {
32
- "build": "npm run babel",
33
- "build:watch": "npm run babel:watch",
34
- "clean": "rimraf lib",
35
- "babel": "babel src -d lib",
36
- "babel:watch": "npm run babel -- -w",
37
- "lint": "eslint .",
32
+ "lint": "eslint . --ext .mjs --ext .cjs",
38
33
  "lint:fix": "npm run lint -- --fix",
39
- "start": "cross-env DEBUG=minimserver*,itunes* NODE_ENV=production node app",
40
- "start:dev": "cross-env DEBUG=minimserver*,itunes* NODE_ENV=development node app",
41
- "prepublishOnly": "npm run build",
42
- "prebuild": "npm run clean"
34
+ "start": "cross-env DEBUG=@sequencemedia/minimserver* NODE_ENV=production node .",
35
+ "dev": "cross-env DEBUG=@sequencemedia/minimserver* NODE_ENV=development node ."
43
36
  },
44
37
  "dependencies": {
45
38
  "anymatch": "^3.1.2",
46
39
  "chokidar": "^3.5.2",
47
- "commander": "^8.1.0",
40
+ "commander": "^8.3.0",
48
41
  "cross-env": "^7.0.3",
49
- "debug": "^4.3.2",
42
+ "debug": "^4.3.3",
50
43
  "del": "^6.0.0",
51
44
  "dotenv": "^10.0.0",
52
45
  "fs-extra": "^10.0.0",
53
- "ps-list": "^7.2.0",
54
- "sacred-fs": "^1.2.1",
55
- "supports-color": "^9.0.2"
46
+ "ps-list": "^8.0.0",
47
+ "supports-color": "^9.2.1"
56
48
  },
57
49
  "devDependencies": {
58
- "@babel/cli": "^7.14.8",
59
- "@babel/core": "^7.14.8",
60
- "@babel/plugin-proposal-export-default-from": "^7.14.5",
61
- "@babel/plugin-proposal-export-namespace-from": "^7.14.5",
62
- "@babel/polyfill": "^7.12.1",
63
- "@babel/preset-env": "^7.14.8",
64
- "@babel/register": "^7.14.5",
65
- "babel-plugin-module-resolver": "^4.1.0",
66
- "babel-plugin-syntax-async-functions": "^6.13.0",
67
- "core-js": "^3.16.0",
68
- "@babel/eslint-parser": "^7.14.7",
69
- "eslint": "^7.32.0",
70
- "eslint-import-resolver-babel-module": "^5.3.1",
71
- "rimraf": "^3.0.2",
72
- "standard": "^16.0.3"
50
+ "@babel/cli": "^7.16.0",
51
+ "@babel/core": "^7.16.5",
52
+ "@babel/eslint-parser": "^7.16.5",
53
+ "@babel/preset-env": "^7.16.5",
54
+ "core-js": "^3.20.1",
55
+ "eslint": "7.32.0",
56
+ "eslint-config-standard": "^16.0.3",
57
+ "eslint-plugin-import": "^2.25.3",
58
+ "eslint-plugin-node": "^11.1.0",
59
+ "eslint-plugin-promise": "5.2.0"
60
+ },
61
+ "imports": {
62
+ "#minimserver": "./src/index.mjs"
73
63
  }
74
64
  }
@@ -1,27 +1,31 @@
1
+ import debug from 'debug'
2
+
1
3
  import os from 'os'
2
4
  import path from 'path'
3
5
  import {
4
6
  exec
5
7
  } from 'child_process'
6
8
 
7
- import {
8
- ensureDir,
9
- ensureFile
10
- } from 'fs-extra'
9
+ import fsExtra from 'fs-extra'
11
10
 
12
11
  import {
13
12
  stat,
14
13
  copyFile
15
- } from 'sacred-fs'
14
+ } from 'fs/promises'
16
15
 
17
16
  import chokidar from 'chokidar'
18
17
  import anymatch from 'anymatch'
19
18
  import del from 'del'
20
19
 
21
- import debug from 'debug'
20
+ const {
21
+ ensureDir,
22
+ ensureFile
23
+ } = fsExtra
24
+
25
+ const error = debug('@sequencemedia/minimserver:error')
26
+ const log = debug('@sequencemedia/minimserver')
22
27
 
23
- const error = debug('minimserver:error')
24
- const log = debug('minimserver:log')
28
+ log('`minimserver` is awake')
25
29
 
26
30
  async function originDirExists (path) {
27
31
  try {
@@ -43,19 +47,36 @@ async function originDirExists (path) {
43
47
  }
44
48
  }
45
49
 
46
- const removeAllM3UFromDestinationDir = async (path) => del(path, { force: true })
50
+ export async function removeAllM3UFromDestinationDir (path) {
51
+ /**
52
+ * log('removeAllM3UFromDestinationDir')
53
+ */
54
+ return (
55
+ await del(path, { force: true })
56
+ )
57
+ }
47
58
 
48
- const ensureDestinationDir = (path) => (
49
- new Promise((resolve, reject) => {
50
- ensureDir(path, (e) => (!e) ? resolve() : reject(e))
51
- })
52
- )
59
+ export function ensureDestinationDir (path) {
60
+ /*
61
+ * log('ensureDestinationDir')
62
+ */
63
+ return (
64
+ new Promise((resolve, reject) => {
65
+ ensureDir(path, (e) => (!e) ? resolve() : reject(e))
66
+ })
67
+ )
68
+ }
53
69
 
54
- const ensureDestinationM3U = (filePath) => (
55
- new Promise((resolve, reject) => {
56
- ensureFile(filePath, (e) => (!e) ? resolve() : reject(e))
57
- })
58
- )
70
+ export function ensureDestinationM3U (filePath) {
71
+ /*
72
+ * log('ensureDestinationM3U')
73
+ */
74
+ return (
75
+ new Promise((resolve, reject) => {
76
+ ensureFile(filePath, (e) => (!e) ? resolve() : reject(e))
77
+ })
78
+ )
79
+ }
59
80
 
60
81
  export function rescan (server) {
61
82
  /*
@@ -112,7 +133,9 @@ export function createFactory (origin, destination) {
112
133
 
113
134
  try {
114
135
  await ensureDestinationM3U(to)
115
- return copyFile(filePath, to)
136
+ return (
137
+ await copyFile(filePath, to)
138
+ )
116
139
  } catch (e) {
117
140
  const {
118
141
  code
@@ -142,7 +165,9 @@ export function changeFactory (origin, destination) {
142
165
 
143
166
  try {
144
167
  await ensureDestinationM3U(to)
145
- return copyFile(filePath, to)
168
+ return (
169
+ await copyFile(filePath, to)
170
+ )
146
171
  } catch (e) {
147
172
  const {
148
173
  code
@@ -171,7 +196,9 @@ export function removeFactory (origin, destination) {
171
196
  log('remove', to)
172
197
 
173
198
  try {
174
- return del(to, { force: true })
199
+ return (
200
+ await del(to, { force: true })
201
+ )
175
202
  } catch ({ message }) {
176
203
  error(message)
177
204
  }
@@ -324,7 +351,7 @@ export function ignorePatternFactory (ignore) {
324
351
  }
325
352
  }
326
353
 
327
- export async function execute (
354
+ export default async function execute (
328
355
  origin = '.',
329
356
  destination = '.',
330
357
  server = 'http://0.0.0.0:9790',
@@ -383,7 +410,7 @@ export async function execute (
383
410
  error(message)
384
411
  }
385
412
  })
386
- .on('error', ({ message }) => {
413
+ .on('error', function handleError ({ message }) {
387
414
  error(`Error in watcher: "${message}"`)
388
415
  })
389
416
 
@@ -1,58 +0,0 @@
1
- version: 2.1
2
-
3
- jobs:
4
- publish:
5
- docker:
6
- - image: circleci/node:lts
7
- steps:
8
- - checkout
9
- - run:
10
- name: Publish to NPM
11
- command: |
12
- echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
13
-
14
- PATTERN="([0-9]+)\.([0-9]+)\.([0-9]+)"
15
- NAME=$(node -p "require('./package').name")
16
- VERSION=$(node -p "require('./package').version")
17
- PUBLISHED_VERSION=$(npm view $NAME version)
18
-
19
- echo Version is $VERSION
20
- echo Published version is $PUBLISHED_VERSION
21
-
22
- [[ $VERSION =~ $PATTERN ]]
23
-
24
- VERSION_MAJOR="${BASH_REMATCH[1]}"
25
- VERSION_MINOR="${BASH_REMATCH[2]}"
26
- VERSION_PATCH="${BASH_REMATCH[3]}"
27
-
28
- [[ $PUBLISHED_VERSION =~ $PATTERN ]]
29
-
30
- PUBLISHED_VERSION_MAJOR="${BASH_REMATCH[1]}"
31
- PUBLISHED_VERSION_MINOR="${BASH_REMATCH[2]}"
32
- PUBLISHED_VERSION_PATCH="${BASH_REMATCH[3]}"
33
-
34
- if [ $VERSION_MAJOR -gt $PUBLISHED_VERSION_MAJOR ] || [ $VERSION_MINOR -gt $PUBLISHED_VERSION_MINOR ] || [ $VERSION_PATCH -gt $PUBLISHED_VERSION_PATCH ]
35
- then
36
- set +e
37
-
38
- npm ci
39
- npm publish
40
-
41
- if [[ $? != 0 ]];
42
- then
43
- echo Version $VERSION was not published
44
- else
45
- echo Published version $VERSION
46
- fi
47
- fi
48
-
49
- workflows:
50
- version: 2
51
- commit-workflow:
52
- jobs:
53
- - publish:
54
- filters:
55
- branches:
56
- only: master
57
- tags:
58
- only: /^v.*/
@@ -1,9 +0,0 @@
1
- version: 2
2
-
3
- updates:
4
- - package-ecosystem: "npm"
5
- directory: "/"
6
- schedule:
7
- interval: "daily"
8
- reviewers:
9
- - sequencemedialimited
package/babel.config.js DELETED
@@ -1,34 +0,0 @@
1
- const presets = [
2
- [
3
- '@babel/env',
4
- {
5
- useBuiltIns: 'usage',
6
- targets: {
7
- node: '12.9.0'
8
- },
9
- corejs: 3
10
- }
11
- ]
12
- ]
13
-
14
- const plugins = [
15
- '@babel/proposal-export-default-from',
16
- '@babel/proposal-export-namespace-from',
17
- 'syntax-async-functions',
18
- [
19
- 'module-resolver', {
20
- root: ['./src'],
21
- cwd: 'babelrc',
22
- alias: {
23
- '~': './src'
24
- }
25
- }
26
- ]
27
- ]
28
-
29
- module.exports = {
30
- compact: true,
31
- comments: false,
32
- presets,
33
- plugins
34
- }
package/lib/index.js DELETED
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.rescan=rescan;exports.restart=restart;exports.relaunch=relaunch;exports.exit=exit;exports.createFactory=createFactory;exports.changeFactory=changeFactory;exports.removeFactory=removeFactory;exports.queueRescanFactory=queueRescanFactory;exports.queueRestartFactory=queueRestartFactory;exports.queueRelaunchFactory=queueRelaunchFactory;exports.ignorePatternFactory=ignorePatternFactory;exports.execute=execute;var _os=_interopRequireDefault(require("os"));var _path=_interopRequireDefault(require("path"));var _child_process=require("child_process");var _fsExtra=require("fs-extra");var _sacredFs=require("sacred-fs");var _chokidar=_interopRequireDefault(require("chokidar"));var _anymatch=_interopRequireDefault(require("anymatch"));var _del=_interopRequireDefault(require("del"));var _debug=_interopRequireDefault(require("debug"));function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}const error=(0,_debug.default)('minimserver:error');const log=(0,_debug.default)('minimserver:log');async function originDirExists(path){try{await(0,_sacredFs.stat)(path);return true;}catch(e){const{code}=e;if(code!=='ENOENT'){const{message}=e;error(message);}return false;}}const removeAllM3UFromDestinationDir=async path=>(0,_del.default)(path,{force:true});const ensureDestinationDir=path=>new Promise((resolve,reject)=>{(0,_fsExtra.ensureDir)(path,e=>!e?resolve():reject(e));});const ensureDestinationM3U=filePath=>new Promise((resolve,reject)=>{(0,_fsExtra.ensureFile)(filePath,e=>!e?resolve():reject(e));});function rescan(server){return new Promise((resolve,reject)=>{(0,_child_process.exec)(`curl -X POST -H "Content-Type: text/plain" ${server} -d rescan`,(e,r)=>!e?resolve(r):reject(e));});}function restart(server){return new Promise((resolve,reject)=>{(0,_child_process.exec)(`curl -X POST -H "Content-Type: text/plain" ${server} -d restart`,(e,r)=>!e?resolve(r):reject(e));});}function relaunch(server){return new Promise((resolve,reject)=>{(0,_child_process.exec)(`curl -X POST -H "Content-Type: text/plain" ${server} -d relaunch`,(e,r)=>!e?resolve(r):reject(e));});}function exit(server){return new Promise((resolve,reject)=>{(0,_child_process.exec)(`curl -X POST -H "Content-Type: text/plain" ${server} -d exit`,(e,r)=>!e?resolve(r):reject(e));});}function createFactory(origin,destination){return async function create(filePath){const to=filePath.replace(origin,destination);log('create',to);try{await ensureDestinationM3U(to);return(0,_sacredFs.copyFile)(filePath,to);}catch(e){const{code}=e;if(code==='ENOENT'){error(`ENOENT in create for "${filePath}"`);}else{const{message}=e;error(message);}}};}function changeFactory(origin,destination){return async function change(filePath){const to=filePath.replace(origin,destination);log('change',to);try{await ensureDestinationM3U(to);return(0,_sacredFs.copyFile)(filePath,to);}catch(e){const{code}=e;if(code==='ENOENT'){error(`ENOENT in change for "${filePath}"`);}else{const{message}=e;error(message);}}};}function removeFactory(origin,destination){return async function remove(filePath){const to=filePath.replace(origin,destination);log('remove',to);try{return(0,_del.default)(to,{force:true});}catch({message}){error(message);}};}function queueRescanFactory(server,bounce){let t=null;let x=null;let y=null;return function enqueue(){if(t){clearTimeout(t);if(x){y=true;return;}}t=setTimeout(async function dequeue(){x=true;try{const response=await rescan(server);log(response.trim());t=null;x=null;if(y){y=null;enqueue();}}catch({message}){error(message);}},bounce);};}function queueRestartFactory(server,bounce){let t=null;let x=null;let y=null;return function enqueue(){if(t){clearTimeout(t);if(x){y=true;return;}}t=setTimeout(async function dequeue(){x=true;try{const response=await restart(server);log(response.trim());t=null;x=null;if(y){y=null;enqueue();}}catch({message}){error(message);}},bounce);};}function queueRelaunchFactory(server,bounce){let t=null;let x=null;let y=null;return function enqueue(){if(t){clearTimeout(t);if(x){y=true;return;}}t=setTimeout(async function dequeue(){x=true;try{const response=await relaunch(server);log(response.trim());t=null;x=null;if(y){y=null;enqueue();}}catch({message}){error(message);}},bounce);};}function ignorePatternFactory(ignore){const ignorePatterns=ignore.split(',');return function ignorePattern(filePath){return /(^|[/\\])\../.test(filePath)||(0,_anymatch.default)(ignorePatterns,filePath);};}async function execute(origin='.',destination='.',server='http://0.0.0.0:9790',ignore='',bounce=60000){let watcher;try{const o=_path.default.resolve(origin.replace('~',_os.default.homedir));if(!(await originDirExists(o)))throw new Error(`Origin "${origin}" does not exist.`);const d=_path.default.resolve(destination.replace('~',_os.default.homedir));const ignorePattern=ignorePatternFactory(ignore);watcher=_chokidar.default.watch(o,{ignored:ignorePattern});const create=createFactory(o,d);const change=changeFactory(o,d);const remove=removeFactory(o,d);await ensureDestinationDir(d);await removeAllM3UFromDestinationDir(d);const queueRescan=queueRescanFactory(server,bounce);watcher.on('add',async function handleAdd(filePath){try{await create(filePath);queueRescan();}catch({message}){error(message);}}).on('change',async function handleChange(filePath){try{await change(filePath);queueRescan();}catch({message}){error(message);}}).on('unlink',async function handleUnlink(filePath){try{await remove(filePath);queueRescan();}catch({message}){error(message);}}).on('error',({message})=>{error(`Error in watcher: "${message}"`);});queueRescan();}catch({message}){if(watcher)watcher.close();error(message);}}