@platformatic/basic 2.0.0-alpha.9 → 2.0.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.
package/index.js CHANGED
@@ -7,13 +7,34 @@ import pino from 'pino'
7
7
  import { packageJson, schema } from './lib/schema.js'
8
8
  import { importFile } from './lib/utils.js'
9
9
 
10
+ const importStackablePackageMarker = '__pltImportStackablePackage.js'
11
+
12
+ export const configCandidates = [
13
+ 'platformatic.application.json',
14
+ 'platformatic.json',
15
+ 'watt.json',
16
+ 'platformatic.application.yaml',
17
+ 'platformatic.yaml',
18
+ 'watt.yaml',
19
+ 'platformatic.application.yml',
20
+ 'platformatic.yml',
21
+ 'watt.yml',
22
+ 'platformatic.application.toml',
23
+ 'platformatic.toml',
24
+ 'watt.toml',
25
+ 'platformatic.application.tml',
26
+ 'platformatic.tml',
27
+ 'watt.tml'
28
+ ]
29
+
10
30
  function isImportFailedError (error, pkg) {
11
- if (error.code !== 'ERR_MODULE_NOT_FOUND') {
31
+ if (error.code !== 'ERR_MODULE_NOT_FOUND' && error.code !== 'MODULE_NOT_FOUND') {
12
32
  return false
13
33
  }
14
34
 
15
35
  const match = error.message.match(/Cannot find package '(.+)' imported from (.+)/)
16
- return match?.[1] === pkg
36
+
37
+ return match?.[1] === pkg || error.requireStack?.[0].endsWith(importStackablePackageMarker)
17
38
  }
18
39
 
19
40
  async function importStackablePackage (opts, pkg, autodetectDescription) {
@@ -27,7 +48,7 @@ async function importStackablePackage (opts, pkg, autodetectDescription) {
27
48
  }
28
49
 
29
50
  // Scope to the service
30
- const require = createRequire(resolve(opts.context.directory, 'index.js'))
51
+ const require = createRequire(resolve(opts.context.directory, importStackablePackageMarker))
31
52
  const imported = require.resolve(pkg)
32
53
  return await importFile(imported)
33
54
  }
@@ -36,17 +57,10 @@ async function importStackablePackage (opts, pkg, autodetectDescription) {
36
57
  throw e
37
58
  }
38
59
 
39
- const rootFolder = relative(process.cwd(), workerData.dirname)
40
-
41
- let errorMessage = `Unable to import package, "${pkg}". Please add it as a dependency `
42
-
43
- if (rootFolder) {
44
- errorMessage += `in the package.json file in the folder ${rootFolder}.`
45
- } else {
46
- errorMessage += 'in the root package.json file.'
47
- }
48
-
49
- throw new Error(errorMessage)
60
+ const serviceDirectory = relative(workerData.dirname, opts.context.directory)
61
+ throw new Error(
62
+ `Unable to import package '${pkg}'. Please add it as a dependency in the package.json file in the folder ${serviceDirectory}.`
63
+ )
50
64
  }
51
65
  }
52
66
 
