@platformatic/foundation 3.0.0-alpha.5 → 3.0.0-alpha.7
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 +1 -1
- package/index.d.ts +16 -6
- package/index.js +1 -0
- package/lib/cli.js +3 -3
- package/lib/configuration.js +3 -2
- package/lib/execution.js +60 -2
- package/lib/logger.js +3 -3
- package/lib/module.js +1 -2
- package/lib/node.js +1 -1
- package/lib/schema.js +29 -14
- package/lib/symbols.js +5 -0
- package/package.json +3 -4
package/LICENSE
CHANGED
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
with Licensor regarding such Contributions.
|
|
137
137
|
|
|
138
138
|
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
-
names, trademarks,
|
|
139
|
+
names, trademarks, application marks, or product names of the Licensor,
|
|
140
140
|
except as required for reasonable and customary use in describing the
|
|
141
141
|
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
142
|
|
package/index.d.ts
CHANGED
|
@@ -3,8 +3,14 @@ import { JSONSchemaType } from 'ajv'
|
|
|
3
3
|
import { EventEmitter } from 'node:events'
|
|
4
4
|
import { Logger } from 'pino'
|
|
5
5
|
|
|
6
|
-
//
|
|
6
|
+
// Symbols
|
|
7
|
+
export declare const kCanceled: unique symbol
|
|
8
|
+
export declare const kFailedImport: unique symbol
|
|
9
|
+
export declare const kHandledError: unique symbol
|
|
7
10
|
export declare const kMetadata: unique symbol
|
|
11
|
+
export declare const kTimeout: unique symbol
|
|
12
|
+
|
|
13
|
+
// Configuration types
|
|
8
14
|
export declare const envVariablePattern: RegExp
|
|
9
15
|
export declare const knownConfigurationFilesExtensions: string[]
|
|
10
16
|
export declare const knownConfigurationFilesSchemas: RegExp[]
|
|
@@ -117,8 +123,13 @@ export declare const SchemaMustBeDefinedError: FastifyError
|
|
|
117
123
|
export declare const ConfigurationDoesNotValidateAgainstSchemaError: FastifyError
|
|
118
124
|
|
|
119
125
|
// Execution types
|
|
120
|
-
export declare const kTimeout: unique symbol
|
|
121
126
|
export declare function executeWithTimeout<T> (promise: Promise<T>, timeout: number, timeoutValue?: any): Promise<T>
|
|
127
|
+
export declare function executeInParallel<T, Args extends any[]> (
|
|
128
|
+
fn: (...args: Args) => Promise<T>,
|
|
129
|
+
args: Args[],
|
|
130
|
+
concurrency?: number,
|
|
131
|
+
throwOnRejections?: boolean
|
|
132
|
+
): Promise<T[]>
|
|
122
133
|
|
|
123
134
|
// File system types
|
|
124
135
|
export declare function removeDotSlash (path: string): string
|
|
@@ -167,7 +178,7 @@ export declare function buildPinoTimestamp (timestamp: string): Function
|
|
|
167
178
|
export declare function buildPinoOptions (
|
|
168
179
|
loggerConfig: any,
|
|
169
180
|
serverConfig: any,
|
|
170
|
-
|
|
181
|
+
applicationId?: string,
|
|
171
182
|
workerId?: string,
|
|
172
183
|
context?: any,
|
|
173
184
|
root?: string
|
|
@@ -185,7 +196,6 @@ export declare const stdTimeFunctions: {
|
|
|
185
196
|
}
|
|
186
197
|
|
|
187
198
|
// Module types
|
|
188
|
-
export declare const kFailedImport: unique symbol
|
|
189
199
|
export declare const defaultPackageManager: string
|
|
190
200
|
|
|
191
201
|
export declare function getLatestNpmVersion (pkg: string): Promise<string | null>
|
|
@@ -201,7 +211,7 @@ export declare function detectApplicationType (
|
|
|
201
211
|
export declare function loadModule (require: NodeRequire, path: string): Promise<any>
|
|
202
212
|
|
|
203
213
|
// Node types
|
|
204
|
-
export declare function
|
|
214
|
+
export declare function checkNodeVersionForApplications (): void
|
|
205
215
|
export declare const features: {
|
|
206
216
|
node: {
|
|
207
217
|
reusePort: boolean
|
|
@@ -234,7 +244,7 @@ export declare const health: JSONSchemaType<object>
|
|
|
234
244
|
export declare const healthWithoutDefaults: JSONSchemaType<object>
|
|
235
245
|
export declare const telemetryExporter: JSONSchemaType<object>
|
|
236
246
|
export declare const telemetry: JSONSchemaType<object>
|
|
237
|
-
export declare const
|
|
247
|
+
export declare const applications: JSONSchemaType<object[]>
|
|
238
248
|
export declare const runtimeUnwrappablePropertiesList: string[]
|
|
239
249
|
export declare const runtimeProperties: JSONSchemaType<object>
|
|
240
250
|
export declare const wrappedRuntimeProperties: JSONSchemaType<object>
|
package/index.js
CHANGED
package/lib/cli.js
CHANGED
|
@@ -152,8 +152,8 @@ export function getRoot (positionals) {
|
|
|
152
152
|
return root
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
export function
|
|
156
|
-
return `
|
|
155
|
+
export function applicationToEnvVariable (application) {
|
|
156
|
+
return `PLT_APPLICATION_${application.toUpperCase().replaceAll(/[^A-Z0-9_]/g, '_')}_PATH`
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
export async function findRuntimeConfigurationFile (
|
|
@@ -166,7 +166,7 @@ export async function findRuntimeConfigurationFile (
|
|
|
166
166
|
) {
|
|
167
167
|
let configFile = await findConfigurationFileRecursive(root, configurationFile, '@platformatic/runtime')
|
|
168
168
|
|
|
169
|
-
// If a runtime was not found, search for
|
|
169
|
+
// If a runtime was not found, search for application file that we wrap in a runtime
|
|
170
170
|
if (!configFile && !configurationFile) {
|
|
171
171
|
configFile = await findConfigurationFileRecursive(root, configurationFile)
|
|
172
172
|
}
|
package/lib/configuration.js
CHANGED
|
@@ -17,13 +17,13 @@ import {
|
|
|
17
17
|
} from './errors.js'
|
|
18
18
|
import { isFileAccessible } from './file-system.js'
|
|
19
19
|
import { loadModule, splitModuleFromVersion } from './module.js'
|
|
20
|
+
import { kMetadata } from './symbols.js'
|
|
20
21
|
|
|
21
22
|
const { parse: parseJSON5, stringify: rawStringifyJSON5 } = JSON5
|
|
22
23
|
const { parse: parseTOML, stringify: stringifyTOML } = toml
|
|
23
24
|
|
|
24
25
|
const kReplaceEnvIgnore = Symbol('plt.foundation.replaceEnvIgnore')
|
|
25
26
|
|
|
26
|
-
export const kMetadata = Symbol('plt.foundation.metadata')
|
|
27
27
|
export const envVariablePattern = /(?:\{{1,2})([a-z0-9_]+)(?:\}{1,2})/i
|
|
28
28
|
|
|
29
29
|
export const knownConfigurationFilesExtensions = ['json', 'json5', 'yaml', 'yml', 'toml', 'tml']
|
|
@@ -120,7 +120,8 @@ export function printValidationErrors (err) {
|
|
|
120
120
|
|
|
121
121
|
export function listRecognizedConfigurationFiles (suffixes, extensions) {
|
|
122
122
|
if (typeof suffixes === 'undefined' || suffixes === null) {
|
|
123
|
-
|
|
123
|
+
// composer is retained for backward compatibility with V2
|
|
124
|
+
suffixes = ['runtime', 'service', 'application', 'db', 'gateway', 'composer']
|
|
124
125
|
} else if (suffixes && !Array.isArray(suffixes)) {
|
|
125
126
|
suffixes = [suffixes]
|
|
126
127
|
} else if (!suffixes) {
|
package/lib/execution.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Unpromise } from '@watchable/unpromise'
|
|
2
2
|
import { setTimeout as sleep } from 'node:timers/promises'
|
|
3
|
-
|
|
4
|
-
export const kTimeout = Symbol('plt.utils.timeout')
|
|
3
|
+
import { kCanceled, kTimeout } from './symbols.js'
|
|
5
4
|
|
|
6
5
|
export async function executeWithTimeout (promise, timeout, timeoutValue = kTimeout) {
|
|
7
6
|
const ac = new AbortController()
|
|
@@ -11,3 +10,62 @@ export async function executeWithTimeout (promise, timeout, timeoutValue = kTime
|
|
|
11
10
|
return value
|
|
12
11
|
})
|
|
13
12
|
}
|
|
13
|
+
|
|
14
|
+
export async function executeInParallel (fn, args, concurrency = 5, throwOnRejections = true, throwAllErrors = false) {
|
|
15
|
+
const { promise, resolve } = Promise.withResolvers()
|
|
16
|
+
const results = new Map()
|
|
17
|
+
let current = 0
|
|
18
|
+
let pending = 0
|
|
19
|
+
let firstError
|
|
20
|
+
let terminated = false
|
|
21
|
+
|
|
22
|
+
if (args.length === 0) {
|
|
23
|
+
return []
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function scheduleNext () {
|
|
27
|
+
// While we have capacity and there are still items to process
|
|
28
|
+
while (current < args.length && pending < concurrency) {
|
|
29
|
+
const i = current++
|
|
30
|
+
pending++
|
|
31
|
+
|
|
32
|
+
// Perform the async operation
|
|
33
|
+
fn(...args[i])
|
|
34
|
+
.then(result => {
|
|
35
|
+
results.set(i, result)
|
|
36
|
+
})
|
|
37
|
+
.catch(err => {
|
|
38
|
+
results.set(i, err)
|
|
39
|
+
firstError = err
|
|
40
|
+
})
|
|
41
|
+
.finally(() => {
|
|
42
|
+
pending--
|
|
43
|
+
|
|
44
|
+
if (terminated) {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if ((current === args.length && pending === 0) || (firstError && throwOnRejections)) {
|
|
49
|
+
terminated = true
|
|
50
|
+
resolve()
|
|
51
|
+
} else {
|
|
52
|
+
scheduleNext()
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
scheduleNext()
|
|
59
|
+
await promise
|
|
60
|
+
|
|
61
|
+
const returnedValues = []
|
|
62
|
+
for (let j = 0; j < args.length; j++) {
|
|
63
|
+
returnedValues.push(results.has(j) ? results.get(j) : kCanceled)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (firstError && throwOnRejections) {
|
|
67
|
+
throw throwAllErrors ? AggregateError(returnedValues, 'One or more operations failed.') : firstError
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return returnedValues
|
|
71
|
+
}
|
package/lib/logger.js
CHANGED
|
@@ -54,13 +54,13 @@ export function buildPinoTimestamp (timestamp) {
|
|
|
54
54
|
return stdTimeFunctions[timestamp]
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
export function buildPinoOptions (loggerConfig, serverConfig,
|
|
57
|
+
export function buildPinoOptions (loggerConfig, serverConfig, applicationId, workerId, context, root) {
|
|
58
58
|
const pinoOptions = {
|
|
59
59
|
level: loggerConfig?.level ?? serverConfig?.level ?? 'trace'
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
if (
|
|
63
|
-
pinoOptions.name =
|
|
62
|
+
if (applicationId) {
|
|
63
|
+
pinoOptions.name = applicationId
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
if (loggerConfig?.base) {
|
package/lib/module.js
CHANGED
|
@@ -4,11 +4,10 @@ import { resolve } from 'node:path'
|
|
|
4
4
|
import { fileURLToPath } from 'node:url'
|
|
5
5
|
import { request } from 'undici'
|
|
6
6
|
import { hasJavascriptFiles } from './file-system.js'
|
|
7
|
+
import { kFailedImport } from './symbols.js'
|
|
7
8
|
|
|
8
9
|
let platformaticPackageVersion
|
|
9
10
|
|
|
10
|
-
export const kFailedImport = Symbol('plt.utils.failedImport')
|
|
11
|
-
|
|
12
11
|
export const defaultPackageManager = 'npm'
|
|
13
12
|
|
|
14
13
|
export async function getLatestNpmVersion (pkg) {
|
package/lib/node.js
CHANGED
package/lib/schema.js
CHANGED
|
@@ -618,13 +618,13 @@ export const telemetry = {
|
|
|
618
618
|
}
|
|
619
619
|
]
|
|
620
620
|
},
|
|
621
|
-
|
|
621
|
+
applicationName: {
|
|
622
622
|
type: 'string',
|
|
623
|
-
description: 'The name of the
|
|
623
|
+
description: 'The name of the application. Defaults to the folder name if not specified.'
|
|
624
624
|
},
|
|
625
625
|
version: {
|
|
626
626
|
type: 'string',
|
|
627
|
-
description: 'The version of the
|
|
627
|
+
description: 'The version of the application (optional)'
|
|
628
628
|
},
|
|
629
629
|
skip: {
|
|
630
630
|
type: 'array',
|
|
@@ -655,11 +655,11 @@ export const telemetry = {
|
|
|
655
655
|
]
|
|
656
656
|
}
|
|
657
657
|
},
|
|
658
|
-
required: ['
|
|
658
|
+
required: ['applicationName'],
|
|
659
659
|
additionalProperties: false
|
|
660
660
|
}
|
|
661
661
|
|
|
662
|
-
export const
|
|
662
|
+
export const applications = {
|
|
663
663
|
type: 'array',
|
|
664
664
|
items: {
|
|
665
665
|
type: 'object',
|
|
@@ -689,6 +689,13 @@ export const services = {
|
|
|
689
689
|
},
|
|
690
690
|
workers,
|
|
691
691
|
health: { ...healthWithoutDefaults },
|
|
692
|
+
dependencies: {
|
|
693
|
+
type: 'array',
|
|
694
|
+
items: {
|
|
695
|
+
type: 'string'
|
|
696
|
+
},
|
|
697
|
+
default: []
|
|
698
|
+
},
|
|
692
699
|
arguments: {
|
|
693
700
|
type: 'array',
|
|
694
701
|
items: {
|
|
@@ -750,10 +757,11 @@ export const services = {
|
|
|
750
757
|
export const runtimeUnwrappablePropertiesList = [
|
|
751
758
|
'$schema',
|
|
752
759
|
'entrypoint',
|
|
760
|
+
'applications',
|
|
753
761
|
'autoload',
|
|
754
|
-
'
|
|
762
|
+
'applications',
|
|
755
763
|
'web',
|
|
756
|
-
'
|
|
764
|
+
'resolvedApplicationsBasePath'
|
|
757
765
|
]
|
|
758
766
|
|
|
759
767
|
export const runtimeProperties = {
|
|
@@ -802,6 +810,12 @@ export const runtimeProperties = {
|
|
|
802
810
|
workers,
|
|
803
811
|
health: { ...healthWithoutDefaults },
|
|
804
812
|
preload,
|
|
813
|
+
dependencies: {
|
|
814
|
+
type: 'array',
|
|
815
|
+
items: {
|
|
816
|
+
type: 'string'
|
|
817
|
+
}
|
|
818
|
+
},
|
|
805
819
|
arguments: {
|
|
806
820
|
type: 'array',
|
|
807
821
|
items: {
|
|
@@ -816,9 +830,10 @@ export const runtimeProperties = {
|
|
|
816
830
|
}
|
|
817
831
|
}
|
|
818
832
|
},
|
|
819
|
-
|
|
833
|
+
applications,
|
|
834
|
+
services: applications,
|
|
835
|
+
web: applications,
|
|
820
836
|
workers: { ...workers, default: 1 },
|
|
821
|
-
web: services,
|
|
822
837
|
logger,
|
|
823
838
|
server,
|
|
824
839
|
startTimeout: {
|
|
@@ -849,7 +864,7 @@ export const runtimeProperties = {
|
|
|
849
864
|
],
|
|
850
865
|
default: 10000
|
|
851
866
|
},
|
|
852
|
-
|
|
867
|
+
application: {
|
|
853
868
|
anyOf: [
|
|
854
869
|
{
|
|
855
870
|
type: 'number',
|
|
@@ -861,7 +876,7 @@ export const runtimeProperties = {
|
|
|
861
876
|
}
|
|
862
877
|
},
|
|
863
878
|
default: {},
|
|
864
|
-
required: ['runtime', '
|
|
879
|
+
required: ['runtime', 'application'],
|
|
865
880
|
additionalProperties: false
|
|
866
881
|
},
|
|
867
882
|
health,
|
|
@@ -1081,7 +1096,7 @@ export const runtimeProperties = {
|
|
|
1081
1096
|
}
|
|
1082
1097
|
}
|
|
1083
1098
|
},
|
|
1084
|
-
|
|
1099
|
+
applicationTimeout: {
|
|
1085
1100
|
anyOf: [
|
|
1086
1101
|
{
|
|
1087
1102
|
type: 'number',
|
|
@@ -1101,7 +1116,7 @@ export const runtimeProperties = {
|
|
|
1101
1116
|
],
|
|
1102
1117
|
default: 30000 // 5 minutes
|
|
1103
1118
|
},
|
|
1104
|
-
|
|
1119
|
+
resolvedApplicationsBasePath: {
|
|
1105
1120
|
type: 'string',
|
|
1106
1121
|
default: 'external'
|
|
1107
1122
|
},
|
|
@@ -1182,7 +1197,7 @@ export const schemaComponents = {
|
|
|
1182
1197
|
healthWithoutDefaults,
|
|
1183
1198
|
telemetryExporter,
|
|
1184
1199
|
telemetry,
|
|
1185
|
-
|
|
1200
|
+
applications,
|
|
1186
1201
|
runtimeProperties,
|
|
1187
1202
|
wrappedRuntimeProperties,
|
|
1188
1203
|
wrappedRuntime
|
package/lib/symbols.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export const kCanceled = Symbol('plt.foundation.canceled')
|
|
2
|
+
export const kFailedImport = Symbol('plt.foundation.failedImport')
|
|
3
|
+
export const kHandledError = Symbol('plt.foundation.handledError')
|
|
4
|
+
export const kMetadata = Symbol('plt.foundation.metadata')
|
|
5
|
+
export const kTimeout = Symbol('plt.foundation.timeout')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/foundation",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.7",
|
|
4
4
|
"description": "Platformatic Foundation",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"yaml": "^2.4.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"borp": "^0.20.0",
|
|
37
36
|
"c8": "^10.0.0",
|
|
37
|
+
"cleaner-spec-reporter": "^0.5.0",
|
|
38
38
|
"eslint": "9",
|
|
39
39
|
"fastify": "^5.0.0",
|
|
40
40
|
"neostandard": "^0.12.0",
|
|
@@ -46,8 +46,7 @@
|
|
|
46
46
|
"node": ">=22.18.0"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
|
-
"test": "
|
|
50
|
-
"coverage": "c8 -r html -r text node --test --test-concurrency=1 --test-timeout=1200000 test/*.test.js",
|
|
49
|
+
"test": "node --test --test-reporter=cleaner-spec-reporter --test-concurrency=1 --test-timeout=2000000 test/*.test.js test/**/*.test.js",
|
|
51
50
|
"lint": "eslint"
|
|
52
51
|
}
|
|
53
52
|
}
|