@platformatic/service 1.51.8 → 2.0.0-alpha.2
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/config.d.ts +0 -16
- package/help/help.txt +0 -2
- package/index.d.ts +1 -5
- package/index.js +7 -15
- package/index.test-d.ts +2 -2
- package/lib/compile.js +22 -100
- package/lib/plugins/openapi.js +1 -12
- package/lib/plugins/typescript.js +8 -4
- package/lib/root-endpoint/index.js +0 -17
- package/lib/root-endpoint/public/index.html +4 -21
- package/lib/schema.js +58 -428
- package/lib/start.js +2 -5
- package/lib/utils.js +1 -124
- package/lib/versions/no-allow-cycles.js +15 -0
- package/package.json +8 -9
- package/schema.json +2 -192
- package/service.mjs +2 -6
- package/help/versions bump.txt +0 -25
- package/help/versions update.txt +0 -23
- package/lib/bump-version.js +0 -178
- package/lib/errors.js +0 -16
- package/lib/get-openapi-schema.js +0 -47
- package/lib/plugins/versions.js +0 -217
- package/lib/update-version.js +0 -863
package/config.d.ts
CHANGED
|
@@ -214,22 +214,6 @@ export interface PlatformaticService {
|
|
|
214
214
|
fullRequest?: boolean;
|
|
215
215
|
validateResponse?: boolean;
|
|
216
216
|
}[];
|
|
217
|
-
versions?: {
|
|
218
|
-
/**
|
|
219
|
-
* The path to the directory containing the versions mappers
|
|
220
|
-
*/
|
|
221
|
-
dir: string;
|
|
222
|
-
configs: {
|
|
223
|
-
version: string;
|
|
224
|
-
openapi?: {
|
|
225
|
-
prefix?: string;
|
|
226
|
-
path?: string;
|
|
227
|
-
};
|
|
228
|
-
plugins?: {
|
|
229
|
-
[k: string]: unknown;
|
|
230
|
-
};
|
|
231
|
-
}[];
|
|
232
|
-
};
|
|
233
217
|
}
|
|
234
218
|
export interface OpenTelemetry {
|
|
235
219
|
/**
|
package/help/help.txt
CHANGED
|
@@ -6,5 +6,3 @@ Available commands:
|
|
|
6
6
|
* `start` - start the server.
|
|
7
7
|
* `schema config` - generate the schema configuration file.
|
|
8
8
|
* `compile` - compile the typescript files.
|
|
9
|
-
* `versions bump` - bump a new version of the API.
|
|
10
|
-
* `versions update` - update the latest version of the API.
|
package/index.d.ts
CHANGED
|
@@ -46,10 +46,6 @@ export interface Stackable<ConfigType> {
|
|
|
46
46
|
transformConfig?: (config: any) => Promise<any>
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
interface SchemaExport {
|
|
50
|
-
schema: JSONSchemaType<PlatformaticServiceConfig>
|
|
51
|
-
}
|
|
52
|
-
|
|
53
49
|
interface TSCompilerOptions {
|
|
54
50
|
clean: boolean
|
|
55
51
|
}
|
|
@@ -57,7 +53,7 @@ interface TSCompiler {
|
|
|
57
53
|
compile: (cwd: string, config: object, originalLogger: FastifyBaseLogger, options: TSCompilerOptions) => Promise<boolean>
|
|
58
54
|
}
|
|
59
55
|
|
|
60
|
-
export const schema:
|
|
56
|
+
export const schema: JSONSchemaType<PlatformaticServiceConfig>
|
|
61
57
|
|
|
62
58
|
export declare const platformaticService: Stackable<PlatformaticServiceConfig>
|
|
63
59
|
|
package/index.js
CHANGED
|
@@ -4,7 +4,6 @@ const { isKeyEnabled } = require('@platformatic/utils')
|
|
|
4
4
|
const { readFile } = require('fs/promises')
|
|
5
5
|
const { join } = require('path')
|
|
6
6
|
|
|
7
|
-
const compiler = require('./lib/compile')
|
|
8
7
|
const setupCors = require('./lib/plugins/cors')
|
|
9
8
|
const setupOpenAPI = require('./lib/plugins/openapi.js')
|
|
10
9
|
const setupGraphQL = require('./lib/plugins/graphql.js')
|
|
@@ -13,10 +12,10 @@ const setupMetrics = require('./lib/plugins/metrics')
|
|
|
13
12
|
const setupTsCompiler = require('./lib/plugins/typescript')
|
|
14
13
|
const setupHealthCheck = require('./lib/plugins/health-check')
|
|
15
14
|
const loadPlugins = require('./lib/plugins/plugins')
|
|
16
|
-
const loadVersions = require('./lib/plugins/versions')
|
|
17
15
|
const upgrade = require('./lib/upgrade')
|
|
18
16
|
const { telemetry } = require('@platformatic/telemetry')
|
|
19
17
|
|
|
18
|
+
const { buildCompileCmd, extractTypeScriptCompileOptionsFromConfig } = require('./lib/compile')
|
|
20
19
|
const { schema } = require('./lib/schema')
|
|
21
20
|
const { addLoggerToTheConfig } = require('./lib/utils')
|
|
22
21
|
const { start, buildServer } = require('./lib/start')
|
|
@@ -61,8 +60,7 @@ async function platformaticService (app, opts) {
|
|
|
61
60
|
|
|
62
61
|
if (isKeyEnabled('openapi', serviceConfig)) {
|
|
63
62
|
const openapi = serviceConfig.openapi
|
|
64
|
-
|
|
65
|
-
app.register(setupOpenAPI, { openapi, versions })
|
|
63
|
+
app.register(setupOpenAPI, { openapi })
|
|
66
64
|
}
|
|
67
65
|
|
|
68
66
|
if (isKeyEnabled('graphql', serviceConfig)) {
|
|
@@ -85,13 +83,6 @@ async function platformaticService (app, opts) {
|
|
|
85
83
|
app.register(loadPlugins)
|
|
86
84
|
}
|
|
87
85
|
|
|
88
|
-
await app.register(async (app) => {
|
|
89
|
-
if (config.versions) {
|
|
90
|
-
// TODO: Add typescript mappers support
|
|
91
|
-
await app.register(loadVersions)
|
|
92
|
-
}
|
|
93
|
-
})
|
|
94
|
-
|
|
95
86
|
if (isKeyEnabled('cors', config.server)) {
|
|
96
87
|
app.register(setupCors, config.server.cors)
|
|
97
88
|
}
|
|
@@ -102,7 +93,6 @@ async function platformaticService (app, opts) {
|
|
|
102
93
|
}
|
|
103
94
|
|
|
104
95
|
platformaticService[Symbol.for('skip-override')] = true
|
|
105
|
-
platformaticService.schema = schema
|
|
106
96
|
platformaticService.configType = 'service'
|
|
107
97
|
platformaticService.configManagerConfig = {
|
|
108
98
|
version,
|
|
@@ -148,11 +138,13 @@ platformaticService.configManagerConfig = {
|
|
|
148
138
|
function _buildServer (options, app) {
|
|
149
139
|
return buildServer(options, app || platformaticService)
|
|
150
140
|
}
|
|
151
|
-
|
|
141
|
+
module.exports = platformaticService
|
|
142
|
+
module.exports.schema = schema
|
|
152
143
|
module.exports.buildServer = _buildServer
|
|
153
|
-
module.exports.
|
|
144
|
+
module.exports.schemas = require('./lib/schema')
|
|
154
145
|
module.exports.platformaticService = platformaticService
|
|
155
146
|
module.exports.addLoggerToTheConfig = addLoggerToTheConfig
|
|
156
|
-
module.exports.tsCompiler = compiler
|
|
157
147
|
module.exports.start = start
|
|
158
148
|
module.exports.Generator = ServiceGenerator
|
|
149
|
+
module.exports.buildCompileCmd = buildCompileCmd
|
|
150
|
+
module.exports.extractTypeScriptCompileOptionsFromConfig = extractTypeScriptCompileOptionsFromConfig
|
package/index.test-d.ts
CHANGED
|
@@ -36,7 +36,7 @@ function buildStackable (): Stackable<PlatformaticServiceConfig> {
|
|
|
36
36
|
await platformaticService(app, opts)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
myApp.schema = platformaticService.
|
|
39
|
+
myApp.schema = platformaticService.schema
|
|
40
40
|
myApp.configType = 'myApp'
|
|
41
41
|
myApp.configManagerConfig = {
|
|
42
42
|
version: platformaticService.configManagerConfig.version,
|
|
@@ -81,7 +81,7 @@ function buildStackable2 (): Stackable<PlatformaticServiceConfig> {
|
|
|
81
81
|
await platformaticService(app, opts)
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
myApp.schema = platformaticService.
|
|
84
|
+
myApp.schema = platformaticService.schema
|
|
85
85
|
myApp.configType = 'myApp'
|
|
86
86
|
myApp.configManagerConfig = {
|
|
87
87
|
...platformaticService.configManagerConfig,
|
package/lib/compile.js
CHANGED
|
@@ -1,107 +1,16 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const { compile } = require('@platformatic/ts-compiler')
|
|
4
|
+
const { loadConfig } = require('@platformatic/config')
|
|
4
5
|
const pino = require('pino')
|
|
5
6
|
const pretty = require('pino-pretty')
|
|
6
|
-
const {
|
|
7
|
-
const { isFileAccessible } = require('./utils.js')
|
|
8
|
-
const { readFile, rm } = require('fs/promises')
|
|
9
|
-
|
|
10
|
-
async function getTSCExecutablePath (cwd) {
|
|
11
|
-
const typescriptPath = require.resolve('typescript')
|
|
12
|
-
const typescriptPathCWD = require.resolve('typescript', { paths: [process.cwd()] })
|
|
13
|
-
|
|
14
|
-
const tscLocalPath = join(typescriptPath, '..', '..', 'bin', 'tsc')
|
|
15
|
-
const tscGlobalPath = join(typescriptPathCWD, '..', '..', 'bin', 'tsc')
|
|
16
|
-
|
|
17
|
-
const [tscLocalExists, tscGlobalExists] = await Promise.all([
|
|
18
|
-
isFileAccessible(tscLocalPath),
|
|
19
|
-
isFileAccessible(tscGlobalPath)
|
|
20
|
-
])
|
|
21
|
-
|
|
22
|
-
/* c8 ignore next 7 */
|
|
23
|
-
if (tscLocalExists) {
|
|
24
|
-
return tscLocalPath
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (tscGlobalExists) {
|
|
28
|
-
return tscGlobalPath
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async function setup (cwd, config, logger) {
|
|
33
|
-
if (!logger) {
|
|
34
|
-
logger = pino(
|
|
35
|
-
pretty({
|
|
36
|
-
translateTime: 'SYS:HH:MM:ss',
|
|
37
|
-
ignore: 'hostname,pid'
|
|
38
|
-
})
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
if (config?.server.logger) {
|
|
42
|
-
logger.level = config.server.logger.level
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const { execa } = await import('execa')
|
|
47
|
-
|
|
48
|
-
const tscExecutablePath = await getTSCExecutablePath(cwd)
|
|
49
|
-
/* c8 ignore next 4 */
|
|
50
|
-
if (tscExecutablePath === undefined) {
|
|
51
|
-
const msg = 'The tsc executable was not found.'
|
|
52
|
-
logger.warn(msg)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const tsConfigPath = config?.plugins?.typescript?.tsConfig || resolve(cwd, 'tsconfig.json')
|
|
56
|
-
const tsConfigExists = await isFileAccessible(tsConfigPath)
|
|
57
|
-
|
|
58
|
-
if (!tsConfigExists) {
|
|
59
|
-
const msg = 'No typescript configuration file was found, skipping compilation.'
|
|
60
|
-
logger.info(msg)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return { execa, logger, tscExecutablePath, tsConfigPath, tsConfigExists }
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async function compile (cwd, config, originalLogger, options) {
|
|
67
|
-
const { execa, logger, tscExecutablePath, tsConfigPath, tsConfigExists } = await setup(cwd, config, originalLogger)
|
|
68
|
-
/* c8 ignore next 3 */
|
|
69
|
-
if (!tscExecutablePath || !tsConfigExists) {
|
|
70
|
-
return false
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
const tsFlags = config?.plugins?.typescript?.flags || ['--project', tsConfigPath, '--rootDir', '.']
|
|
75
|
-
const env = {
|
|
76
|
-
...process.env
|
|
77
|
-
}
|
|
78
|
-
delete env.NODE_V8_COVERAGE
|
|
79
|
-
// somehow c8 does not pick up these lines even if there is a specific test
|
|
80
|
-
/* c8 ignore start */
|
|
81
|
-
if (options && options.clean) {
|
|
82
|
-
// delete outdir directory
|
|
83
|
-
const tsConfigContents = JSON.parse(await readFile(tsConfigPath, 'utf8'))
|
|
84
|
-
const outDir = tsConfigContents.compilerOptions.outDir
|
|
85
|
-
if (outDir) {
|
|
86
|
-
const outDirFullPath = join(dirname(tsConfigPath), outDir)
|
|
87
|
-
originalLogger.info(`Removing build directory ${outDirFullPath}`)
|
|
88
|
-
await rm(outDirFullPath, { recursive: true })
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
/* c8 ignore stop */
|
|
92
|
-
await execa(tscExecutablePath, tsFlags, { cwd, env })
|
|
93
|
-
logger.info('Typescript compilation completed successfully.')
|
|
94
|
-
return true
|
|
95
|
-
} catch (error) {
|
|
96
|
-
logger.error(error.message)
|
|
97
|
-
return false
|
|
98
|
-
}
|
|
99
|
-
}
|
|
7
|
+
const { dirname } = require('path')
|
|
100
8
|
|
|
101
9
|
function buildCompileCmd (app) {
|
|
102
10
|
return async function compileCmd (_args) {
|
|
103
11
|
let fullPath = null
|
|
104
12
|
let config = null
|
|
13
|
+
|
|
105
14
|
try {
|
|
106
15
|
const { configManager } = await loadConfig({}, _args, app, {
|
|
107
16
|
watch: false
|
|
@@ -114,9 +23,7 @@ function buildCompileCmd (app) {
|
|
|
114
23
|
console.error(err)
|
|
115
24
|
process.exit(1)
|
|
116
25
|
}
|
|
117
|
-
|
|
118
|
-
clean: _args.includes('--clean')
|
|
119
|
-
}
|
|
26
|
+
|
|
120
27
|
const logger = pino(
|
|
121
28
|
pretty({
|
|
122
29
|
translateTime: 'SYS:HH:MM:ss',
|
|
@@ -124,11 +31,26 @@ function buildCompileCmd (app) {
|
|
|
124
31
|
})
|
|
125
32
|
)
|
|
126
33
|
|
|
127
|
-
|
|
34
|
+
const compileOptions = {
|
|
35
|
+
...extractTypeScriptCompileOptionsFromConfig(config),
|
|
36
|
+
cwd: fullPath,
|
|
37
|
+
logger,
|
|
38
|
+
clean: _args.includes('--clean')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!await compile(compileOptions)) {
|
|
128
42
|
process.exit(1)
|
|
129
43
|
}
|
|
130
44
|
}
|
|
131
45
|
}
|
|
132
46
|
|
|
133
|
-
module.exports.compile = compile
|
|
134
47
|
module.exports.buildCompileCmd = buildCompileCmd
|
|
48
|
+
|
|
49
|
+
function extractTypeScriptCompileOptionsFromConfig (config) {
|
|
50
|
+
return {
|
|
51
|
+
tsConfig: config.plugins?.typescript?.tsConfig,
|
|
52
|
+
flags: config.plugins?.typescript?.flags
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports.extractTypeScriptCompileOptionsFromConfig = extractTypeScriptCompileOptionsFromConfig
|
package/lib/plugins/openapi.js
CHANGED
|
@@ -10,7 +10,7 @@ const fp = require('fastify-plugin')
|
|
|
10
10
|
// despite being covered by test/routes.test.js
|
|
11
11
|
/* c8 ignore next 33 */
|
|
12
12
|
async function setupOpenAPI (app, opts) {
|
|
13
|
-
const { openapi
|
|
13
|
+
const { openapi } = opts
|
|
14
14
|
const openapiConfig = deepmerge({
|
|
15
15
|
exposeRoute: true,
|
|
16
16
|
info: {
|
|
@@ -31,17 +31,6 @@ async function setupOpenAPI (app, opts) {
|
|
|
31
31
|
/* istanbul ignore next */
|
|
32
32
|
return json.$id || `def-${i}`
|
|
33
33
|
}
|
|
34
|
-
},
|
|
35
|
-
transform: ({ schema, url }) => {
|
|
36
|
-
// Hide versioned endpoints
|
|
37
|
-
for (const version of versions?.configs ?? []) {
|
|
38
|
-
if (url.startsWith(version.openapi.prefix)) {
|
|
39
|
-
if (!schema) schema = {}
|
|
40
|
-
schema.hide = true
|
|
41
|
-
break
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return { schema, url }
|
|
45
34
|
}
|
|
46
35
|
}
|
|
47
36
|
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const fp = require('fastify-plugin')
|
|
4
|
-
const compiler = require('
|
|
4
|
+
const compiler = require('@platformatic/ts-compiler')
|
|
5
|
+
const { extractTypeScriptCompileOptionsFromConfig } = require('../compile')
|
|
5
6
|
|
|
6
7
|
async function setupTsCompiler (app) {
|
|
7
|
-
// TODO: move params to opts
|
|
8
|
-
|
|
9
8
|
const configManager = app.platformatic.configManager
|
|
10
9
|
const config = configManager.current
|
|
11
10
|
const workingDir = configManager.dirname
|
|
12
11
|
|
|
13
|
-
await compiler.compile(
|
|
12
|
+
await compiler.compile({
|
|
13
|
+
...extractTypeScriptCompileOptionsFromConfig(config),
|
|
14
|
+
cwd: workingDir,
|
|
15
|
+
clean: false,
|
|
16
|
+
logger: app.log
|
|
17
|
+
})
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
module.exports = fp(setupTsCompiler)
|
|
@@ -5,27 +5,10 @@ const fastifyStatic = require('@fastify/static')
|
|
|
5
5
|
const userAgentParser = require('my-ua-parser')
|
|
6
6
|
|
|
7
7
|
module.exports = async (app, opts) => {
|
|
8
|
-
const versions = opts.versions || {}
|
|
9
|
-
|
|
10
8
|
app.register(fastifyStatic, {
|
|
11
9
|
root: path.join(__dirname, 'public')
|
|
12
10
|
})
|
|
13
11
|
|
|
14
|
-
app.route({
|
|
15
|
-
method: 'GET',
|
|
16
|
-
path: '/_platformatic_versions',
|
|
17
|
-
schema: { hide: true },
|
|
18
|
-
handler: () => {
|
|
19
|
-
const openapiUrls = []
|
|
20
|
-
for (const versionConfig of versions?.configs ?? []) {
|
|
21
|
-
const name = versionConfig.version
|
|
22
|
-
const prefix = versionConfig.openapi.prefix
|
|
23
|
-
openapiUrls.push({ name, prefix })
|
|
24
|
-
}
|
|
25
|
-
return openapiUrls
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
|
|
29
12
|
// root endpoint
|
|
30
13
|
app.route({
|
|
31
14
|
method: 'GET',
|
|
@@ -197,6 +197,7 @@
|
|
|
197
197
|
<div class="button-container">
|
|
198
198
|
<a href="https://docs.platformatic.dev" target="_blank" class="button-link">Documentation</a>
|
|
199
199
|
<div class="open-documentation-version buttons-list-container"> </div>
|
|
200
|
+
<a id="openapi-link" target="_blank" class="button-link">OpenAPI Documentation</a>
|
|
200
201
|
<a id="graphql-link" target="_blank" class="button-link">GraphiQL</a>
|
|
201
202
|
</div>
|
|
202
203
|
</div>
|
|
@@ -205,6 +206,9 @@
|
|
|
205
206
|
<script>
|
|
206
207
|
const currentPath = window.location.pathname
|
|
207
208
|
|
|
209
|
+
const openApiLink = document.getElementById('openapi-link')
|
|
210
|
+
openApiLink.href = currentPath + 'documentation'
|
|
211
|
+
|
|
208
212
|
const graphqlLink = document.getElementById('graphql-link')
|
|
209
213
|
graphqlLink.href = currentPath + 'graphiql'
|
|
210
214
|
|
|
@@ -225,27 +229,6 @@
|
|
|
225
229
|
document.getElementById('logo').src = 'images/platformatic-logo-dark.svg'
|
|
226
230
|
}
|
|
227
231
|
}
|
|
228
|
-
|
|
229
|
-
function join (...paths) {
|
|
230
|
-
return paths.join('/').replace(/\/+/g, '/')
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
fetch('/_platformatic_versions')
|
|
234
|
-
.then(response => response.json())
|
|
235
|
-
.then(versions => {
|
|
236
|
-
const sharedOpenapiHref = join(currentPath, 'documentation')
|
|
237
|
-
const openapiButtons = [
|
|
238
|
-
`<a href="${sharedOpenapiHref}"target="_blank" class="button-link">OpenAPI Documentation</a>`
|
|
239
|
-
]
|
|
240
|
-
|
|
241
|
-
for (const version of versions) {
|
|
242
|
-
const href = join(currentPath, version.prefix, 'documentation')
|
|
243
|
-
openapiButtons.push(`<a href="${href}" target="_blank" class="button-link">OpenAPI Documentation ${version.name}</a>`)
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const buttonList = document.getElementsByClassName('open-documentation-version')[0]
|
|
247
|
-
buttonList.innerHTML = openapiButtons.join('')
|
|
248
|
-
})
|
|
249
232
|
</script>
|
|
250
233
|
</body>
|
|
251
234
|
</html>
|