pockethost 1.4.0 → 1.6.0

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,9 +1,12 @@
1
+ import { uniqueId } from '@s-libs/micro-dash'
1
2
  import { Express, Request, Response } from 'express'
3
+ import { dbg } from '../../cli'
2
4
  import { LogLevelName } from '../Logger'
3
5
  import { DEBUG } from '../debug'
4
6
  import { InstanceFields } from '../schema'
5
7
 
6
8
  enum CoreActions {
9
+ AfterPluginsLoaded = 'core_after_plugins_loaded',
7
10
  Init = 'core_init',
8
11
  Serve = 'core_serve',
9
12
  AppMounted = 'core_on_app_mount',
@@ -18,6 +21,8 @@ enum CoreActions {
18
21
  BeforeInstanceStarted = 'core_before_instance_started',
19
22
  AfterInstanceStarted = 'core_after_instance_started',
20
23
 
24
+ KillInstance = 'core_kill_instance',
25
+
21
26
  BeforeInstanceStopped = 'core_before_instance_stopped',
22
27
  AfterInstanceStopped = 'core_after_instance_stopped',
23
28
 
@@ -27,20 +32,34 @@ enum CoreActions {
27
32
  Request = 'core_edge_request',
28
33
  }
29
34
 
30
- const actions: {
31
- [key: string]: ActionHandler<any>[]
32
- } = {}
33
-
34
35
  export type ActionHandler<TContext = {}> = (
35
36
  context: TContext extends never ? [] : TContext,
36
37
  ) => Promise<void>
37
38
 
38
- async function registerAction(
39
+ interface Action {
40
+ priority: number
41
+ handler: ActionHandler<any>
42
+ }
43
+
44
+ const actions: {
45
+ [key: string]: Action[]
46
+ } = {}
47
+
48
+ function registerAction(
39
49
  action: string,
40
50
  handler: (...args: any[]) => Promise<void>,
41
- ) {
51
+ priority: number = 10,
52
+ ): () => void {
42
53
  if (!(action in actions)) actions[action] = []
43
- actions[action]!.push(handler)
54
+ const uid = uniqueId(`a:${action}:`)
55
+ dbg(`${uid}:subscribe`)
56
+ actions[action]!.push({ priority, handler })
57
+ actions[action]!.sort((a, b) => a.priority - b.priority)
58
+
59
+ return () => {
60
+ dbg(`${uid}:unsubscribe`)
61
+ actions[action] = actions[action]!.filter((a) => a.handler !== handler)
62
+ }
44
63
  }
45
64
 
46
65
  async function action(actionName: string, context: any) {
@@ -49,7 +68,9 @@ async function action(actionName: string, context: any) {
49
68
  }
50
69
  const action = actions[actionName]
51
70
  if (!action) return false
52
- await Promise.all(action.map((handler) => handler(context)))
71
+ for (const { handler } of action) {
72
+ await handler(context)
73
+ }
53
74
  return true
54
75
  }
55
76
 
@@ -58,18 +79,22 @@ export function createCustomActionWithContext<TContext extends {}>(
58
79
  ) {
59
80
  return [
60
81
  async (context: TContext) => action(actionName, context),
61
- async (handler: ActionHandler<TContext>) =>
62
- registerAction(actionName, handler),
82
+ (handler: ActionHandler<TContext>, priority = 10) =>
83
+ registerAction(actionName, handler, priority),
63
84
  ] as const
64
85
  }
65
86
 
66
87
  export function createCustomAction(actionName: CoreActions) {
67
88
  return [
68
89
  async () => action(actionName, {}),
69
- async (handler: ActionHandler) => registerAction(actionName, handler),
90
+ (handler: ActionHandler, priority = 10) =>
91
+ registerAction(actionName, handler, priority),
70
92
  ] as const
71
93
  }
72
94
 
95
+ export const [doAfterPluginsLoadedAction, onAfterPluginsLoadedAction] =
96
+ createCustomAction(CoreActions.AfterPluginsLoaded)
97
+
73
98
  export const [doRequestErrorAction, onRequestErrorAction] =
74
99
  createCustomActionWithContext<{
75
100
  err: Error
@@ -92,7 +117,9 @@ export const [doInstanceLogAction, onInstanceLogAction] =
92
117
  }>(CoreActions.InstanceLog)
93
118
 
94
119
  export const [doAppMountedAction, onAppMountedAction] =
95
- createCustomActionWithContext<{ app: Express }>(CoreActions.AppMounted)
120
+ createCustomActionWithContext<{ app: Express; internalApp: Express }>(
121
+ CoreActions.AppMounted,
122
+ )
96
123
 
97
124
  export const [doIncomingRequestAction, onIncomingRequestAction] =
98
125
  createCustomActionWithContext<{ req: Request; res: Response; host: string }>(
@@ -117,6 +144,11 @@ export const [doAfterInstanceStartedAction, onAfterInstanceStartedAction] =
117
144
  CoreActions.AfterInstanceStarted,
118
145
  )
119
146
 
147
+ export const [doKillInstanceAction, onKillInstanceAction] =
148
+ createCustomActionWithContext<{ instance: InstanceFields }>(
149
+ CoreActions.KillInstance,
150
+ )
151
+
120
152
  export const [doBeforeInstanceStoppedAction, onBeforeInstanceStoppedAction] =
121
153
  createCustomActionWithContext<{ instance: InstanceFields; url: string }>(
122
154
  CoreActions.BeforeInstanceStopped,
@@ -2,13 +2,19 @@ import { Command } from 'commander'
2
2
  import { Request, Response } from 'express'
3
3
  import { DEBUG } from '../debug'
4
4
  import { InstanceFields, InstanceId } from '../schema'
5
+ import { UserId } from '../schema/BaseFields'
5
6
 
6
7
  export enum CoreFilters {
8
+ Settings = 'core_settings',
7
9
  CliCommands = 'core_cli_commands',
8
10
  ServeSlugs = 'core_serve_slugs',
9
11
  SpawnConfig = 'core_spawn_config',
12
+ AuthenticateUser = 'core_authenticate_user',
10
13
  GetInstanceByRequestInfo = 'core_get_instance_by_request_info',
11
14
  GetInstanceById = 'core_get_instance_by_id',
15
+ GetOneInstanceByExactCriteria = 'core_get_one_instance_by_exact_criteria',
16
+ GetAllInstancesByExactCriteria = 'core_get_all_instances_by_exact_criteria',
17
+ InstanceConfig = 'core_instance_config',
12
18
  ErrorSpawningInstanceMessage = 'core_error_spawning_instance_message',
13
19
  FailedToLaunchInstanceMessage = 'core_failed_to_launch_instance_message',
14
20
  AuthenticateRequest = 'core_authenticate_request',
@@ -16,6 +22,7 @@ export enum CoreFilters {
16
22
  GetOrProvisionInstanceUrl = 'core_get_or_provision_instance_url',
17
23
  PocketBaseLaunchHandler = 'core_pocket_base_launch_handler',
18
24
  NewInstanceRecord = 'core_new_instance_record',
25
+ IsInstanceRunning = 'core_is_instance_running',
19
26
  }
20
27
 
21
28
  export type FilterHandler<TCarry, TContext> = (
@@ -30,14 +37,23 @@ const filters: {
30
37
  [key: string]: FilterEntry<any>[]
31
38
  } = {}
32
39
 
33
- async function registerFilter<TCarry, TContext extends {} = {}>(
40
+ function registerFilter<TCarry, TContext extends {} = {}>(
34
41
  filter: string,
35
42
  handler: FilterHandler<TCarry, TContext>,
36
43
  priority = 10,
37
- ) {
44
+ ): () => void {
38
45
  if (!(filter in filters)) filters[filter] = []
39
46
  filters[filter]!.push({ priority, handler })
40
47
  filters[filter]!.sort((a, b) => a.priority - b.priority)
48
+
49
+ return () => {
50
+ const index = filters[filter]!.findIndex(
51
+ (entry) => entry.handler === handler,
52
+ )
53
+ if (index !== -1) {
54
+ filters[filter]!.splice(index, 1)
55
+ }
56
+ }
41
57
  }
42
58
 
43
59
  async function filter<TCarry, TContext extends {} = {}>(
@@ -52,7 +68,14 @@ async function filter<TCarry, TContext extends {} = {}>(
52
68
  if (!filter) return initialValue
53
69
  return filter.reduce(
54
70
  (carry, entry) =>
55
- carry.then((carryRes) => entry.handler(carryRes, context)),
71
+ carry
72
+ .then((carryRes) => entry.handler(carryRes, context))
73
+ .then((carryRes) => {
74
+ if (DEBUG()) {
75
+ console.log(`f:${filterName}`, carryRes, context)
76
+ }
77
+ return carryRes
78
+ }),
56
79
  Promise.resolve(initialValue),
57
80
  ) as TCarry
58
81
  }
@@ -63,8 +86,15 @@ function createCustomFilterWithContext<TCarry, TContext extends {} = {}>(
63
86
  return [
64
87
  async (initialValue: TCarry, context: TContext) =>
65
88
  filter<TCarry, TContext>(filterName, initialValue, context),
66
- async (handler: FilterHandler<TCarry, TContext>, priority = 10) =>
67
- registerFilter<TCarry, TContext>(filterName, handler, priority),
89
+ async <TExtraCarry = unknown>(
90
+ handler: FilterHandler<TCarry & TExtraCarry, TContext>,
91
+ priority = 10,
92
+ ) =>
93
+ registerFilter<TCarry & TExtraCarry, TContext>(
94
+ filterName,
95
+ handler,
96
+ priority,
97
+ ),
68
98
  ] as const
69
99
  }
70
100
 
@@ -72,11 +102,24 @@ function createCustomFilter<TCarry>(filterName: string) {
72
102
  return [
73
103
  async (initialValue: TCarry) =>
74
104
  filter<TCarry>(filterName, initialValue, {}),
75
- async (handler: FilterHandler<TCarry, {}>, priority = 10) =>
76
- registerFilter<TCarry, {}>(filterName, handler, priority),
105
+ async <TExtraCarry = unknown>(
106
+ handler: FilterHandler<TCarry & TExtraCarry, {}>,
107
+ priority = 10,
108
+ ) =>
109
+ registerFilter<TCarry & TExtraCarry, {}>(filterName, handler, priority),
77
110
  ] as const
78
111
  }
79
112
 
113
+ export const [doSettingsFilter, onSettingsFilter] = createCustomFilter<{
114
+ [_: string]: any
115
+ }>(CoreFilters.Settings)
116
+
117
+ export const [doAuthenticateUserFilter, onAuthenticateUserFilter] =
118
+ createCustomFilterWithContext<
119
+ UserId | undefined,
120
+ { username: string; password: string }
121
+ >(CoreFilters.AuthenticateUser)
122
+
80
123
  export const [
81
124
  doGetInstanceByRequestInfoFilter,
82
125
  onGetInstanceByRequestInfoFilter,
@@ -91,6 +134,22 @@ export const [doGetInstanceByIdFilter, onGetInstanceByIdFilter] =
91
134
  { instanceId: InstanceId }
92
135
  >(CoreFilters.GetInstanceById)
93
136
 
137
+ export const [
138
+ doGetOneInstanceByExactCriteriaFilter,
139
+ onGetOneInstanceByExactCriteriaFilter,
140
+ ] = createCustomFilterWithContext<
141
+ InstanceFields | undefined,
142
+ Partial<InstanceFields & { [_: string]: string | number }>
143
+ >(CoreFilters.GetOneInstanceByExactCriteria)
144
+
145
+ export const [
146
+ doGetAllInstancesByExactCriteriaFilter,
147
+ onGetAllInstancesByExactCriteriaFilter,
148
+ ] = createCustomFilterWithContext<
149
+ InstanceFields[],
150
+ Partial<InstanceFields & { [_: string]: string | number }>
151
+ >(CoreFilters.GetAllInstancesByExactCriteria)
152
+
94
153
  export const [doCliCommandsFilter, onCliCommandsFilter] = createCustomFilter<
95
154
  Command[]
96
155
  >(CoreFilters.CliCommands)
@@ -105,12 +164,8 @@ export const [
105
164
  doGetOrProvisionInstanceUrlFilter,
106
165
  onGetOrProvisionInstanceUrlFilter,
107
166
  ] = createCustomFilterWithContext<
108
- string,
167
+ string | undefined,
109
168
  {
110
- req: Request
111
- res: Response
112
- host: string
113
- subdomain: string
114
169
  instance: InstanceFields
115
170
  }
116
171
  >(CoreFilters.GetOrProvisionInstanceUrl)
@@ -118,3 +173,25 @@ export const [
118
173
  export const [doServeSlugsFilter, onServeSlugsFilter] = createCustomFilter<
119
174
  string[]
120
175
  >(CoreFilters.ServeSlugs)
176
+
177
+ export type Bind = {
178
+ base: string
179
+ src: string
180
+ }
181
+ export type Binds = {
182
+ data: Bind[]
183
+ hooks: Bind[]
184
+ migrations: Bind[]
185
+ public: Bind[]
186
+ }
187
+ export type InstanceConfig = {
188
+ binds: Binds
189
+ env: { [_: string]: string }
190
+ }
191
+ export const [doInstanceConfigFilter, onInstanceConfigFilter] =
192
+ createCustomFilter<InstanceConfig>(CoreFilters.InstanceConfig)
193
+
194
+ export const [doIsInstanceRunningFilter, onIsInstanceRunningFilter] =
195
+ createCustomFilterWithContext<boolean, { instance: InstanceFields }>(
196
+ CoreFilters.IsInstanceRunning,
197
+ )
@@ -0,0 +1,10 @@
1
+ export type RecordId = string
2
+ export type UserId = RecordId
3
+ export type IsoDate = string
4
+ export type BaseFields = {
5
+ id: RecordId
6
+ created: IsoDate
7
+ updated: IsoDate
8
+ }
9
+
10
+ export type AnyField = { [_: string]: string | number }
@@ -1,4 +1,6 @@
1
1
  import { doNewInstanceRecordFilter } from '../plugin'
2
+ import { IsoDate } from './BaseFields'
3
+ import { newId, pocketNow } from './util'
2
4
 
3
5
  export type VersionId = string
4
6
 
@@ -21,16 +23,24 @@ export type InstanceSecretCollection = {
21
23
  }
22
24
 
23
25
  export type InstanceFields = {
26
+ id: string
24
27
  subdomain: string
25
28
  version: VersionId
26
29
  secrets: InstanceSecretCollection
27
30
  dev: boolean // Should instance run in --dev mode
31
+ created: IsoDate
32
+ updated: IsoDate
28
33
  }
29
34
 
30
- export const mkInstance = (subdomain: string) =>
31
- doNewInstanceRecordFilter({
35
+ export const mkInstance = (subdomain: string, id = newId()) => {
36
+ const now = pocketNow()
37
+ return doNewInstanceRecordFilter({
38
+ id,
32
39
  subdomain,
33
40
  version: '*',
34
41
  secrets: {},
35
42
  dev: false,
43
+ created: now,
44
+ updated: now,
36
45
  })
46
+ }
@@ -1 +1,7 @@
1
- export const pocketNow = () => new Date().toISOString()
1
+ import { customAlphabet } from 'nanoid'
2
+ import { IsoDate } from './BaseFields'
3
+
4
+ export const newId = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10)
5
+ export const pocketNow = () => toPocketDate(new Date())
6
+ export const toPocketDate = (date: Date) => date.toISOString()
7
+ export const fromPocketDate = (iso: IsoDate) => new Date(iso)
package/src/constants.ts CHANGED
@@ -1,11 +1,10 @@
1
- import { forEach } from '@s-libs/micro-dash'
2
1
  import { config } from 'dotenv'
3
2
  import envPaths from 'env-paths'
4
3
  import { dirname, join } from 'path'
5
4
  import { cwd } from 'process'
6
5
  import { fileURLToPath } from 'url'
7
6
  import { mkBoolean, mkCsvString, mkNumber, mkPath, mkString } from '../core'
8
- import { InstanceId } from './common'
7
+ import { InstanceFields, InstanceId } from './common'
9
8
  import { DEBUG, IS_DEV } from './common/debug'
10
9
  import { Settings } from './core/Settings'
11
10
 
@@ -17,11 +16,7 @@ config({ path: [join(_PH_HOME, '.env'), join(cwd(), `.env`)] })
17
16
 
18
17
  export const _PH_PROJECT_DIR = join(__dirname, '..')
19
18
  export const _APEX_DOMAIN = process.env.APEX_DOMAIN || 'pockethost.lvh.me'
20
- export const _HTTP_PROTOCOL = process.env.HTTP_PROTOCOL || `https:`
21
19
 
22
- export function isSettingKey(key: string): key is keyof typeof settings {
23
- return key in settings
24
- }
25
20
  export const settings = Settings({
26
21
  PH_PLUGINS: mkCsvString([
27
22
  `@pockethost/plugin-console-logger`,
@@ -32,6 +27,7 @@ export const settings = Settings({
32
27
  PH_HOME: mkPath(_PH_HOME),
33
28
  PH_PROJECT_DIR: mkPath(_PH_PROJECT_DIR),
34
29
 
30
+ PH_INTERNAL_HOST: mkString('localhost'),
35
31
  PH_APEX_DOMAIN: mkString(_APEX_DOMAIN),
36
32
 
37
33
  PH_PORT: mkNumber(3000),
@@ -39,6 +35,7 @@ export const settings = Settings({
39
35
  PH_DATA_DIR: mkPath(join(_PH_HOME, 'data'), { create: true }),
40
36
  PH_DEV: mkBoolean(IS_DEV()),
41
37
  PH_DEBUG: mkBoolean(DEBUG()),
38
+ PH_INTERNAL_APP_SECRET: mkString(''),
42
39
  })
43
40
 
44
41
  /** Accessors */
@@ -57,13 +54,17 @@ export const DATA_DIR = (...paths: string[]) =>
57
54
  export const NODE_ENV = () => process.env.NODE_ENV
58
55
  export const INSTANCE_DATA_DIR = (id: InstanceId, ...paths: string[]) =>
59
56
  join(DATA_DIR(), id, ...paths)
60
-
61
- export const logConstants = () => {
62
- forEach(settings, (v, k) => {
63
- console.log(`${k}: ${v}`)
64
- })
65
- }
66
-
67
- if (DEBUG()) {
68
- logConstants()
57
+ export const INTERNAL_HOST = () => settings.PH_INTERNAL_HOST
58
+ export const INTERNAL_APP_SECRET = () => settings.PH_INTERNAL_APP_SECRET
59
+ export const INTERNAL_APP_URL = (...paths: string[]) =>
60
+ `${HTTP_PROTOCOL()}//${INTERNAL_HOST()}:${PORT()}/${INTERNAL_APP_PREFIX}/${join(
61
+ ...paths,
62
+ )}`
63
+ export const INTERNAL_APP_PREFIX = `_internal`
64
+ export const INTERNAL_APP_AUTH_HEADER = `x-pockethost-authorization`
65
+ export const HTTP_PROTOCOL = () => (PORT() === 443 ? 'https:' : 'http:')
66
+ export const PUBLIC_INSTANCE_URL = ({ subdomain }: Partial<InstanceFields>) => {
67
+ const url = new URL(`${HTTP_PROTOCOL()}//${subdomain}.${APEX_DOMAIN()}`)
68
+ url.port = `${PORT() === 80 || PORT() == 443 ? '' : PORT()}`
69
+ return url
69
70
  }
@@ -0,0 +1,108 @@
1
+ import { forEach, keys, omit, uniq } from '@s-libs/micro-dash'
2
+ import { parse } from 'dotenv'
3
+ import { existsSync, readFileSync, writeFileSync } from 'fs'
4
+ import { info } from '../cli'
5
+ import { PH_HOME, settings } from '../constants'
6
+
7
+ const envFile = () => {
8
+ const envFile = PH_HOME(`.env`)
9
+ if (!existsSync(envFile)) {
10
+ writeFileSync(envFile, '')
11
+ }
12
+ return envFile
13
+ }
14
+
15
+ export const setConfig = (name: string, value: string) => {
16
+ if (value === '=') throw new Error(`Invalid value ${value}`)
17
+
18
+ const values = _parse()
19
+ values[name] = value
20
+ writeFileSync(
21
+ envFile(),
22
+ Object.entries(values)
23
+ .map(([k, v]) => `${k}=${v}`)
24
+ .join('\n'),
25
+ )
26
+ process.env[name] = value
27
+ info(`Set ${name}=${value}`)
28
+ info(`Written to ${envFile()}`)
29
+ }
30
+
31
+ export const unsetConfig = (name: string) => {
32
+ const values = _parse()
33
+ delete values[name]
34
+ writeFileSync(
35
+ envFile(),
36
+ Object.entries(values)
37
+ .map(([k, v]) => `${k}=${v}`)
38
+ .join('\n'),
39
+ )
40
+ info(`Unset ${name}`)
41
+ info(`Written to ${envFile()}`)
42
+ }
43
+
44
+ export const listConfig = () => {
45
+ const values = _parse()
46
+
47
+ if (keys(values).length > 0) {
48
+ info()
49
+ info(`Config values from ${envFile()}:`)
50
+ forEach(values, (v, k) => {
51
+ info(`\t${k}=${v}`)
52
+ })
53
+ info()
54
+ } else {
55
+ info(`No config values found in ${envFile()}`)
56
+ }
57
+
58
+ const defaults = omit(settings, keys(values) as any)
59
+ if (keys(defaults).length > 0) {
60
+ info(`Default values:`)
61
+ forEach(settings, (v, k) => {
62
+ if (k in values) return
63
+ info(`\t${k}=${v}`)
64
+ })
65
+ } else {
66
+ info(`No default values because all values are defined in ${envFile()}`)
67
+ }
68
+ }
69
+
70
+ export const appendConfig = (name: string, value: string) => {
71
+ const values = _parse()
72
+ values[name] = uniq([
73
+ ...(values[name]
74
+ ?.split(/,/)
75
+ .map((v) => v.trim())
76
+ .filter((v) => !!v) || []),
77
+ value,
78
+ ]).join(`,`)
79
+ writeFileSync(
80
+ envFile(),
81
+ Object.entries(values)
82
+ .map(([k, v]) => `${k}=${v}`)
83
+ .join('\n'),
84
+ )
85
+ info(`Added ${value} to ${name}`)
86
+ info(`Written to ${envFile()}`)
87
+ }
88
+
89
+ export const filterConfig = (name: string, value: string) => {
90
+ const values = _parse()
91
+ values[name] = uniq([
92
+ ...(values[name]
93
+ ?.split(/,/)
94
+ .map((v) => v.trim())
95
+ .filter((v) => v !== value) || []),
96
+ ]).join(`,`)
97
+ writeFileSync(
98
+ envFile(),
99
+ Object.entries(values)
100
+ .map(([k, v]) => `${k}=${v}`)
101
+ .join('\n'),
102
+ )
103
+ info(`Filtered ${value} from ${name}`)
104
+ info(`Written to ${envFile()}`)
105
+ }
106
+
107
+ export const _parse = () =>
108
+ parse(readFileSync(envFile(), { encoding: 'utf8' }).toString())
package/src/core/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from '../constants'
2
2
  export * from './Settings'
3
3
  export * from './asyncExecutionGuard'
4
+ export * from './config'
4
5
  export * from './exit'
5
6
  export * from './internal'
6
7
  export * from './smartFetch'
@@ -1,4 +1,4 @@
1
- import fetch, { Response } from 'node-fetch'
1
+ import fetch, { RequestInit, Response } from 'node-fetch'
2
2
  import { LoggerService } from '../common'
3
3
 
4
4
  export const TRYFETCH_RETRY_MS = 50
@@ -6,7 +6,7 @@ export const TRYFETCH_RETRY_MS = 50
6
6
  export type TryFetchConfig = {
7
7
  preflight: () => Promise<boolean>
8
8
  retryMs: number
9
- }
9
+ } & RequestInit
10
10
 
11
11
  /**
12
12
  * @param url The URL to fetch
@@ -53,7 +53,10 @@ export const tryFetch = async (
53
53
  }
54
54
  try {
55
55
  dbg(`Fetch: START`)
56
- const res = await fetch(url, { signal: AbortSignal.timeout(500) })
56
+ const res = await fetch(url, {
57
+ ...config,
58
+ signal: AbortSignal.timeout(500),
59
+ })
57
60
  dbg(`Fetch: SUCCESS`)
58
61
  resolve(res)
59
62
  } catch (e) {
@@ -0,0 +1,3 @@
1
+ /// <reference path="./lib.d.ts" />
2
+ /// <reference path="./goja.d.ts" />
3
+ /// <reference path="./types.d.ts" />
@@ -0,0 +1,58 @@
1
+ interface Require {
2
+ (id: string): any
3
+ }
4
+ declare var require: Require
5
+
6
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console) */
7
+ interface Console {
8
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/assert) */
9
+ assert(condition?: boolean, ...data: any[]): void
10
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/clear) */
11
+ clear(): void
12
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/count) */
13
+ count(label?: string): void
14
+ /**
15
+ * [MDN
16
+ * Reference](https://developer.mozilla.org/docs/Web/API/console/countReset)
17
+ */
18
+ countReset(label?: string): void
19
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/debug) */
20
+ debug(...data: any[]): void
21
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/dir) */
22
+ dir(item?: any, options?: any): void
23
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/dirxml) */
24
+ dirxml(...data: any[]): void
25
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error) */
26
+ error(...data: any[]): void
27
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/group) */
28
+ group(...data: any[]): void
29
+ /**
30
+ * [MDN
31
+ * Reference](https://developer.mozilla.org/docs/Web/API/console/groupCollapsed)
32
+ */
33
+ groupCollapsed(...data: any[]): void
34
+ /**
35
+ * [MDN
36
+ * Reference](https://developer.mozilla.org/docs/Web/API/console/groupEnd)
37
+ */
38
+ groupEnd(): void
39
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/info) */
40
+ info(...data: any[]): void
41
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log) */
42
+ log(...data: any[]): void
43
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/table) */
44
+ table(tabularData?: any, properties?: string[]): void
45
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/time) */
46
+ time(label?: string): void
47
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/timeEnd) */
48
+ timeEnd(label?: string): void
49
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/timeLog) */
50
+ timeLog(label?: string, ...data: any[]): void
51
+ timeStamp(label?: string): void
52
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/trace) */
53
+ trace(...data: any[]): void
54
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/warn) */
55
+ warn(...data: any[]): void
56
+ }
57
+
58
+ declare var console: Console
@@ -0,0 +1,5 @@
1
+ type Logger = (...args: any[]) => void
2
+
3
+ interface Lib {
4
+ mkLog: (namespace: string) => Logger
5
+ }