@maestro-js/init 1.0.0-alpha.24 → 1.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/dist/bin.d.ts +1 -2
- package/dist/bin.js +6 -6
- package/dist/{chunk-FO3IYFDW.js → chunk-P4YULL3I.js} +56 -128
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -3
- package/package.json +2 -2
package/dist/bin.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { }
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/bin.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
#!/usr/bin/env node
|
|
2
3
|
import {
|
|
3
4
|
buildProjectTree,
|
|
4
|
-
getInitVersion,
|
|
5
5
|
scaffold
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-P4YULL3I.js";
|
|
7
7
|
|
|
8
8
|
// src/bin.ts
|
|
9
9
|
import crypto from "crypto";
|
|
@@ -50,10 +50,10 @@ function deriveDbPort(name2) {
|
|
|
50
50
|
}
|
|
51
51
|
function installSkills(targetDir2) {
|
|
52
52
|
const skillSources = [
|
|
53
|
-
{ cmd:
|
|
54
|
-
{ cmd: "npx skills add https://react-aria.adobe.com --
|
|
55
|
-
{ cmd: "npx skills add anthropics/skills --skill skill-creator -
|
|
56
|
-
{ cmd: "npx skills add mattpocock/skills --skill grill-me -
|
|
53
|
+
{ cmd: "npx --yes @maestro-js/agent-skills", label: "maestro" },
|
|
54
|
+
{ cmd: "npx skills add https://react-aria.adobe.com --all", label: "react-aria" },
|
|
55
|
+
{ cmd: "npx skills add anthropics/skills --skill skill-creator -y", label: "skill-creator" },
|
|
56
|
+
{ cmd: "npx skills add mattpocock/skills --skill grill-me -y", label: "grill-me" },
|
|
57
57
|
{ cmd: "playwright-cli install --skills", label: "playwright-cli" }
|
|
58
58
|
];
|
|
59
59
|
for (const { cmd, label } of skillSources) {
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// src/index.ts
|
|
4
|
-
import fs from "fs";
|
|
5
|
-
import path from "path";
|
|
6
|
-
import { fileURLToPath } from "url";
|
|
7
|
-
|
|
8
3
|
// src/templates/root.ts
|
|
9
|
-
function rootPackageJson(name
|
|
4
|
+
function rootPackageJson(name) {
|
|
10
5
|
return JSON.stringify(
|
|
11
6
|
{
|
|
12
7
|
type: "module",
|
|
@@ -16,13 +11,13 @@ function rootPackageJson(name, maestroVersion) {
|
|
|
16
11
|
"fks-restrict": "maestro config:run --config services -- node ./scripts/foreign-key-delete-behavior.ts restrict"
|
|
17
12
|
},
|
|
18
13
|
dependencies: {
|
|
19
|
-
"@maestro-js/config":
|
|
14
|
+
"@maestro-js/config": "latest",
|
|
20
15
|
[`@${name}/services`]: "workspace:*"
|
|
21
16
|
},
|
|
22
17
|
devDependencies: {
|
|
23
|
-
"@maestro-js/cli":
|
|
24
|
-
"@maestro-js/db-migrate":
|
|
25
|
-
"@maestro-js/db":
|
|
18
|
+
"@maestro-js/cli": "latest",
|
|
19
|
+
"@maestro-js/db-migrate": "latest",
|
|
20
|
+
"@maestro-js/db": "latest",
|
|
26
21
|
"@types/node": "^22.19.11",
|
|
27
22
|
tsx: "^4.21.0"
|
|
28
23
|
}
|
|
@@ -139,7 +134,7 @@ var dbMigrateConfig = `export default async function (env: Record<string, string
|
|
|
139
134
|
`;
|
|
140
135
|
|
|
141
136
|
// src/templates/schemas.ts
|
|
142
|
-
function schemasPackageJson(name
|
|
137
|
+
function schemasPackageJson(name) {
|
|
143
138
|
return JSON.stringify(
|
|
144
139
|
{
|
|
145
140
|
name: `@${name}/schemas`,
|
|
@@ -150,7 +145,7 @@ function schemasPackageJson(name, maestroVersion) {
|
|
|
150
145
|
dependencies: {
|
|
151
146
|
"iso-fns": "npm:iso-fns@2.0.0-alpha.26",
|
|
152
147
|
zod: "^4.3.0",
|
|
153
|
-
"@maestro-js/iso-zod":
|
|
148
|
+
"@maestro-js/iso-zod": "latest"
|
|
154
149
|
},
|
|
155
150
|
devDependencies: {}
|
|
156
151
|
},
|
|
@@ -163,7 +158,7 @@ var schemasIndex = `// Export your Zod schemas here
|
|
|
163
158
|
`;
|
|
164
159
|
|
|
165
160
|
// src/templates/services.ts
|
|
166
|
-
function servicesPackageJson(name
|
|
161
|
+
function servicesPackageJson(name) {
|
|
167
162
|
return JSON.stringify(
|
|
168
163
|
{
|
|
169
164
|
name: `@${name}/services`,
|
|
@@ -177,29 +172,29 @@ function servicesPackageJson(name, maestroVersion) {
|
|
|
177
172
|
dependencies: {
|
|
178
173
|
[`@${name}/schemas`]: "workspace:*",
|
|
179
174
|
"@aws-sdk/client-ses": "^3.1004.0",
|
|
180
|
-
"@maestro-js/auth":
|
|
181
|
-
"@maestro-js/cache":
|
|
182
|
-
"@maestro-js/config":
|
|
183
|
-
"@maestro-js/crypt":
|
|
184
|
-
"@maestro-js/custom-errors":
|
|
185
|
-
"@maestro-js/db":
|
|
186
|
-
"@maestro-js/exceptions":
|
|
187
|
-
"@maestro-js/hash":
|
|
188
|
-
"@maestro-js/helpers":
|
|
189
|
-
"@maestro-js/iso-zod":
|
|
190
|
-
"@maestro-js/log":
|
|
191
|
-
"@maestro-js/mail":
|
|
192
|
-
"@maestro-js/password":
|
|
193
|
-
"@maestro-js/permissions":
|
|
194
|
-
"@maestro-js/queue":
|
|
195
|
-
"@maestro-js/rate-limiting":
|
|
196
|
-
"@maestro-js/recurring-jobs":
|
|
197
|
-
"@maestro-js/session":
|
|
175
|
+
"@maestro-js/auth": "latest",
|
|
176
|
+
"@maestro-js/cache": "latest",
|
|
177
|
+
"@maestro-js/config": "latest",
|
|
178
|
+
"@maestro-js/crypt": "latest",
|
|
179
|
+
"@maestro-js/custom-errors": "latest",
|
|
180
|
+
"@maestro-js/db": "latest",
|
|
181
|
+
"@maestro-js/exceptions": "latest",
|
|
182
|
+
"@maestro-js/hash": "latest",
|
|
183
|
+
"@maestro-js/helpers": "latest",
|
|
184
|
+
"@maestro-js/iso-zod": "latest",
|
|
185
|
+
"@maestro-js/log": "latest",
|
|
186
|
+
"@maestro-js/mail": "latest",
|
|
187
|
+
"@maestro-js/password": "latest",
|
|
188
|
+
"@maestro-js/permissions": "latest",
|
|
189
|
+
"@maestro-js/queue": "latest",
|
|
190
|
+
"@maestro-js/rate-limiting": "latest",
|
|
191
|
+
"@maestro-js/recurring-jobs": "latest",
|
|
192
|
+
"@maestro-js/session": "latest",
|
|
198
193
|
"iso-fns": "npm:iso-fns@2.0.0-alpha.26",
|
|
199
194
|
zod: "^4.3.0"
|
|
200
195
|
},
|
|
201
196
|
devDependencies: {
|
|
202
|
-
"@maestro-js/cli":
|
|
197
|
+
"@maestro-js/cli": "latest",
|
|
203
198
|
"@types/node": "^22.0.0",
|
|
204
199
|
"beartest-js": "^8.0.2"
|
|
205
200
|
}
|
|
@@ -384,7 +379,7 @@ export { CustomErrors } from '@maestro-js/custom-errors'
|
|
|
384
379
|
`;
|
|
385
380
|
|
|
386
381
|
// src/templates/web.ts
|
|
387
|
-
function webPackageJson(name
|
|
382
|
+
function webPackageJson(name) {
|
|
388
383
|
return JSON.stringify(
|
|
389
384
|
{
|
|
390
385
|
name: `@${name}/${name}-web`,
|
|
@@ -402,9 +397,9 @@ function webPackageJson(name, maestroVersion) {
|
|
|
402
397
|
dependencies: {
|
|
403
398
|
[`@${name}/schemas`]: "workspace:*",
|
|
404
399
|
[`@${name}/services`]: "workspace:*",
|
|
405
|
-
"@maestro-js/custom-errors":
|
|
406
|
-
"@maestro-js/log":
|
|
407
|
-
"@maestro-js/form":
|
|
400
|
+
"@maestro-js/custom-errors": "latest",
|
|
401
|
+
"@maestro-js/log": "latest",
|
|
402
|
+
"@maestro-js/form": "latest",
|
|
408
403
|
"@react-router/node": "^7.9.0",
|
|
409
404
|
"@react-router/serve": "^7.9.0",
|
|
410
405
|
"@sentry/react-router": "^9",
|
|
@@ -419,8 +414,8 @@ function webPackageJson(name, maestroVersion) {
|
|
|
419
414
|
zod: "^4.0.0"
|
|
420
415
|
},
|
|
421
416
|
devDependencies: {
|
|
422
|
-
"@maestro-js/cli":
|
|
423
|
-
"@maestro-js/react-router-file-routes":
|
|
417
|
+
"@maestro-js/cli": "latest",
|
|
418
|
+
"@maestro-js/react-router-file-routes": "latest",
|
|
424
419
|
"@playwright/test": "^1.52.0",
|
|
425
420
|
"@react-router/dev": "^7.9.0",
|
|
426
421
|
"@tailwindcss/vite": "^4.2.0",
|
|
@@ -909,93 +904,34 @@ export function getRequestContext(context: Readonly<RouterContextProvider>) {
|
|
|
909
904
|
return request
|
|
910
905
|
}
|
|
911
906
|
`;
|
|
912
|
-
var csrfMiddlewareServer = `import {
|
|
913
|
-
import type { MiddlewareFunction } from 'react-router'
|
|
907
|
+
var csrfMiddlewareServer = `import type { MiddlewareFunction } from 'react-router'
|
|
914
908
|
import { getRequestContext } from './request-context.server'
|
|
915
909
|
|
|
916
|
-
const MUTATING_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE'])
|
|
917
|
-
|
|
918
910
|
export const csrfMiddleware: MiddlewareFunction<Response> = async ({ request, context }, next) => {
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
if (contentType.startsWith('application/x-www-form-urlencoded') || contentType.startsWith('multipart/form-data')) {
|
|
929
|
-
try {
|
|
930
|
-
const cloned = request.clone()
|
|
931
|
-
const formData = await cloned.formData()
|
|
932
|
-
const value = formData.get('__csrfToken')
|
|
933
|
-
clientCsrfToken = typeof value === 'string' ? value : null
|
|
934
|
-
} catch {
|
|
935
|
-
clientCsrfToken = null
|
|
911
|
+
const mutatingMethods = ['POST', 'PUT', 'DELETE']
|
|
912
|
+
if (mutatingMethods.includes(request.method)) {
|
|
913
|
+
const cloned = request.clone()
|
|
914
|
+
const formDataForMiddleware = await cloned.formData()
|
|
915
|
+
const clientCsrfToken = formDataForMiddleware.get('__csrfToken')
|
|
916
|
+
const requestContext = getRequestContext(context)
|
|
917
|
+
const sessionCsrfToken = requestContext.session.getCsrfToken()
|
|
918
|
+
if (clientCsrfToken !== sessionCsrfToken) {
|
|
919
|
+
throw new Response('Invalid CSRF token', { status: 403 })
|
|
936
920
|
}
|
|
937
|
-
} else {
|
|
938
|
-
clientCsrfToken = request.headers.get('x-csrf-token')
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
const requestContext = getRequestContext(context)
|
|
942
|
-
const sessionCsrfToken = requestContext.session.getCsrfToken()
|
|
943
|
-
|
|
944
|
-
if (!clientCsrfToken || !constantTimeEqual(clientCsrfToken, sessionCsrfToken)) {
|
|
945
|
-
throw new Response('Invalid CSRF token', { status: 403 })
|
|
946
921
|
}
|
|
947
922
|
return next()
|
|
948
923
|
}
|
|
949
|
-
|
|
950
|
-
function constantTimeEqual(a: string, b: string): boolean {
|
|
951
|
-
const aBuf = Buffer.from(a)
|
|
952
|
-
const bBuf = Buffer.from(b)
|
|
953
|
-
if (aBuf.length !== bBuf.length) return false
|
|
954
|
-
return timingSafeEqual(aBuf, bBuf)
|
|
955
|
-
}
|
|
956
924
|
`;
|
|
957
925
|
var securityHeadersMiddlewareServer = `import type { MiddlewareFunction } from 'react-router'
|
|
958
926
|
|
|
959
|
-
// Security-headers middleware must be the OUTERMOST middleware so that headers
|
|
960
|
-
// are applied to thrown Responses (e.g. 403s from csrfMiddleware) as well as
|
|
961
|
-
// returned ones \u2014 try/finally ensures both code paths get the headers.
|
|
962
927
|
export const securityHeadersMiddleware: MiddlewareFunction<Response> = async (_args, next) => {
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
applySecurityHeaders(thrown.headers)
|
|
969
|
-
}
|
|
970
|
-
throw thrown
|
|
971
|
-
}
|
|
972
|
-
applySecurityHeaders(response.headers)
|
|
928
|
+
const response = await next()
|
|
929
|
+
response.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')
|
|
930
|
+
response.headers.set('X-Content-Type-Options', 'nosniff')
|
|
931
|
+
response.headers.set('X-Frame-Options', 'DENY')
|
|
932
|
+
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
|
|
973
933
|
return response
|
|
974
934
|
}
|
|
975
|
-
|
|
976
|
-
function applySecurityHeaders(headers: Headers) {
|
|
977
|
-
headers.set('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload')
|
|
978
|
-
headers.set('X-Content-Type-Options', 'nosniff')
|
|
979
|
-
headers.set('X-Frame-Options', 'DENY')
|
|
980
|
-
headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
|
|
981
|
-
// Default-deny CSP. Tighten with route-level nonces for inline <script>/<style>.
|
|
982
|
-
// Apps that need third-party origins (analytics, fonts, CDNs) should extend
|
|
983
|
-
// this list \u2014 ship something restrictive by default rather than leaving it
|
|
984
|
-
// off entirely.
|
|
985
|
-
if (!headers.has('Content-Security-Policy')) {
|
|
986
|
-
headers.set(
|
|
987
|
-
'Content-Security-Policy',
|
|
988
|
-
"default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; " +
|
|
989
|
-
"script-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'"
|
|
990
|
-
)
|
|
991
|
-
}
|
|
992
|
-
headers.set(
|
|
993
|
-
'Permissions-Policy',
|
|
994
|
-
'camera=(), microphone=(), geolocation=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=()'
|
|
995
|
-
)
|
|
996
|
-
headers.set('Cross-Origin-Opener-Policy', 'same-origin')
|
|
997
|
-
headers.set('Cross-Origin-Resource-Policy', 'same-origin')
|
|
998
|
-
}
|
|
999
935
|
`;
|
|
1000
936
|
var customErrorStatusCodeMiddlewareServer = `import * as Sentry from '@sentry/react-router'
|
|
1001
937
|
import { type MiddlewareFunction } from 'react-router'
|
|
@@ -1047,7 +983,7 @@ export function getSessionToast(session: Session): Toast | null {
|
|
|
1047
983
|
`;
|
|
1048
984
|
|
|
1049
985
|
// src/templates/queue-processor.ts
|
|
1050
|
-
function queueProcessorPackageJson(name
|
|
986
|
+
function queueProcessorPackageJson(name) {
|
|
1051
987
|
return JSON.stringify(
|
|
1052
988
|
{
|
|
1053
989
|
name: `@${name}/queue-processor`,
|
|
@@ -1057,11 +993,11 @@ function queueProcessorPackageJson(name, maestroVersion) {
|
|
|
1057
993
|
start: "maestro config:run --config queue-processor -- tsx src/index.ts"
|
|
1058
994
|
},
|
|
1059
995
|
dependencies: {
|
|
1060
|
-
"@maestro-js/config":
|
|
996
|
+
"@maestro-js/config": "latest",
|
|
1061
997
|
[`@${name}/services`]: "workspace:*"
|
|
1062
998
|
},
|
|
1063
999
|
devDependencies: {
|
|
1064
|
-
"@maestro-js/cli":
|
|
1000
|
+
"@maestro-js/cli": "latest",
|
|
1065
1001
|
"@types/node": "^22.19.11",
|
|
1066
1002
|
tsx: "^4.21.0"
|
|
1067
1003
|
}
|
|
@@ -1254,16 +1190,9 @@ function replaceTokens(content, tokens) {
|
|
|
1254
1190
|
}
|
|
1255
1191
|
|
|
1256
1192
|
// src/index.ts
|
|
1257
|
-
function getInitVersion() {
|
|
1258
|
-
const dir = path.dirname(fileURLToPath(import.meta.url));
|
|
1259
|
-
const raw = fs.readFileSync(path.join(dir, "../package.json"), "utf-8");
|
|
1260
|
-
const pkg = JSON.parse(raw);
|
|
1261
|
-
return pkg.version;
|
|
1262
|
-
}
|
|
1263
1193
|
function buildProjectTree(name) {
|
|
1264
|
-
const maestroVersion = `^${getInitVersion()}`;
|
|
1265
1194
|
return {
|
|
1266
|
-
"package.json": rootPackageJson(name
|
|
1195
|
+
"package.json": rootPackageJson(name),
|
|
1267
1196
|
"pnpm-workspace.yaml": pnpmWorkspace(name),
|
|
1268
1197
|
"tsconfig.json": rootTsconfig,
|
|
1269
1198
|
".env": rootEnv,
|
|
@@ -1276,13 +1205,13 @@ function buildProjectTree(name) {
|
|
|
1276
1205
|
},
|
|
1277
1206
|
packages: {
|
|
1278
1207
|
schemas: {
|
|
1279
|
-
"package.json": schemasPackageJson(name
|
|
1208
|
+
"package.json": schemasPackageJson(name),
|
|
1280
1209
|
src: {
|
|
1281
1210
|
"index.ts": schemasIndex
|
|
1282
1211
|
}
|
|
1283
1212
|
},
|
|
1284
1213
|
services: {
|
|
1285
|
-
"package.json": servicesPackageJson(name
|
|
1214
|
+
"package.json": servicesPackageJson(name),
|
|
1286
1215
|
"tsconfig.json": servicesTsconfig,
|
|
1287
1216
|
src: {
|
|
1288
1217
|
"maestro.ts": maestroTs,
|
|
@@ -1291,7 +1220,7 @@ function buildProjectTree(name) {
|
|
|
1291
1220
|
}
|
|
1292
1221
|
},
|
|
1293
1222
|
[`${name}-web`]: {
|
|
1294
|
-
"package.json": webPackageJson(name
|
|
1223
|
+
"package.json": webPackageJson(name),
|
|
1295
1224
|
"tsconfig.json": webTsconfig,
|
|
1296
1225
|
"vite.config.ts": viteConfig,
|
|
1297
1226
|
"react-router.config.ts": reactRouterConfig,
|
|
@@ -1320,7 +1249,7 @@ function buildProjectTree(name) {
|
|
|
1320
1249
|
}
|
|
1321
1250
|
},
|
|
1322
1251
|
"queue-processor": {
|
|
1323
|
-
"package.json": queueProcessorPackageJson(name
|
|
1252
|
+
"package.json": queueProcessorPackageJson(name),
|
|
1324
1253
|
"tsconfig.json": queueProcessorTsconfig,
|
|
1325
1254
|
src: {
|
|
1326
1255
|
"index.ts": queueProcessorIndex,
|
|
@@ -1342,6 +1271,5 @@ function buildProjectTree(name) {
|
|
|
1342
1271
|
|
|
1343
1272
|
export {
|
|
1344
1273
|
scaffold,
|
|
1345
|
-
getInitVersion,
|
|
1346
1274
|
buildProjectTree
|
|
1347
1275
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,6 @@ type Tree = {
|
|
|
4
4
|
type Tokens = Record<string, string>;
|
|
5
5
|
declare function scaffold(tree: Tree, basePath: string, tokens?: Tokens): Promise<string[]>;
|
|
6
6
|
|
|
7
|
-
declare function getInitVersion(): string;
|
|
8
7
|
declare function buildProjectTree(name: string): Tree;
|
|
9
8
|
|
|
10
|
-
export { type Tokens, type Tree, buildProjectTree,
|
|
9
|
+
export { type Tokens, type Tree, buildProjectTree, scaffold };
|
package/dist/index.js
CHANGED