@@ -65,10 +79,13 @@ async function buildStackable (opts) {
65
79
  const hadConfig = opts.config
66
80
 
67
81
  if (!hadConfig) {
68
- const candidate = resolve(root, 'platformatic.application.json')
82
+ for (const candidate of configCandidates) {
83
+ const candidatePath = resolve(root, candidate)
69
84
 
70
- if (existsSync(candidate)) {
71
- opts.config = candidate
85
+ if (existsSync(candidatePath)) {
86
+ opts.config = candidatePath
87
+ break
88
+ }
72
89
  }
73
90
  }
74
91
 
@@ -91,7 +108,10 @@ async function buildStackable (opts) {
91
108
  const imported = await importStackablePackage(opts, toImport, autodetectDescription)
92
109
 
93
110
  const serviceRoot = relative(process.cwd(), opts.context.directory)
94
- if (!hadConfig && !existsSync(resolve(serviceRoot, 'platformatic.application.json'))) {
111
+ if (
112
+ !hadConfig &&
113
+ !existsSync(resolve(serviceRoot, 'platformatic.json') || existsSync(resolve(serviceRoot, 'watt.json')))
114
+ ) {
95
115
  const logger = pino({
96
116
  level: opts.context.serverConfig?.logger?.level ?? 'warn',
97
117
  name: opts.context.serviceId
@@ -100,7 +120,7 @@ async function buildStackable (opts) {
100
120
  logger.warn(
101
121
  [
102
122
  `Platformatic has auto-detected that service ${opts.context.serviceId} ${autodetectDescription}.\n`,
103
- `We suggest you create a platformatic.application.json file in the folder ${serviceRoot} with the "$schema" `,
123
+ `We suggest you create a platformatic.json or watt.json file in the folder ${serviceRoot} with the "$schema" `,
104
124
  `property set to "https://schemas.platformatic.dev/${toImport}/${packageJson.version}.json".`
105
125
  ].join('')
106
126
  )
package/lib/base.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { deepmerge } from '@platformatic/utils'
1
2
  import { parseCommandString } from 'execa'
2
3
  import { spawn } from 'node:child_process'
3
4
  import { once } from 'node:events'
@@ -19,10 +20,11 @@ export class BaseStackable {
19
20
  this.type = type
20
21
  this.version = version
21
22
  this.id = options.context.serviceId
23
+ this.telemetryConfig = options.context.telemetryConfig
22
24
  this.options = options
23
25
  this.root = root
24
26
  this.configManager = configManager
25
- this.serverConfig = options.context.serverConfig
27
+ this.serverConfig = deepmerge(options.context.serverConfig ?? {}, configManager.current.server ?? {})
26
28
  this.openapiSchema = null
27
29
  this.getGraphqlSchema = null
28
30
  this.isEntrypoint = options.context.isEntrypoint
@@ -30,7 +32,7 @@ export class BaseStackable {
30
32
 
31
33
  // Setup the logger
32
34
  const pinoOptions = {
33
- level: (this.configManager.current.server ?? this.serverConfig)?.logger?.level ?? 'trace'
35
+ level: this.serverConfig?.logger?.level ?? 'trace'
34
36
  }
35
37
 
36
38
  if (this.id) {
@@ -54,6 +56,10 @@ export class BaseStackable {
54
56
  return this.configManager.current
55
57
  }
56
58
 
59
+ async getEnv () {
60
+ return this.configManager.env
61
+ }
62
+
57
63
  async getWatchConfig () {
58
64
  const config = this.configManager.current
59
65
 
@@ -175,7 +181,6 @@ export class BaseStackable {
175
181
  async startWithCommand (command, loader) {
176
182
  const config = this.configManager.current
177
183
  const basePath = config.application?.basePath ? cleanBasePath(config.application?.basePath) : ''
178
-
179
184
  this.#childManager = new ChildManager({
180
185
  logger: this.logger,
181
186
  loader,
@@ -185,7 +190,8 @@ export class BaseStackable {
185
190
  root: pathToFileURL(this.root).toString(),
186
191
  basePath,
187
192
  logLevel: this.logger.level,
188
- port: (this.isEntrypoint ? this.serverConfig?.port || 0 : undefined) ?? true
193
+ port: (this.isEntrypoint ? this.serverConfig?.port || 0 : undefined) ?? true,
194
+ telemetry: this.telemetryConfig
189
195
  }
190
196
  })
191
197
 
@@ -1,5 +1,5 @@
1
1
  import { ITC, generateNotification } from '@platformatic/itc'
2
- import { createDirectory, errors } from '@platformatic/utils'
2
+ import { createDirectory, ensureLoggableError } from '@platformatic/utils'
3
3
  import { once } from 'node:events'
4
4
  import { rm, writeFile } from 'node:fs/promises'
5
5
  import { createServer } from 'node:http'
@@ -213,7 +213,7 @@ export class ChildManager extends ITC {
213
213
  }
214
214
 
215
215
  #handleUnexpectedError (error, message, exitCode) {
216
- this.#logger.error({ err: errors.ensureLoggableError(error) }, message)
216
+ this.#logger.error({ err: ensureLoggableError(error) }, message)
217
217
  process.exit(exitCode)
218
218
  }
219
219
  }
@@ -1,11 +1,13 @@
1
1
  import { ITC } from '@platformatic/itc'
2
- import { createPinoWritable, errors } from '@platformatic/utils'
2
+ import { setupNodeHTTPTelemetry } from '@platformatic/telemetry'
3
+ import { createPinoWritable, ensureLoggableError } from '@platformatic/utils'
3
4
  import { tracingChannel } from 'node:diagnostics_channel'
4
5
  import { once } from 'node:events'
5
6
  import { readFile } from 'node:fs/promises'
6
7
  import { register } from 'node:module'
7
8
  import { platform, tmpdir } from 'node:os'
8
9
  import { basename, resolve } from 'node:path'
10
+ import { fileURLToPath } from 'node:url'
9
11
  import { isMainThread } from 'node:worker_threads'
10
12
  import pino from 'pino'
11
13
  import { getGlobalDispatcher, setGlobalDispatcher } from 'undici'
@@ -90,6 +92,7 @@ export class ChildProcess extends ITC {
90
92
 
91
93
  this.listen()
92
94
  this.#setupLogger()
95
+ this.#setupTelemetry()
93
96
  this.#setupHandlers()
94
97
  this.#setupServer()
95
98
  this.#setupInterceptors()
@@ -115,7 +118,7 @@ export class ChildProcess extends ITC {
115
118
  try {
116
119
  this.#listener(JSON.parse(message))
117
120
  } catch (error) {
118
- this.#logger.error({ err: errors.ensureLoggableError(error) }, 'Handling a message failed.')
121
+ this.#logger.error({ err: ensureLoggableError(error) }, 'Handling a message failed.')
119
122
  process.exit(exitCodes.PROCESS_MESSAGE_HANDLING_FAILED)
120
123
  }
121
124
  })
@@ -158,12 +161,18 @@ export class ChildProcess extends ITC {
158
161
  })
159
162
 
160
163
  Reflect.defineProperty(process, 'stdout', { value: createPinoWritable(this.#logger, 'info') })
161
- Reflect.defineProperty(process, 'stderr', { value: createPinoWritable(this.#logger, 'error') })
164
+ Reflect.defineProperty(process, 'stderr', { value: createPinoWritable(this.#logger, 'error', true) })
162
165
  } else {
163
166
  this.#logger = pino({ level: 'info', name: globalThis.platformatic.id })
164
167
  }
165
168
  }
166
169
 
170
+ #setupTelemetry () {
171
+ if (globalThis.platformatic.telemetry) {
172
+ setupNodeHTTPTelemetry(globalThis.platformatic.telemetry, this.#logger)
173
+ }
174
+ }
175
+
167
176
  #setupServer () {
168
177
  const subscribers = {
169
178
  asyncStart ({ options }) {
@@ -196,9 +205,8 @@ export class ChildProcess extends ITC {
196
205
 
197
206
  #setupHandlers () {
198
207
  function handleUnhandled (type, err) {
199
- process._rawDebug(globalThis.platformatic.id, err)
200
208
  this.#logger.error(
201
- { err: errors.ensureLoggableError(err) },
209
+ { err: ensureLoggableError(err) },
202
210
  `Child process for service ${globalThis.platformatic.id} threw an ${type}.`
203
211
  )
204
212
 
@@ -216,6 +224,10 @@ async function main () {
216
224
 
217
225
  globalThis.platformatic = data
218
226
 
227
+ if (data.root && isMainThread) {
228
+ process.chdir(fileURLToPath(data.root))
229
+ }
230
+
219
231
  if (loader) {
220
232
  register(loader, { data })
221
233
  }
@@ -1,5 +1,5 @@
1
1
  import { generateRequest } from '@platformatic/itc'
2
- import { errors } from '@platformatic/utils'
2
+ import { ensureLoggableError } from '@platformatic/utils'
3
3
  import { once } from 'node:events'
4
4
  import { platform } from 'node:os'
5
5
  import { workerData } from 'node:worker_threads'
@@ -9,7 +9,7 @@ import { getSocketPath } from './child-manager.js'
9
9
 
10
10
  function logDirectError (message, error) {
11
11
  process._rawDebug(`Logger thread for child process of service ${workerData.id} ${message}.`, {
12
- error: errors.ensureLoggableError(error)
12
+ error: ensureLoggableError(error)
13
13
  })
14
14
  }
15
15
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/basic",
3
- "version": "2.0.0-alpha.9",
3
+ "version": "2.0.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -23,15 +23,16 @@
23
23
  "split2": "^4.2.0",
24
24
  "undici": "^6.19.5",
25
25
  "ws": "^8.18.0",
26
- "@platformatic/config": "2.0.0-alpha.9",
27
- "@platformatic/itc": "2.0.0-alpha.9",
28
- "@platformatic/utils": "2.0.0-alpha.9"
26
+ "@platformatic/config": "2.0.0",
27
+ "@platformatic/itc": "2.0.0",
28
+ "@platformatic/telemetry": "2.0.0",
29
+ "@platformatic/utils": "2.0.0"
29
30
  },
30
31
  "devDependencies": {
31
32
  "borp": "^0.17.0",
32
33
  "eslint": "9",
33
34
  "express": "^4.19.2",
34
- "fastify": "5.0.0-alpha.4",
35
+ "fastify": "^5.0.0",
35
36
  "json-schema-to-typescript": "^15.0.0",
36
37
  "neostandard": "^0.11.1",
37
38
  "next": "^14.2.5",
@@ -39,8 +40,8 @@
39
40
  "react-dom": "^18.3.1",
40
41
  "typescript": "^5.5.4",
41
42
  "vite": "^5.4.0",
42
- "@platformatic/composer": "2.0.0-alpha.9",
43
- "@platformatic/service": "2.0.0-alpha.9"
43
+ "@platformatic/service": "2.0.0",
44
+ "@platformatic/composer": "2.0.0"
44
45
  },
45
46
  "scripts": {
46
47
  "gen-schema": "node lib/schema.js > schema.json",
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/@platformatic/basic/2.0.0-alpha.9.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/basic/2.0.0.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Stackable",
5
5
  "type": "object",