@platformatic/remix 2.74.3 → 3.0.0-alpha.4
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 -265
- package/lib/schema.js +6 -4
- package/lib/stackable.js +224 -0
- package/package.json +11 -9
- package/schema.json +3 -2
package/config.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -1,272 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import { ConfigManager } from '@platformatic/config'
|
|
12
|
-
import { features } from '@platformatic/utils'
|
|
13
|
-
import { ViteStackable } from '@platformatic/vite'
|
|
14
|
-
import { createRequestHandler } from '@remix-run/express'
|
|
15
|
-
import express from 'express'
|
|
16
|
-
import inject from 'light-my-request'
|
|
17
|
-
import { existsSync } from 'node:fs'
|
|
18
|
-
import { readFile } from 'node:fs/promises'
|
|
19
|
-
import { dirname, resolve } from 'node:path'
|
|
20
|
-
import { pinoHttp } from 'pino-http'
|
|
21
|
-
import { satisfies } from 'semver'
|
|
22
|
-
import { packageJson, schema } from './lib/schema.js'
|
|
23
|
-
|
|
24
|
-
const supportedVersions = '^2.0.0'
|
|
25
|
-
|
|
26
|
-
export class RemixStackable extends ViteStackable {
|
|
27
|
-
#app
|
|
28
|
-
#server
|
|
29
|
-
#dispatcher
|
|
30
|
-
#remix
|
|
31
|
-
#basePath
|
|
32
|
-
|
|
33
|
-
constructor (options, root, configManager) {
|
|
34
|
-
super(options, root, configManager)
|
|
35
|
-
|
|
36
|
-
this.type = 'remix'
|
|
37
|
-
this.version = packageJson.version
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async init () {
|
|
41
|
-
await super.init()
|
|
42
|
-
|
|
43
|
-
if (!this.isProduction) {
|
|
44
|
-
this.#remix = resolve(dirname(resolvePackage(this.root, '@remix-run/dev')), '..')
|
|
45
|
-
const remixPackage = JSON.parse(await readFile(resolve(this.#remix, 'package.json'), 'utf-8'))
|
|
46
|
-
|
|
47
|
-
if (!satisfies(remixPackage.version, supportedVersions)) {
|
|
48
|
-
throw new errors.UnsupportedVersion('@remix-run/dev', remixPackage.version, supportedVersions)
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const config = this.configManager.current
|
|
53
|
-
this.#basePath = config.application?.basePath
|
|
54
|
-
? ensureTrailingSlash(cleanBasePath(config.application?.basePath))
|
|
55
|
-
: undefined
|
|
56
|
-
|
|
57
|
-
this.registerGlobals({ basePath: this.#basePath })
|
|
58
|
-
|
|
59
|
-
this.subprocessTerminationSignal = 'SIGKILL'
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async start ({ listen }) {
|
|
63
|
-
// Make this idempotent
|
|
64
|
-
if (this.url) {
|
|
65
|
-
return this.url
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const config = this.configManager.current
|
|
69
|
-
const command = config.application.commands[this.isProduction ? 'production' : 'development']
|
|
70
|
-
|
|
71
|
-
if (command) {
|
|
72
|
-
return this.startWithCommand(command)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return this.isProduction ? this.#startProduction(listen) : this.#startDevelopment(listen)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async stop () {
|
|
79
|
-
if (this.childManager) {
|
|
80
|
-
return this.stopCommand()
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (this.isProduction) {
|
|
84
|
-
return this.#stopProduction()
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return super.stop()
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
async build () {
|
|
91
|
-
const config = this.configManager.current
|
|
92
|
-
const command = config.application.commands.build
|
|
93
|
-
const basePath = config.application?.basePath
|
|
94
|
-
? ensureTrailingSlash(cleanBasePath(config.application?.basePath))
|
|
95
|
-
: undefined
|
|
96
|
-
|
|
97
|
-
if (command) {
|
|
98
|
-
return this.buildWithCommand(command, basePath)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
await this.init()
|
|
102
|
-
const { viteBuild } = await importFile(resolve(this.#remix, 'dist/cli/commands.js'))
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
globalThis.platformatic.isBuilding = true
|
|
106
|
-
|
|
107
|
-
await viteBuild(this.root, {
|
|
108
|
-
emptyOutDir: true,
|
|
109
|
-
logLevel: this.logger.level,
|
|
110
|
-
mode: 'production',
|
|
111
|
-
profile: false
|
|
112
|
-
})
|
|
113
|
-
} finally {
|
|
114
|
-
globalThis.platformatic.isBuilding = false
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
async inject (injectParams, onInject) {
|
|
119
|
-
if (!this.isProduction) {
|
|
120
|
-
return super.inject(injectParams, onInject)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const res = await inject(this.#app, injectParams, onInject)
|
|
124
|
-
|
|
125
|
-
/* c8 ignore next 3 */
|
|
126
|
-
if (onInject) {
|
|
127
|
-
return
|
|
128
|
-
} // Since inject might be called from the main thread directly via ITC, let's clean it up
|
|
129
|
-
|
|
130
|
-
const { statusCode, headers, body, payload, rawPayload } = res
|
|
131
|
-
return { statusCode, headers, body, payload, rawPayload }
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
getMeta () {
|
|
135
|
-
if (!this.isProduction) {
|
|
136
|
-
return super.getMeta()
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return {
|
|
140
|
-
composer: {
|
|
141
|
-
tcp: typeof this.url !== 'undefined',
|
|
142
|
-
url: this.url,
|
|
143
|
-
prefix: this.basePath ?? this.#basePath,
|
|
144
|
-
wantsAbsoluteUrls: true,
|
|
145
|
-
needsRootTrailingSlash: true
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
async #startDevelopment (listen) {
|
|
151
|
-
const preloadViteEsmPath = resolve(this.#remix, './dist/vite/import-vite-esm-sync.js')
|
|
152
|
-
|
|
153
|
-
// Older versions
|
|
154
|
-
if (existsSync(preloadViteEsmPath)) {
|
|
155
|
-
const { preloadViteEsm } = await importFile(resolve(this.#remix, './dist/vite/import-vite-esm-sync.js'))
|
|
156
|
-
await preloadViteEsm()
|
|
157
|
-
} else {
|
|
158
|
-
const { preloadVite } = await importFile(resolve(this.#remix, './dist/vite/vite.js'))
|
|
159
|
-
await preloadVite()
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
await super.start({ listen })
|
|
163
|
-
|
|
164
|
-
/* c8 ignore next 3 */
|
|
165
|
-
if (!this._getVite().config.plugins.some(p => p.name === 'remix')) {
|
|
166
|
-
this.logger.warn('Could not find Remix plugin in your Vite configuration. Continuing as plain Vite application.')
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
await this._collectMetrics()
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
async #startProduction (listen) {
|
|
173
|
-
// Listen if entrypoint
|
|
174
|
-
if (this.#app && listen) {
|
|
175
|
-
const serverOptions = this.serverConfig
|
|
176
|
-
const listenOptions = { host: serverOptions?.hostname || '127.0.0.1', port: serverOptions?.port || 0 }
|
|
177
|
-
|
|
178
|
-
if (this.isProduction && features.node.reusePort) {
|
|
179
|
-
listenOptions.reusePort = true
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
this.#server = await new Promise((resolve, reject) => {
|
|
183
|
-
return this.#app
|
|
184
|
-
.listen(listenOptions, function () {
|
|
185
|
-
resolve(this)
|
|
186
|
-
})
|
|
187
|
-
.on('error', reject)
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
this.url = getServerUrl(this.#server)
|
|
191
|
-
|
|
192
|
-
return this.url
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const outputDirectory = this.configManager.current.remix.outputDirectory
|
|
196
|
-
this.verifyOutputDirectory(resolve(this.root, outputDirectory))
|
|
197
|
-
|
|
198
|
-
const build = await importFile(resolve(this.root, `${outputDirectory}/server/index.js`))
|
|
199
|
-
this.#basePath = ensureTrailingSlash(cleanBasePath(build.basename))
|
|
200
|
-
|
|
201
|
-
// Setup express app
|
|
202
|
-
this.#app = express()
|
|
203
|
-
this.#app.disable('x-powered-by')
|
|
204
|
-
this.#app.use(pinoHttp({ logger: this.logger }))
|
|
205
|
-
this.#app.use(this.#basePath, express.static(resolve(this.root, `${outputDirectory}/client`)))
|
|
206
|
-
this.#app.all(`${ensureTrailingSlash(cleanBasePath(this.#basePath))}*`, createRequestHandler({ build }))
|
|
207
|
-
|
|
208
|
-
await this._collectMetrics()
|
|
209
|
-
return this.url
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
async #stopProduction () {
|
|
213
|
-
/* c8 ignore next 3 */
|
|
214
|
-
if (!this.#server?.listening) {
|
|
215
|
-
return
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return new Promise((resolve, reject) => {
|
|
219
|
-
this.#server.close(error => {
|
|
220
|
-
/* c8 ignore next 3 */
|
|
221
|
-
if (error) {
|
|
222
|
-
return reject(error)
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
resolve()
|
|
226
|
-
})
|
|
227
|
-
})
|
|
228
|
-
}
|
|
1
|
+
import { transform as basicTransform, resolve, validationOptions } from '@platformatic/basic'
|
|
2
|
+
import { kMetadata, loadConfiguration as utilsLoadConfiguration } from '@platformatic/foundation'
|
|
3
|
+
import { schema } from './lib/schema.js'
|
|
4
|
+
import { RemixStackable } 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
|
|
229
11
|
}
|
|
230
12
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (this.current.watch === undefined) {
|
|
234
|
-
this.current.watch = { enabled: false }
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (typeof this.current.watch !== 'object') {
|
|
238
|
-
this.current.watch = { enabled: this.current.watch || false }
|
|
239
|
-
}
|
|
13
|
+
export async function loadConfiguration (configOrRoot, sourceOrConfig, context) {
|
|
14
|
+
const { root, source } = await resolve(configOrRoot, sourceOrConfig, 'application')
|
|
240
15
|
|
|
241
|
-
return
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const configManager = new ConfigManager({
|
|
248
|
-
schema,
|
|
249
|
-
source: opts.config ?? {},
|
|
250
|
-
schemaOptions,
|
|
251
|
-
transformConfig,
|
|
252
|
-
dirname: root,
|
|
253
|
-
context: opts.context
|
|
16
|
+
return utilsLoadConfiguration(source, context?.schema ?? schema, {
|
|
17
|
+
validationOptions,
|
|
18
|
+
transform,
|
|
19
|
+
replaceEnv: true,
|
|
20
|
+
root,
|
|
21
|
+
...context
|
|
254
22
|
})
|
|
255
|
-
await configManager.parseAndValidate()
|
|
256
|
-
|
|
257
|
-
return new RemixStackable(opts, root, configManager)
|
|
258
23
|
}
|
|
259
24
|
|
|
260
|
-
export
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
configType: 'remix',
|
|
264
|
-
configManagerConfig: {
|
|
265
|
-
schemaOptions,
|
|
266
|
-
transformConfig
|
|
267
|
-
},
|
|
268
|
-
buildStackable,
|
|
269
|
-
schema,
|
|
270
|
-
version: packageJson.version,
|
|
271
|
-
modulesToLoad: []
|
|
25
|
+
export async function create (configOrRoot, sourceOrConfig, context) {
|
|
26
|
+
const config = await loadConfiguration(configOrRoot, sourceOrConfig, context)
|
|
27
|
+
return new RemixStackable(config[kMetadata].root, config, context)
|
|
272
28
|
}
|
|
29
|
+
|
|
30
|
+
export { packageJson, schema, schemaComponents, version } from './lib/schema.js'
|
|
31
|
+
export * from './lib/stackable.js'
|
package/lib/schema.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { schemaComponents as basicSchemaComponents } from '@platformatic/basic'
|
|
2
|
-
import { schemaComponents as utilsSchemaComponents } from '@platformatic/
|
|
2
|
+
import { schemaComponents as utilsSchemaComponents } from '@platformatic/foundation'
|
|
3
3
|
import { schemaComponents as viteSchemaComponents } from '@platformatic/vite'
|
|
4
4
|
import { readFileSync } from 'node:fs'
|
|
5
|
+
import { resolve } from 'node:path'
|
|
5
6
|
|
|
6
|
-
export const packageJson = JSON.parse(readFileSync(
|
|
7
|
+
export const packageJson = JSON.parse(readFileSync(resolve(import.meta.dirname, '../package.json'), 'utf8'))
|
|
8
|
+
export const version = packageJson.version
|
|
7
9
|
|
|
8
10
|
export const remix = {
|
|
9
11
|
type: 'object',
|
|
@@ -22,7 +24,7 @@ export const schemaComponents = { remix }
|
|
|
22
24
|
export const schema = {
|
|
23
25
|
$id: `https://schemas.platformatic.dev/@platformatic/remix/${packageJson.version}.json`,
|
|
24
26
|
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
25
|
-
title: 'Platformatic Remix
|
|
27
|
+
title: 'Platformatic Remix Config',
|
|
26
28
|
type: 'object',
|
|
27
29
|
properties: {
|
|
28
30
|
$schema: {
|
|
@@ -31,7 +33,7 @@ export const schema = {
|
|
|
31
33
|
logger: utilsSchemaComponents.logger,
|
|
32
34
|
server: utilsSchemaComponents.server,
|
|
33
35
|
watch: basicSchemaComponents.watch,
|
|
34
|
-
application: basicSchemaComponents.
|
|
36
|
+
application: basicSchemaComponents.buildableApplication,
|
|
35
37
|
runtime: utilsSchemaComponents.wrappedRuntime,
|
|
36
38
|
vite: viteSchemaComponents.vite,
|
|
37
39
|
remix
|
package/lib/stackable.js
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cleanBasePath,
|
|
3
|
+
ensureTrailingSlash,
|
|
4
|
+
errors,
|
|
5
|
+
getServerUrl,
|
|
6
|
+
importFile,
|
|
7
|
+
resolvePackage
|
|
8
|
+
} from '@platformatic/basic'
|
|
9
|
+
import { features } from '@platformatic/foundation'
|
|
10
|
+
import { ViteStackable } from '@platformatic/vite'
|
|
11
|
+
import { createRequestHandler } from '@remix-run/express'
|
|
12
|
+
import express from 'express'
|
|
13
|
+
import inject from 'light-my-request'
|
|
14
|
+
import { existsSync } from 'node:fs'
|
|
15
|
+
import { readFile } from 'node:fs/promises'
|
|
16
|
+
import { dirname, resolve } from 'node:path'
|
|
17
|
+
import { pinoHttp } from 'pino-http'
|
|
18
|
+
import { satisfies } from 'semver'
|
|
19
|
+
import { packageJson } from './schema.js'
|
|
20
|
+
|
|
21
|
+
const supportedVersions = '^2.0.0'
|
|
22
|
+
|
|
23
|
+
export class RemixStackable extends ViteStackable {
|
|
24
|
+
#app
|
|
25
|
+
#server
|
|
26
|
+
#remix
|
|
27
|
+
#basePath
|
|
28
|
+
|
|
29
|
+
constructor (root, config, context) {
|
|
30
|
+
super(root, config, context)
|
|
31
|
+
this.type = 'remix'
|
|
32
|
+
this.version = packageJson.version
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async init () {
|
|
36
|
+
await super.init()
|
|
37
|
+
|
|
38
|
+
if (!this.isProduction) {
|
|
39
|
+
this.#remix = resolve(dirname(resolvePackage(this.root, '@remix-run/dev')), '..')
|
|
40
|
+
const remixPackage = JSON.parse(await readFile(resolve(this.#remix, 'package.json'), 'utf-8'))
|
|
41
|
+
|
|
42
|
+
if (!satisfies(remixPackage.version, supportedVersions)) {
|
|
43
|
+
throw new errors.UnsupportedVersion('@remix-run/dev', remixPackage.version, supportedVersions)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const config = this.config
|
|
48
|
+
this.#basePath = config.application?.basePath
|
|
49
|
+
? ensureTrailingSlash(cleanBasePath(config.application?.basePath))
|
|
50
|
+
: undefined
|
|
51
|
+
|
|
52
|
+
this.registerGlobals({ basePath: this.#basePath })
|
|
53
|
+
|
|
54
|
+
this.subprocessTerminationSignal = 'SIGKILL'
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async start ({ listen }) {
|
|
58
|
+
// Make this idempotent
|
|
59
|
+
if (this.url) {
|
|
60
|
+
return this.url
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const config = this.config
|
|
64
|
+
const command = config.application.commands[this.isProduction ? 'production' : 'development']
|
|
65
|
+
|
|
66
|
+
if (command) {
|
|
67
|
+
return this.startWithCommand(command)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return this.isProduction ? this.#startProduction(listen) : this.#startDevelopment(listen)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async stop () {
|
|
74
|
+
if (this.childManager) {
|
|
75
|
+
return this.stopCommand()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (this.isProduction) {
|
|
79
|
+
return this.#stopProduction()
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return super.stop()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async build () {
|
|
86
|
+
const config = this.config
|
|
87
|
+
const command = config.application.commands.build
|
|
88
|
+
const basePath = config.application?.basePath
|
|
89
|
+
? ensureTrailingSlash(cleanBasePath(config.application?.basePath))
|
|
90
|
+
: undefined
|
|
91
|
+
|
|
92
|
+
if (command) {
|
|
93
|
+
return this.buildWithCommand(command, basePath)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
await this.init()
|
|
97
|
+
const { viteBuild } = await importFile(resolve(this.#remix, 'dist/cli/commands.js'))
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
globalThis.platformatic.isBuilding = true
|
|
101
|
+
|
|
102
|
+
await viteBuild(this.root, {
|
|
103
|
+
emptyOutDir: true,
|
|
104
|
+
logLevel: this.logger.level,
|
|
105
|
+
mode: 'production',
|
|
106
|
+
profile: false
|
|
107
|
+
})
|
|
108
|
+
} finally {
|
|
109
|
+
globalThis.platformatic.isBuilding = false
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async inject (injectParams, onInject) {
|
|
114
|
+
if (!this.isProduction) {
|
|
115
|
+
return super.inject(injectParams, onInject)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const res = await inject(this.#app, injectParams, onInject)
|
|
119
|
+
|
|
120
|
+
/* c8 ignore next 3 */
|
|
121
|
+
if (onInject) {
|
|
122
|
+
return
|
|
123
|
+
} // Since inject might be called from the main thread directly via ITC, let's clean it up
|
|
124
|
+
|
|
125
|
+
const { statusCode, headers, body, payload, rawPayload } = res
|
|
126
|
+
return { statusCode, headers, body, payload, rawPayload }
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
getMeta () {
|
|
130
|
+
if (!this.isProduction) {
|
|
131
|
+
return super.getMeta()
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
composer: {
|
|
136
|
+
tcp: typeof this.url !== 'undefined',
|
|
137
|
+
url: this.url,
|
|
138
|
+
prefix: this.basePath ?? this.#basePath,
|
|
139
|
+
wantsAbsoluteUrls: true,
|
|
140
|
+
needsRootTrailingSlash: true
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async #startDevelopment (listen) {
|
|
146
|
+
const preloadViteEsmPath = resolve(this.#remix, './dist/vite/import-vite-esm-sync.js')
|
|
147
|
+
|
|
148
|
+
// Older versions
|
|
149
|
+
if (existsSync(preloadViteEsmPath)) {
|
|
150
|
+
const { preloadViteEsm } = await importFile(resolve(this.#remix, './dist/vite/import-vite-esm-sync.js'))
|
|
151
|
+
await preloadViteEsm()
|
|
152
|
+
} else {
|
|
153
|
+
const { preloadVite } = await importFile(resolve(this.#remix, './dist/vite/vite.js'))
|
|
154
|
+
await preloadVite()
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
await super.start({ listen })
|
|
158
|
+
|
|
159
|
+
/* c8 ignore next 3 */
|
|
160
|
+
if (!this._getVite().config.plugins.some(p => p.name === 'remix')) {
|
|
161
|
+
this.logger.warn('Could not find Remix plugin in your Vite configuration. Continuing as plain Vite application.')
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
await this._collectMetrics()
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async #startProduction (listen) {
|
|
168
|
+
// Listen if entrypoint
|
|
169
|
+
if (this.#app && listen) {
|
|
170
|
+
const serverOptions = this.serverConfig
|
|
171
|
+
const listenOptions = { host: serverOptions?.hostname || '127.0.0.1', port: serverOptions?.port || 0 }
|
|
172
|
+
|
|
173
|
+
if (this.isProduction && features.node.reusePort) {
|
|
174
|
+
listenOptions.reusePort = true
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
this.#server = await new Promise((resolve, reject) => {
|
|
178
|
+
return this.#app
|
|
179
|
+
.listen(listenOptions, function () {
|
|
180
|
+
resolve(this)
|
|
181
|
+
})
|
|
182
|
+
.on('error', reject)
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
this.url = getServerUrl(this.#server)
|
|
186
|
+
|
|
187
|
+
return this.url
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const outputDirectory = this.config.remix.outputDirectory
|
|
191
|
+
this.verifyOutputDirectory(resolve(this.root, outputDirectory))
|
|
192
|
+
|
|
193
|
+
const build = await importFile(resolve(this.root, `${outputDirectory}/server/index.js`))
|
|
194
|
+
this.#basePath = ensureTrailingSlash(cleanBasePath(build.basename))
|
|
195
|
+
|
|
196
|
+
// Setup express app
|
|
197
|
+
this.#app = express()
|
|
198
|
+
this.#app.disable('x-powered-by')
|
|
199
|
+
this.#app.use(pinoHttp({ logger: this.logger }))
|
|
200
|
+
this.#app.use(this.#basePath, express.static(resolve(this.root, `${outputDirectory}/client`)))
|
|
201
|
+
this.#app.all(`${ensureTrailingSlash(cleanBasePath(this.#basePath))}*`, createRequestHandler({ build }))
|
|
202
|
+
|
|
203
|
+
await this._collectMetrics()
|
|
204
|
+
return this.url
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async #stopProduction () {
|
|
208
|
+
/* c8 ignore next 3 */
|
|
209
|
+
if (!this.#server?.listening) {
|
|
210
|
+
return
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return new Promise((resolve, reject) => {
|
|
214
|
+
this.#server.close(error => {
|
|
215
|
+
/* c8 ignore next 3 */
|
|
216
|
+
if (error) {
|
|
217
|
+
return reject(error)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
resolve()
|
|
221
|
+
})
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/remix",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-alpha.4",
|
|
4
4
|
"description": "Platformatic Remix Stackable",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -20,10 +20,9 @@
|
|
|
20
20
|
"light-my-request": "^6.0.0",
|
|
21
21
|
"pino-http": "^10.2.0",
|
|
22
22
|
"semver": "^7.6.3",
|
|
23
|
-
"@platformatic/
|
|
24
|
-
"@platformatic/
|
|
25
|
-
"@platformatic/vite": "
|
|
26
|
-
"@platformatic/utils": "2.74.3"
|
|
23
|
+
"@platformatic/basic": "3.0.0-alpha.4",
|
|
24
|
+
"@platformatic/foundation": "3.0.0-alpha.4",
|
|
25
|
+
"@platformatic/vite": "3.0.0-alpha.4"
|
|
27
26
|
},
|
|
28
27
|
"devDependencies": {
|
|
29
28
|
"@remix-run/dev": "^2.16.8",
|
|
@@ -40,12 +39,15 @@
|
|
|
40
39
|
"typescript": "^5.5.4",
|
|
41
40
|
"vite": "^5.4.2",
|
|
42
41
|
"ws": "^8.18.0",
|
|
43
|
-
"@platformatic/composer": "
|
|
44
|
-
"@platformatic/service": "
|
|
42
|
+
"@platformatic/composer": "3.0.0-alpha.4",
|
|
43
|
+
"@platformatic/service": "3.0.0-alpha.4"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=22.18.0"
|
|
45
47
|
},
|
|
46
48
|
"scripts": {
|
|
47
|
-
"test": "npm run lint && borp --concurrency=1 --
|
|
48
|
-
"coverage": "npm run lint && borp -C -X test -X test/fixtures --concurrency=1 --
|
|
49
|
+
"test": "npm run lint && borp --concurrency=1 --timeout 1200000",
|
|
50
|
+
"coverage": "npm run lint && borp -C -X test -X test/fixtures --concurrency=1 --timeout 1200000",
|
|
49
51
|
"gen-schema": "node lib/schema.js > schema.json",
|
|
50
52
|
"gen-types": "json2ts > config.d.ts < schema.json",
|
|
51
53
|
"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/remix/
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/@platformatic/remix/3.0.0-alpha.4.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
|
-
"title": "Platformatic Remix
|
|
4
|
+
"title": "Platformatic Remix Config",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
7
7
|
"$schema": {
|
|
@@ -362,6 +362,7 @@
|
|
|
362
362
|
}
|
|
363
363
|
},
|
|
364
364
|
"additionalProperties": false,
|
|
365
|
+
"required": [],
|
|
365
366
|
"default": {}
|
|
366
367
|
},
|
|
367
368
|
"runtime": {
|