@platformatic/astro 2.72.0 → 3.0.0-alpha.1
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 +1 -1
- package/index.js +24 -335
- package/lib/schema.js +4 -2
- package/lib/stackable.js +298 -0
- package/package.json +7 -9
- package/schema.json +2 -2
package/config.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -1,342 +1,31 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
importFile,
|
|
12
|
-
resolvePackage,
|
|
13
|
-
schemaOptions
|
|
14
|
-
} from '@platformatic/basic'
|
|
15
|
-
import { ConfigManager } from '@platformatic/config'
|
|
16
|
-
import { features } from '@platformatic/utils'
|
|
17
|
-
import fastify from 'fastify'
|
|
18
|
-
import { existsSync } from 'node:fs'
|
|
19
|
-
import { readFile, writeFile } from 'node:fs/promises'
|
|
20
|
-
import { dirname, resolve } from 'node:path'
|
|
21
|
-
import { satisfies } from 'semver'
|
|
22
|
-
import { packageJson, schema } from './lib/schema.js'
|
|
23
|
-
|
|
24
|
-
const supportedVersions = '^4.0.0 || ^5.0.0'
|
|
25
|
-
|
|
26
|
-
export class AstroStackable extends BaseStackable {
|
|
27
|
-
#astro
|
|
28
|
-
#app
|
|
29
|
-
#server
|
|
30
|
-
#basePath
|
|
31
|
-
|
|
32
|
-
constructor (options, root, configManager) {
|
|
33
|
-
super('astro', packageJson.version, options, root, configManager)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async init () {
|
|
37
|
-
if (this.isProduction) {
|
|
38
|
-
return
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
this.#astro = resolve(dirname(resolvePackage(this.root, 'astro')), '../..')
|
|
42
|
-
const astroPackage = JSON.parse(await readFile(resolve(this.#astro, 'package.json'), 'utf-8'))
|
|
43
|
-
|
|
44
|
-
if (!satisfies(astroPackage.version, supportedVersions)) {
|
|
45
|
-
throw new errors.UnsupportedVersion('astro', astroPackage.version, supportedVersions)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async start ({ listen }) {
|
|
50
|
-
// Make this idempotent
|
|
51
|
-
if (this.url) {
|
|
52
|
-
return this.url
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (this.isProduction) {
|
|
56
|
-
await this.#startProduction(listen)
|
|
57
|
-
} else {
|
|
58
|
-
await this.#startDevelopment(listen)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
await this._collectMetrics()
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async stop () {
|
|
65
|
-
if (this.childManager) {
|
|
66
|
-
return this.stopCommand()
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return this.isProduction ? this.#app.close() : this.#app.stop()
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async build () {
|
|
73
|
-
const config = this.configManager.current
|
|
74
|
-
const command = config.application.commands.build
|
|
75
|
-
const configFile = config.astro.configFile // Note: Astro expect this to be a relative path to the root
|
|
76
|
-
let basePath = config.application?.basePath
|
|
77
|
-
? ensureTrailingSlash(cleanBasePath(config.application?.basePath))
|
|
78
|
-
: undefined
|
|
79
|
-
|
|
80
|
-
if (command) {
|
|
81
|
-
return this.buildWithCommand(command, basePath)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
await this.init()
|
|
85
|
-
const { build } = await importFile(resolve(this.#astro, 'dist/core/index.js'))
|
|
86
|
-
|
|
87
|
-
try {
|
|
88
|
-
globalThis.platformatic.isBuilding = true
|
|
89
|
-
|
|
90
|
-
await build({
|
|
91
|
-
root: this.root,
|
|
92
|
-
base: basePath,
|
|
93
|
-
outDir: config.application.outputDirectory,
|
|
94
|
-
mode: 'production',
|
|
95
|
-
configFile,
|
|
96
|
-
logLevel: this.logger.level,
|
|
97
|
-
integrations: [
|
|
98
|
-
{
|
|
99
|
-
name: 'platformatic',
|
|
100
|
-
hooks: {
|
|
101
|
-
'astro:config:done': ({ config }) => {
|
|
102
|
-
basePath = ensureTrailingSlash(cleanBasePath(config.base))
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
]
|
|
107
|
-
})
|
|
108
|
-
} finally {
|
|
109
|
-
globalThis.platformatic.isBuilding = false
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
await writeFile(
|
|
113
|
-
resolve(this.root, config.application.outputDirectory, '.platformatic-build.json'),
|
|
114
|
-
JSON.stringify({ basePath }),
|
|
115
|
-
'utf-8'
|
|
116
|
-
)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/* c8 ignore next 5 */
|
|
120
|
-
async getWatchConfig () {
|
|
121
|
-
return {
|
|
122
|
-
enabled: false
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
getMeta () {
|
|
127
|
-
const config = this.subprocessConfig ?? this.#app?.config
|
|
128
|
-
|
|
129
|
-
const composer = {
|
|
130
|
-
tcp: typeof this.url !== 'undefined',
|
|
131
|
-
url: this.url,
|
|
132
|
-
prefix: this.basePath ?? config?.base ?? this.#basePath,
|
|
133
|
-
wantsAbsoluteUrls: true,
|
|
134
|
-
needsRootTrailingSlash: true,
|
|
135
|
-
needsRefererBasedRedirect: !this.isProduction
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return { composer }
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// This is only used in non SSR production mode as in other modes a TCP server is started
|
|
142
|
-
async inject (injectParams, onInject) {
|
|
143
|
-
const res = await this.#app.inject(injectParams, onInject)
|
|
144
|
-
|
|
145
|
-
/* c8 ignore next 3 */
|
|
146
|
-
if (onInject) {
|
|
147
|
-
return
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Since inject might be called from the main thread directly via ITC, let's clean it up
|
|
151
|
-
const { statusCode, headers, body, payload, rawPayload } = res
|
|
152
|
-
return { statusCode, headers, body, payload, rawPayload }
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
async #startDevelopment () {
|
|
156
|
-
// Make this idempotent
|
|
157
|
-
if (this.url) {
|
|
158
|
-
return this.url
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const config = this.configManager.current
|
|
162
|
-
const command = this.configManager.current.application.commands.development
|
|
163
|
-
|
|
164
|
-
this.#basePath = config.application?.basePath
|
|
165
|
-
? ensureTrailingSlash(cleanBasePath(config.application?.basePath))
|
|
166
|
-
: undefined
|
|
167
|
-
|
|
168
|
-
this.registerGlobals({ basePath: this.#basePath })
|
|
169
|
-
|
|
170
|
-
if (command) {
|
|
171
|
-
return this.startWithCommand(command)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Prepare options
|
|
175
|
-
const { hostname, port } = this.serverConfig ?? {}
|
|
176
|
-
const configFile = config.astro.configFile // Note: Astro expect this to be a relative path to the root
|
|
177
|
-
|
|
178
|
-
const serverOptions = {
|
|
179
|
-
host: hostname || '127.0.0.1',
|
|
180
|
-
port: port || 0
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Require Astro
|
|
184
|
-
const serverPromise = createServerListener(
|
|
185
|
-
(this.isEntrypoint ? serverOptions?.port : undefined) ?? true,
|
|
186
|
-
(this.isEntrypoint ? serverOptions?.hostname : undefined) ?? true
|
|
187
|
-
)
|
|
188
|
-
const { dev } = await importFile(resolve(this.#astro, 'dist/core/index.js'))
|
|
189
|
-
|
|
190
|
-
// Create the server and listen
|
|
191
|
-
this.#app = await dev({
|
|
192
|
-
root: this.root,
|
|
193
|
-
base: this.#basePath,
|
|
194
|
-
mode: 'development',
|
|
195
|
-
configFile,
|
|
196
|
-
logLevel: this.logger.level,
|
|
197
|
-
server: serverOptions,
|
|
198
|
-
vite: {
|
|
199
|
-
server: {
|
|
200
|
-
allowedHosts: ['.plt.local']
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
integrations: [
|
|
204
|
-
{
|
|
205
|
-
name: 'platformatic',
|
|
206
|
-
hooks: {
|
|
207
|
-
'astro:config:setup': ({ config }) => {
|
|
208
|
-
this.#basePath = ensureTrailingSlash(cleanBasePath(config.base))
|
|
209
|
-
|
|
210
|
-
/*
|
|
211
|
-
As Astro generates invalid paths in development mode which ignore the basePath
|
|
212
|
-
(see https://github.com/withastro/astro/issues/11445), make sure we provide
|
|
213
|
-
the prefix in HMR path.
|
|
214
|
-
*/
|
|
215
|
-
config.vite.server ??= {}
|
|
216
|
-
config.vite.server.hmr ??= {}
|
|
217
|
-
config.vite.server.hmr.path = `/${this.#basePath}/`.replaceAll(/\/+/g, '/')
|
|
218
|
-
config.vite.server.fs ??= {}
|
|
219
|
-
config.vite.server.fs.strict = false
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
]
|
|
224
|
-
})
|
|
225
|
-
|
|
226
|
-
this.#server = await serverPromise
|
|
227
|
-
this.url = getServerUrl(this.#server)
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
async #startProduction (listen) {
|
|
231
|
-
const config = this.configManager.current
|
|
232
|
-
const command = this.configManager.current.application.commands.production
|
|
233
|
-
const outputDirectory = config.application.outputDirectory
|
|
234
|
-
|
|
235
|
-
this.#basePath = config.application?.basePath
|
|
236
|
-
? ensureTrailingSlash(cleanBasePath(config.application?.basePath))
|
|
237
|
-
: undefined
|
|
238
|
-
|
|
239
|
-
this.registerGlobals({ basePath: this.#basePath })
|
|
240
|
-
|
|
241
|
-
if (command) {
|
|
242
|
-
return this.startWithCommand(command)
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (this.#app && listen) {
|
|
246
|
-
const serverOptions = this.serverConfig
|
|
247
|
-
const listenOptions = { host: serverOptions?.hostname || '127.0.0.1', port: serverOptions?.port || 0 }
|
|
248
|
-
|
|
249
|
-
if (this.isProduction && features.node.reusePort) {
|
|
250
|
-
listenOptions.reusePort = true
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
await this.#app.listen(listenOptions)
|
|
254
|
-
this.url = getServerUrl(this.#app.server)
|
|
255
|
-
return this.url
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
this.#app = fastify({ loggerInstance: this.logger })
|
|
259
|
-
|
|
260
|
-
const root = resolve(this.root, outputDirectory)
|
|
261
|
-
this.verifyOutputDirectory(root)
|
|
262
|
-
|
|
263
|
-
const buildInfoPath = resolve(root, '.platformatic-build.json')
|
|
264
|
-
|
|
265
|
-
if (!this.#basePath && existsSync(buildInfoPath)) {
|
|
266
|
-
try {
|
|
267
|
-
const buildInfo = JSON.parse(await readFile(buildInfoPath, 'utf-8'))
|
|
268
|
-
this.#basePath = buildInfo.basePath
|
|
269
|
-
} catch (e) {
|
|
270
|
-
console.log(e)
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const ssrEntrypoint = resolve(this.root, outputDirectory, 'server/entry.mjs')
|
|
275
|
-
|
|
276
|
-
if (existsSync(ssrEntrypoint)) {
|
|
277
|
-
const { handler } = await importFile(ssrEntrypoint)
|
|
278
|
-
|
|
279
|
-
await this.#app.register(fastifyStatic, {
|
|
280
|
-
root: resolve(this.root, outputDirectory, 'client'),
|
|
281
|
-
prefix: this.#basePath,
|
|
282
|
-
prefixAvoidTrailingSlash: true,
|
|
283
|
-
schemaHide: true
|
|
284
|
-
})
|
|
285
|
-
|
|
286
|
-
await this.#app.register(middie)
|
|
287
|
-
await this.#app.use(this.#basePath, handler)
|
|
288
|
-
} else {
|
|
289
|
-
await this.#app.register(fastifyStatic, {
|
|
290
|
-
root,
|
|
291
|
-
prefix: this.#basePath,
|
|
292
|
-
prefixAvoidTrailingSlash: true,
|
|
293
|
-
schemaHide: true
|
|
294
|
-
})
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
await this.#app.ready()
|
|
298
|
-
}
|
|
1
|
+
import { transform as basicTransform, resolve, validationOptions } from '@platformatic/basic'
|
|
2
|
+
import { kMetadata, loadConfiguration as utilsLoadConfiguration } from '@platformatic/utils'
|
|
3
|
+
import { schema } from './lib/schema.js'
|
|
4
|
+
import { AstroStackable } from './lib/stackable.js'
|
|
5
|
+
|
|
6
|
+
/* c8 ignore next 5 */
|
|
7
|
+
export async function transform (config, schema, options) {
|
|
8
|
+
config = await basicTransform(config, schema, options)
|
|
9
|
+
config.watch = { enabled: false }
|
|
10
|
+
return config
|
|
299
11
|
}
|
|
300
12
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
if (this.current.watch === undefined) {
|
|
304
|
-
this.current.watch = { enabled: false }
|
|
305
|
-
}
|
|
13
|
+
export async function loadConfiguration (configOrRoot, sourceOrConfig, context) {
|
|
14
|
+
const { root, source } = await resolve(configOrRoot, sourceOrConfig, 'application')
|
|
306
15
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
export async function buildStackable (opts) {
|
|
315
|
-
const root = opts.context.directory
|
|
316
|
-
|
|
317
|
-
const configManager = new ConfigManager({
|
|
318
|
-
schema,
|
|
319
|
-
source: opts.config ?? {},
|
|
320
|
-
schemaOptions,
|
|
321
|
-
transformConfig,
|
|
322
|
-
dirname: root,
|
|
323
|
-
context: opts.context
|
|
16
|
+
return utilsLoadConfiguration(source, context?.schema ?? schema, {
|
|
17
|
+
validationOptions,
|
|
18
|
+
transform,
|
|
19
|
+
replaceEnv: true,
|
|
20
|
+
root,
|
|
21
|
+
...context
|
|
324
22
|
})
|
|
325
|
-
await configManager.parseAndValidate()
|
|
326
|
-
|
|
327
|
-
return new AstroStackable(opts, root, configManager)
|
|
328
23
|
}
|
|
329
24
|
|
|
330
|
-
export
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
configType: 'astro',
|
|
334
|
-
configManagerConfig: {
|
|
335
|
-
schemaOptions,
|
|
336
|
-
transformConfig
|
|
337
|
-
},
|
|
338
|
-
buildStackable,
|
|
339
|
-
schema,
|
|
340
|
-
version: packageJson.version,
|
|
341
|
-
modulesToLoad: []
|
|
25
|
+
export async function create (configOrRoot, sourceOrConfig, context) {
|
|
26
|
+
const config = await loadConfiguration(configOrRoot, sourceOrConfig, context)
|
|
27
|
+
return new AstroStackable(config[kMetadata].root, config, context)
|
|
342
28
|
}
|
|
29
|
+
|
|
30
|
+
export { packageJson, schema, schemaComponents, version } from './lib/schema.js'
|
|
31
|
+
export * from './lib/stackable.js'
|
package/lib/schema.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { schemaComponents as basicSchemaComponents } from '@platformatic/basic'
|
|
2
2
|
import { schemaComponents as utilsSchemaComponents } from '@platformatic/utils'
|
|
3
3
|
import { readFileSync } from 'node:fs'
|
|
4
|
+
import { resolve } from 'node:path'
|
|
4
5
|
|
|
5
|
-
export const packageJson = JSON.parse(readFileSync(
|
|
6
|
+
export const packageJson = JSON.parse(readFileSync(resolve(import.meta.dirname, '../package.json'), 'utf8'))
|
|
7
|
+
export const version = packageJson.version
|
|
6
8
|
|
|
7
9
|
export const astro = {
|
|
8
10
|
type: 'object',
|
|
@@ -20,7 +22,7 @@ export const schemaComponents = { astro }
|
|
|
20
22
|
export const schema = {
|
|
21
23
|
$id: `https://schemas.platformatic.dev/@platformatic/astro/${packageJson.version}.json`,
|
|
22
24
|
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
23
|
-
title: 'Platformatic Astro
|
|
25
|
+
title: 'Platformatic Astro Config',
|
|
24
26
|
type: 'object',
|
|
25
27
|
properties: {
|
|
26
28
|
$schema: {
|
package/lib/stackable.js
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import middie from '@fastify/middie'
|
|
2
|
+
import fastifyStatic from '@fastify/static'
|
|
3
|
+
import {
|
|
4
|
+
BaseStackable,
|
|
5
|
+
cleanBasePath,
|
|
6
|
+
createServerListener,
|
|
7
|
+
ensureTrailingSlash,
|
|
8
|
+
errors,
|
|
9
|
+
getServerUrl,
|
|
10
|
+
importFile,
|
|
11
|
+
resolvePackage
|
|
12
|
+
} from '@platformatic/basic'
|
|
13
|
+
import { features } from '@platformatic/utils'
|
|
14
|
+
import fastify from 'fastify'
|
|
15
|
+
import { existsSync } from 'node:fs'
|
|
16
|
+
import { readFile, writeFile } from 'node:fs/promises'
|
|
17
|
+
import { dirname, resolve } from 'node:path'
|
|
18
|
+
import { satisfies } from 'semver'
|
|
19
|
+
import { version } from './schema.js'
|
|
20
|
+
|
|
21
|
+
const supportedVersions = '^4.0.0 || ^5.0.0'
|
|
22
|
+
|
|
23
|
+
export class AstroStackable extends BaseStackable {
|
|
24
|
+
#astro
|
|
25
|
+
#app
|
|
26
|
+
#server
|
|
27
|
+
#basePath
|
|
28
|
+
|
|
29
|
+
constructor (root, config, context) {
|
|
30
|
+
super('astro', version, root, config, context)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async init () {
|
|
34
|
+
await super.init()
|
|
35
|
+
|
|
36
|
+
if (this.isProduction) {
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.#astro = resolve(dirname(resolvePackage(this.root, 'astro')), '../..')
|
|
41
|
+
const astroPackage = JSON.parse(await readFile(resolve(this.#astro, 'package.json'), 'utf-8'))
|
|
42
|
+
|
|
43
|
+
if (!satisfies(astroPackage.version, supportedVersions)) {
|
|
44
|
+
throw new errors.UnsupportedVersion('astro', astroPackage.version, supportedVersions)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async start ({ listen }) {
|
|
49
|
+
// Make this idempotent
|
|
50
|
+
if (this.url) {
|
|
51
|
+
return this.url
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (this.isProduction) {
|
|
55
|
+
await this.#startProduction(listen)
|
|
56
|
+
} else {
|
|
57
|
+
await this.#startDevelopment(listen)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
await this._collectMetrics()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async stop () {
|
|
64
|
+
if (this.childManager) {
|
|
65
|
+
return this.stopCommand()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return this.isProduction ? this.#app.close() : this.#app.stop()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async build () {
|
|
72
|
+
const config = this.config
|
|
73
|
+
const command = config.application.commands.build
|
|
74
|
+
const configFile = config.astro.configFile // Note: Astro expect this to be a relative path to the root
|
|
75
|
+
let basePath = config.application?.basePath
|
|
76
|
+
? ensureTrailingSlash(cleanBasePath(config.application?.basePath))
|
|
77
|
+
: undefined
|
|
78
|
+
|
|
79
|
+
if (command) {
|
|
80
|
+
return this.buildWithCommand(command, basePath)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
await this.init()
|
|
84
|
+
const { build } = await importFile(resolve(this.#astro, 'dist/core/index.js'))
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
globalThis.platformatic.isBuilding = true
|
|
88
|
+
|
|
89
|
+
await build({
|
|
90
|
+
root: this.root,
|
|
91
|
+
base: basePath,
|
|
92
|
+
outDir: config.application.outputDirectory,
|
|
93
|
+
mode: 'production',
|
|
94
|
+
configFile,
|
|
95
|
+
logLevel: this.logger.level,
|
|
96
|
+
integrations: [
|
|
97
|
+
{
|
|
98
|
+
name: 'platformatic',
|
|
99
|
+
hooks: {
|
|
100
|
+
'astro:config:done': ({ config }) => {
|
|
101
|
+
basePath = ensureTrailingSlash(cleanBasePath(config.base))
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
})
|
|
107
|
+
} finally {
|
|
108
|
+
globalThis.platformatic.isBuilding = false
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
await writeFile(
|
|
112
|
+
resolve(this.root, config.application.outputDirectory, '.platformatic-build.json'),
|
|
113
|
+
JSON.stringify({ basePath }),
|
|
114
|
+
'utf-8'
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* c8 ignore next 5 */
|
|
119
|
+
async getWatchConfig () {
|
|
120
|
+
return {
|
|
121
|
+
enabled: false
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getMeta () {
|
|
126
|
+
const config = this.subprocessConfig ?? this.#app?.config
|
|
127
|
+
|
|
128
|
+
const composer = {
|
|
129
|
+
tcp: typeof this.url !== 'undefined',
|
|
130
|
+
url: this.url,
|
|
131
|
+
prefix: this.basePath ?? config?.base ?? this.#basePath,
|
|
132
|
+
wantsAbsoluteUrls: true,
|
|
133
|
+
needsRootTrailingSlash: true,
|
|
134
|
+
needsRefererBasedRedirect: !this.isProduction
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return { composer }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// This is only used in non SSR production mode as in other modes a TCP server is started
|
|
141
|
+
async inject (injectParams, onInject) {
|
|
142
|
+
const res = await this.#app.inject(injectParams, onInject)
|
|
143
|
+
|
|
144
|
+
/* c8 ignore next 3 */
|
|
145
|
+
if (onInject) {
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Since inject might be called from the main thread directly via ITC, let's clean it up
|
|
150
|
+
const { statusCode, headers, body, payload, rawPayload } = res
|
|
151
|
+
return { statusCode, headers, body, payload, rawPayload }
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async #startDevelopment () {
|
|
155
|
+
// Make this idempotent
|
|
156
|
+
if (this.url) {
|
|
157
|
+
return this.url
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const config = this.config
|
|
161
|
+
const command = this.config.application.commands.development
|
|
162
|
+
|
|
163
|
+
this.#basePath = config.application?.basePath
|
|
164
|
+
? ensureTrailingSlash(cleanBasePath(config.application?.basePath))
|
|
165
|
+
: undefined
|
|
166
|
+
|
|
167
|
+
this.registerGlobals({ basePath: this.#basePath })
|
|
168
|
+
|
|
169
|
+
if (command) {
|
|
170
|
+
return this.startWithCommand(command)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Prepare options
|
|
174
|
+
const { hostname, port } = this.serverConfig ?? {}
|
|
175
|
+
const configFile = config.astro.configFile // Note: Astro expect this to be a relative path to the root
|
|
176
|
+
|
|
177
|
+
const serverOptions = {
|
|
178
|
+
host: hostname || '127.0.0.1',
|
|
179
|
+
port: port || 0
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Require Astro
|
|
183
|
+
const serverPromise = createServerListener(
|
|
184
|
+
(this.isEntrypoint ? serverOptions?.port : undefined) ?? true,
|
|
185
|
+
(this.isEntrypoint ? serverOptions?.hostname : undefined) ?? true
|
|
186
|
+
)
|
|
187
|
+
const { dev } = await importFile(resolve(this.#astro, 'dist/core/index.js'))
|
|
188
|
+
|
|
189
|
+
// Create the server and listen
|
|
190
|
+
this.#app = await dev({
|
|
191
|
+
root: this.root,
|
|
192
|
+
base: this.#basePath,
|
|
193
|
+
mode: 'development',
|
|
194
|
+
configFile,
|
|
195
|
+
logLevel: this.logger.level,
|
|
196
|
+
server: serverOptions,
|
|
197
|
+
vite: {
|
|
198
|
+
server: {
|
|
199
|
+
allowedHosts: ['.plt.local']
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
integrations: [
|
|
203
|
+
{
|
|
204
|
+
name: 'platformatic',
|
|
205
|
+
hooks: {
|
|
206
|
+
'astro:config:setup': ({ config }) => {
|
|
207
|
+
this.#basePath = ensureTrailingSlash(cleanBasePath(config.base))
|
|
208
|
+
|
|
209
|
+
/*
|
|
210
|
+
As Astro generates invalid paths in development mode which ignore the basePath
|
|
211
|
+
(see https://github.com/withastro/astro/issues/11445), make sure we provide
|
|
212
|
+
the prefix in HMR path.
|
|
213
|
+
*/
|
|
214
|
+
config.vite.server ??= {}
|
|
215
|
+
config.vite.server.hmr ??= {}
|
|
216
|
+
config.vite.server.hmr.path = `/${this.#basePath}/`.replaceAll(/\/+/g, '/')
|
|
217
|
+
config.vite.server.fs ??= {}
|
|
218
|
+
config.vite.server.fs.strict = false
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
this.#server = await serverPromise
|
|
226
|
+
this.url = getServerUrl(this.#server)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async #startProduction (listen) {
|
|
230
|
+
const config = this.config
|
|
231
|
+
const command = this.config.application.commands.production
|
|
232
|
+
const outputDirectory = config.application.outputDirectory
|
|
233
|
+
|
|
234
|
+
this.#basePath = config.application?.basePath
|
|
235
|
+
? ensureTrailingSlash(cleanBasePath(config.application?.basePath))
|
|
236
|
+
: undefined
|
|
237
|
+
|
|
238
|
+
this.registerGlobals({ basePath: this.#basePath })
|
|
239
|
+
|
|
240
|
+
if (command) {
|
|
241
|
+
return this.startWithCommand(command)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (this.#app && listen) {
|
|
245
|
+
const serverOptions = this.serverConfig
|
|
246
|
+
const listenOptions = { host: serverOptions?.hostname || '127.0.0.1', port: serverOptions?.port || 0 }
|
|
247
|
+
|
|
248
|
+
if (this.isProduction && features.node.reusePort) {
|
|
249
|
+
listenOptions.reusePort = true
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
await this.#app.listen(listenOptions)
|
|
253
|
+
this.url = getServerUrl(this.#app.server)
|
|
254
|
+
return this.url
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
this.#app = fastify({ loggerInstance: this.logger })
|
|
258
|
+
|
|
259
|
+
const root = resolve(this.root, outputDirectory)
|
|
260
|
+
this.verifyOutputDirectory(root)
|
|
261
|
+
|
|
262
|
+
const buildInfoPath = resolve(root, '.platformatic-build.json')
|
|
263
|
+
|
|
264
|
+
if (!this.#basePath && existsSync(buildInfoPath)) {
|
|
265
|
+
try {
|
|
266
|
+
const buildInfo = JSON.parse(await readFile(buildInfoPath, 'utf-8'))
|
|
267
|
+
this.#basePath = buildInfo.basePath
|
|
268
|
+
} catch (e) {
|
|
269
|
+
console.log(e)
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const ssrEntrypoint = resolve(this.root, outputDirectory, 'server/entry.mjs')
|
|
274
|
+
|
|
275
|
+
if (existsSync(ssrEntrypoint)) {
|
|
276
|
+
const { handler } = await importFile(ssrEntrypoint)
|
|
277
|
+
|
|
278
|
+
await this.#app.register(fastifyStatic, {
|
|
279
|
+
root: resolve(this.root, outputDirectory, 'client'),
|
|
280
|
+
prefix: this.#basePath,
|
|
281
|
+
prefixAvoidTrailingSlash: true,
|
|
282
|
+
schemaHide: true
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
await this.#app.register(middie)
|
|
286
|
+
await this.#app.use(this.#basePath, handler)
|
|
287
|
+
} else {
|
|
288
|
+
await this.#app.register(fastifyStatic, {
|
|
289
|
+
root,
|
|
290
|
+
prefix: this.#basePath,
|
|
291
|
+
prefixAvoidTrailingSlash: true,
|
|
292
|
+
schemaHide: true
|
|
293
|
+
})
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
await this.#app.ready()
|
|
297
|
+
}
|
|
298
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/astro",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-alpha.1",
|
|
4
4
|
"description": "Platformatic Astro Stackable",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -19,9 +19,8 @@
|
|
|
19
19
|
"@fastify/static": "^8.0.0",
|
|
20
20
|
"fastify": "^5.0.0",
|
|
21
21
|
"semver": "^7.6.3",
|
|
22
|
-
"@platformatic/basic": "
|
|
23
|
-
"@platformatic/
|
|
24
|
-
"@platformatic/utils": "2.72.0"
|
|
22
|
+
"@platformatic/basic": "3.0.0-alpha.1",
|
|
23
|
+
"@platformatic/utils": "3.0.0-alpha.1"
|
|
25
24
|
},
|
|
26
25
|
"devDependencies": {
|
|
27
26
|
"@astrojs/node": "^9.2.0",
|
|
@@ -29,17 +28,16 @@
|
|
|
29
28
|
"borp": "^0.20.0",
|
|
30
29
|
"eslint": "9",
|
|
31
30
|
"json-schema-to-typescript": "^15.0.1",
|
|
32
|
-
"minimatch": "^10.0.3",
|
|
33
31
|
"neostandard": "^0.12.0",
|
|
34
32
|
"typescript": "^5.5.4",
|
|
35
33
|
"vite": "^5.4.4",
|
|
36
34
|
"ws": "^8.18.0",
|
|
37
|
-
"@platformatic/composer": "
|
|
38
|
-
"@platformatic/service": "
|
|
35
|
+
"@platformatic/composer": "3.0.0-alpha.1",
|
|
36
|
+
"@platformatic/service": "3.0.0-alpha.1"
|
|
39
37
|
},
|
|
40
38
|
"scripts": {
|
|
41
|
-
"test": "npm run lint && borp --concurrency=1 --
|
|
42
|
-
"coverage": "npm run lint && borp -C -X test -X test/fixtures --concurrency=1 --
|
|
39
|
+
"test": "npm run lint && borp --concurrency=1 --timeout 1200000",
|
|
40
|
+
"coverage": "npm run lint && borp -C -X test -X test/fixtures --concurrency=1 --timeout 1200000",
|
|
43
41
|
"gen-schema": "node lib/schema.js > schema.json",
|
|
44
42
|
"gen-types": "json2ts > config.d.ts < schema.json",
|
|
45
43
|
"build": "pnpm run gen-schema && pnpm run gen-types",
|
package/schema.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://schemas.platformatic.dev/@platformatic/astro/
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/@platformatic/astro/3.0.0-alpha.1.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
|
-
"title": "Platformatic Astro
|
|
4
|
+
"title": "Platformatic Astro Config",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
7
7
|
"$schema": {
|