canopycms 0.0.61-int.75 → 0.0.61
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/ai/handler.js +1 -1
- package/dist/ai/handler.js.map +1 -1
- package/dist/api/assets.d.ts.map +1 -1
- package/dist/api/assets.js +36 -4
- package/dist/api/assets.js.map +1 -1
- package/dist/api/branch-status.d.ts.map +1 -1
- package/dist/api/branch-status.js +56 -0
- package/dist/api/branch-status.js.map +1 -1
- package/dist/api/branch-withdraw.d.ts.map +1 -1
- package/dist/api/branch-withdraw.js +14 -3
- package/dist/api/branch-withdraw.js.map +1 -1
- package/dist/api/branch.d.ts +31 -2
- package/dist/api/branch.d.ts.map +1 -1
- package/dist/api/branch.js +252 -13
- package/dist/api/branch.js.map +1 -1
- package/dist/api/content.d.ts.map +1 -1
- package/dist/api/content.js +12 -4
- package/dist/api/content.js.map +1 -1
- package/dist/api/entries.d.ts.map +1 -1
- package/dist/api/entries.js +11 -9
- package/dist/api/entries.js.map +1 -1
- package/dist/api/guards.d.ts.map +1 -1
- package/dist/api/guards.js +12 -5
- package/dist/api/guards.js.map +1 -1
- package/dist/api/permissions.d.ts +2 -2
- package/dist/api/permissions.d.ts.map +1 -1
- package/dist/api/permissions.js +51 -3
- package/dist/api/permissions.js.map +1 -1
- package/dist/api/reference-options.d.ts.map +1 -1
- package/dist/api/reference-options.js +10 -17
- package/dist/api/reference-options.js.map +1 -1
- package/dist/api/resolve-references.d.ts.map +1 -1
- package/dist/api/resolve-references.js +3 -1
- package/dist/api/resolve-references.js.map +1 -1
- package/dist/api/schema.d.ts.map +1 -1
- package/dist/api/schema.js +3 -2
- package/dist/api/schema.js.map +1 -1
- package/dist/api/settings-helpers.d.ts.map +1 -1
- package/dist/api/settings-helpers.js +6 -5
- package/dist/api/settings-helpers.js.map +1 -1
- package/dist/assets/pipeline.d.ts +11 -2
- package/dist/assets/pipeline.d.ts.map +1 -1
- package/dist/assets/pipeline.js +114 -2
- package/dist/assets/pipeline.js.map +1 -1
- package/dist/assets/transform-directives.d.ts +18 -0
- package/dist/assets/transform-directives.d.ts.map +1 -1
- package/dist/assets/transform-directives.js +18 -0
- package/dist/assets/transform-directives.js.map +1 -1
- package/dist/assets/transform.d.ts.map +1 -1
- package/dist/assets/transform.js +1 -10
- package/dist/assets/transform.js.map +1 -1
- package/dist/auth/types.d.ts +29 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/authorization/index.d.ts +1 -1
- package/dist/authorization/index.d.ts.map +1 -1
- package/dist/authorization/index.js +1 -1
- package/dist/authorization/index.js.map +1 -1
- package/dist/authorization/protected-branch.d.ts +75 -0
- package/dist/authorization/protected-branch.d.ts.map +1 -1
- package/dist/authorization/protected-branch.js +39 -0
- package/dist/authorization/protected-branch.js.map +1 -1
- package/dist/branch-registry.d.ts.map +1 -1
- package/dist/branch-registry.js +5 -1
- package/dist/branch-registry.js.map +1 -1
- package/dist/branch-schema-cache.d.ts.map +1 -1
- package/dist/branch-schema-cache.js +9 -0
- package/dist/branch-schema-cache.js.map +1 -1
- package/dist/build/generate-ai-content.js +1 -1
- package/dist/build/generate-ai-content.js.map +1 -1
- package/dist/cli/cli.js +1442 -828
- package/dist/cli/generate-ai-content.js +404 -136
- package/dist/cli/init.d.ts +8 -2
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +440 -151
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/project-detect.d.ts +89 -0
- package/dist/cli/project-detect.d.ts.map +1 -0
- package/dist/cli/project-detect.js +240 -0
- package/dist/cli/project-detect.js.map +1 -0
- package/dist/cli/template-files/Dockerfile.cms.template +11 -6
- package/dist/cli/template-files/cdk-app.ts.template +82 -0
- package/dist/cli/template-files/cdk.json.template +9 -0
- package/dist/cli/template-files/cms-stack.ts.template +124 -0
- package/dist/cli/template-files/deploy-cms.yml.template +125 -13
- package/dist/cli/template-files/dockerignore.template +2 -1
- package/dist/cli/templates.d.ts +26 -2
- package/dist/cli/templates.d.ts.map +1 -1
- package/dist/cli/templates.js +36 -4
- package/dist/cli/templates.js.map +1 -1
- package/dist/config/schemas/config.d.ts +2 -3
- package/dist/config/schemas/config.d.ts.map +1 -1
- package/dist/config/schemas/config.js +21 -1
- package/dist/config/schemas/config.js.map +1 -1
- package/dist/config/validation.d.ts +9 -0
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +22 -12
- package/dist/config/validation.js.map +1 -1
- package/dist/content-reader.js +1 -1
- package/dist/content-reader.js.map +1 -1
- package/dist/content-store.d.ts +11 -0
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +2 -1
- package/dist/content-store.js.map +1 -1
- package/dist/dev-content-watcher.d.ts.map +1 -1
- package/dist/dev-content-watcher.js +4 -1
- package/dist/dev-content-watcher.js.map +1 -1
- package/dist/editor/BranchManager.d.ts +15 -0
- package/dist/editor/BranchManager.d.ts.map +1 -1
- package/dist/editor/BranchManager.js +43 -9
- package/dist/editor/BranchManager.js.map +1 -1
- package/dist/editor/CanopyEditor.d.ts.map +1 -1
- package/dist/editor/CanopyEditor.js +2 -2
- package/dist/editor/CanopyEditor.js.map +1 -1
- package/dist/editor/Editor.d.ts.map +1 -1
- package/dist/editor/Editor.js +110 -48
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/admin/SystemHealthPanel.d.ts.map +1 -1
- package/dist/editor/admin/SystemHealthPanel.js +9 -8
- package/dist/editor/admin/SystemHealthPanel.js.map +1 -1
- package/dist/editor/components/EditorHeader.d.ts +6 -0
- package/dist/editor/components/EditorHeader.d.ts.map +1 -1
- package/dist/editor/components/EditorHeader.js +76 -23
- package/dist/editor/components/EditorHeader.js.map +1 -1
- package/dist/editor/components/EntryCreateModal.d.ts.map +1 -1
- package/dist/editor/components/EntryCreateModal.js +21 -6
- package/dist/editor/components/EntryCreateModal.js.map +1 -1
- package/dist/editor/context/SWRProvider.d.ts +31 -0
- package/dist/editor/context/SWRProvider.d.ts.map +1 -0
- package/dist/editor/context/SWRProvider.js +12 -0
- package/dist/editor/context/SWRProvider.js.map +1 -0
- package/dist/editor/context/index.d.ts +3 -0
- package/dist/editor/context/index.d.ts.map +1 -1
- package/dist/editor/context/index.js +3 -0
- package/dist/editor/context/index.js.map +1 -1
- package/dist/editor/editor-utils.d.ts.map +1 -1
- package/dist/editor/editor-utils.js +8 -2
- package/dist/editor/editor-utils.js.map +1 -1
- package/dist/editor/fields/ImageField.d.ts.map +1 -1
- package/dist/editor/fields/ImageField.js +27 -3
- package/dist/editor/fields/ImageField.js.map +1 -1
- package/dist/editor/fields/ReferenceField.d.ts.map +1 -1
- package/dist/editor/fields/ReferenceField.js +52 -31
- package/dist/editor/fields/ReferenceField.js.map +1 -1
- package/dist/editor/hooks/__test__/test-utils.d.ts +38 -3
- package/dist/editor/hooks/__test__/test-utils.d.ts.map +1 -1
- package/dist/editor/hooks/__test__/test-utils.js +50 -4
- package/dist/editor/hooks/__test__/test-utils.js.map +1 -1
- package/dist/editor/hooks/index.d.ts +4 -1
- package/dist/editor/hooks/index.d.ts.map +1 -1
- package/dist/editor/hooks/index.js +4 -1
- package/dist/editor/hooks/index.js.map +1 -1
- package/dist/editor/hooks/useBranchManager.d.ts +21 -1
- package/dist/editor/hooks/useBranchManager.d.ts.map +1 -1
- package/dist/editor/hooks/useBranchManager.js +68 -32
- package/dist/editor/hooks/useBranchManager.js.map +1 -1
- package/dist/editor/hooks/useBranchesData.d.ts +57 -0
- package/dist/editor/hooks/useBranchesData.d.ts.map +1 -0
- package/dist/editor/hooks/useBranchesData.js +69 -0
- package/dist/editor/hooks/useBranchesData.js.map +1 -0
- package/dist/editor/hooks/useCommentSystem.d.ts.map +1 -1
- package/dist/editor/hooks/useCommentSystem.js +24 -22
- package/dist/editor/hooks/useCommentSystem.js.map +1 -1
- package/dist/editor/hooks/useCommentsData.d.ts +29 -0
- package/dist/editor/hooks/useCommentsData.d.ts.map +1 -0
- package/dist/editor/hooks/useCommentsData.js +40 -0
- package/dist/editor/hooks/useCommentsData.js.map +1 -0
- package/dist/editor/hooks/useDraftManager.d.ts.map +1 -1
- package/dist/editor/hooks/useDraftManager.js +32 -18
- package/dist/editor/hooks/useDraftManager.js.map +1 -1
- package/dist/editor/hooks/useEntriesData.d.ts +35 -0
- package/dist/editor/hooks/useEntriesData.d.ts.map +1 -0
- package/dist/editor/hooks/useEntriesData.js +96 -0
- package/dist/editor/hooks/useEntriesData.js.map +1 -0
- package/dist/editor/hooks/useEntryManager.d.ts +8 -15
- package/dist/editor/hooks/useEntryManager.d.ts.map +1 -1
- package/dist/editor/hooks/useEntryManager.js +259 -117
- package/dist/editor/hooks/useEntryManager.js.map +1 -1
- package/dist/editor/hooks/usePermissionManager.d.ts +2 -2
- package/dist/editor/hooks/usePermissionManager.d.ts.map +1 -1
- package/dist/editor/hooks/usePermissionManager.js +11 -9
- package/dist/editor/hooks/usePermissionManager.js.map +1 -1
- package/dist/editor/hooks/useReferenceResolution.d.ts.map +1 -1
- package/dist/editor/hooks/useReferenceResolution.js +24 -1
- package/dist/editor/hooks/useReferenceResolution.js.map +1 -1
- package/dist/editor/media/MediaLibraryBody.d.ts.map +1 -1
- package/dist/editor/media/MediaLibraryBody.js +12 -2
- package/dist/editor/media/MediaLibraryBody.js.map +1 -1
- package/dist/editor/permission-manager/GroupSelector.d.ts.map +1 -1
- package/dist/editor/permission-manager/GroupSelector.js +7 -2
- package/dist/editor/permission-manager/GroupSelector.js.map +1 -1
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts +3 -3
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts.map +1 -1
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js +1 -0
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js.map +1 -1
- package/dist/editor/permission-manager/types.d.ts +6 -4
- package/dist/editor/permission-manager/types.d.ts.map +1 -1
- package/dist/editor/test-setup.js +8 -0
- package/dist/editor/test-setup.js.map +1 -1
- package/dist/git-manager.d.ts +126 -9
- package/dist/git-manager.d.ts.map +1 -1
- package/dist/git-manager.js +251 -27
- package/dist/git-manager.js.map +1 -1
- package/dist/github-service.d.ts.map +1 -1
- package/dist/github-service.js +13 -7
- package/dist/github-service.js.map +1 -1
- package/dist/http/handler.d.ts.map +1 -1
- package/dist/http/handler.js +8 -2
- package/dist/http/handler.js.map +1 -1
- package/dist/operating-mode/client-unsafe-strategy.d.ts.map +1 -1
- package/dist/operating-mode/client-unsafe-strategy.js +7 -8
- package/dist/operating-mode/client-unsafe-strategy.js.map +1 -1
- package/dist/operating-mode/deployment-name.d.ts +28 -0
- package/dist/operating-mode/deployment-name.d.ts.map +1 -0
- package/dist/operating-mode/deployment-name.js +78 -0
- package/dist/operating-mode/deployment-name.js.map +1 -0
- package/dist/operating-mode/index.d.ts +5 -1
- package/dist/operating-mode/index.d.ts.map +1 -1
- package/dist/operating-mode/index.js +7 -1
- package/dist/operating-mode/index.js.map +1 -1
- package/dist/operating-mode/types.d.ts +13 -3
- package/dist/operating-mode/types.d.ts.map +1 -1
- package/dist/paths/branch-name.d.ts +38 -0
- package/dist/paths/branch-name.d.ts.map +1 -1
- package/dist/paths/branch-name.js +46 -0
- package/dist/paths/branch-name.js.map +1 -1
- package/dist/paths/index.d.ts +1 -1
- package/dist/paths/index.d.ts.map +1 -1
- package/dist/paths/index.js +1 -1
- package/dist/paths/index.js.map +1 -1
- package/dist/reference-resolver.d.ts +6 -2
- package/dist/reference-resolver.d.ts.map +1 -1
- package/dist/reference-resolver.js +8 -1
- package/dist/reference-resolver.js.map +1 -1
- package/dist/schema/meta-loader.d.ts.map +1 -1
- package/dist/schema/meta-loader.js +10 -2
- package/dist/schema/meta-loader.js.map +1 -1
- package/dist/schema/schema-store.d.ts +11 -2
- package/dist/schema/schema-store.d.ts.map +1 -1
- package/dist/schema/schema-store.js +23 -11
- package/dist/schema/schema-store.js.map +1 -1
- package/dist/settings-workspace.d.ts +0 -15
- package/dist/settings-workspace.d.ts.map +1 -1
- package/dist/settings-workspace.js +97 -1
- package/dist/settings-workspace.js.map +1 -1
- package/dist/types.d.ts +63 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/debug.d.ts +11 -0
- package/dist/utils/debug.d.ts.map +1 -1
- package/dist/utils/debug.js +12 -1
- package/dist/utils/debug.js.map +1 -1
- package/dist/utils/git.d.ts +38 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +69 -0
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/logger.d.ts +71 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +85 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/validation/entry-type-reference-validator.d.ts +33 -0
- package/dist/validation/entry-type-reference-validator.d.ts.map +1 -0
- package/dist/validation/entry-type-reference-validator.js +110 -0
- package/dist/validation/entry-type-reference-validator.js.map +1 -0
- package/dist/worker/cms-worker.d.ts +232 -3
- package/dist/worker/cms-worker.d.ts.map +1 -1
- package/dist/worker/cms-worker.js +856 -87
- package/dist/worker/cms-worker.js.map +1 -1
- package/dist/worker/log.d.ts +61 -0
- package/dist/worker/log.d.ts.map +1 -0
- package/dist/worker/log.js +74 -0
- package/dist/worker/log.js.map +1 -0
- package/package.json +3 -1
package/dist/cli/init.js
CHANGED
|
@@ -267,6 +267,16 @@ var init_config = __esm({
|
|
|
267
267
|
allowNetworkRemoteInProd: z4.boolean().optional(),
|
|
268
268
|
settingsBranch: z4.string().optional(),
|
|
269
269
|
autoCreateSettingsPR: z4.boolean().optional(),
|
|
270
|
+
// Deliberately `deploymentNameSchema.optional()`, NOT `deploymentNameSchema` alone.
|
|
271
|
+
// deploymentNameSchema.default('prod') would make `parse(undefined)` resolve to
|
|
272
|
+
// the literal 'prod' instead of staying `undefined` — collapsing the
|
|
273
|
+
// env > config > modeDefault precedence chain that resolveDeploymentName
|
|
274
|
+
// (operating-mode/deployment-name.ts) implements: config would then always
|
|
275
|
+
// "win" over modeDefault (masking dev's real default of 'local'), and the env
|
|
276
|
+
// var would just be racing config's baked-in 'prod' instead of a true absence.
|
|
277
|
+
// `.optional()` here is what keeps an omitted deploymentName reaching
|
|
278
|
+
// resolveDeploymentName as `undefined`, so it can fall through to modeDefault.
|
|
279
|
+
// Do not "fix" this by removing `.optional()`.
|
|
270
280
|
deploymentName: deploymentNameSchema.optional(),
|
|
271
281
|
contentRoot: contentRootSchema.default("content"),
|
|
272
282
|
sourceRoot: sourceRootSchema.optional(),
|
|
@@ -356,14 +366,59 @@ var init_config2 = __esm({
|
|
|
356
366
|
}
|
|
357
367
|
});
|
|
358
368
|
|
|
369
|
+
// dist/utils/error.js
|
|
370
|
+
function getErrorMessage(err) {
|
|
371
|
+
if (err instanceof Error) {
|
|
372
|
+
return err.message;
|
|
373
|
+
}
|
|
374
|
+
if (typeof err === "string") {
|
|
375
|
+
return err;
|
|
376
|
+
}
|
|
377
|
+
return String(err);
|
|
378
|
+
}
|
|
379
|
+
function isNodeError(err) {
|
|
380
|
+
return err instanceof Error && "code" in err;
|
|
381
|
+
}
|
|
382
|
+
function isNotFoundError(err) {
|
|
383
|
+
return isNodeError(err) && err.code === "ENOENT";
|
|
384
|
+
}
|
|
385
|
+
var init_error = __esm({
|
|
386
|
+
"dist/utils/error.js"() {
|
|
387
|
+
"use strict";
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
// dist/utils/fs.js
|
|
392
|
+
import fs from "node:fs/promises";
|
|
393
|
+
async function filePathExists(filePath) {
|
|
394
|
+
try {
|
|
395
|
+
await fs.stat(filePath);
|
|
396
|
+
return true;
|
|
397
|
+
} catch (err) {
|
|
398
|
+
if (isNotFoundError(err))
|
|
399
|
+
return false;
|
|
400
|
+
throw err;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
var init_fs = __esm({
|
|
404
|
+
"dist/utils/fs.js"() {
|
|
405
|
+
"use strict";
|
|
406
|
+
init_error();
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
|
|
359
410
|
// dist/cli/templates.js
|
|
360
411
|
var templates_exports = {};
|
|
361
412
|
__export(templates_exports, {
|
|
413
|
+
SCAFFOLD_STACK_NAME: () => SCAFFOLD_STACK_NAME,
|
|
362
414
|
aiConfig: () => aiConfig,
|
|
363
415
|
aiRoute: () => aiRoute,
|
|
364
416
|
apiRoute: () => apiRoute,
|
|
365
417
|
canopyCmsConfig: () => canopyCmsConfig,
|
|
366
418
|
canopyContext: () => canopyContext,
|
|
419
|
+
cdkApp: () => cdkApp,
|
|
420
|
+
cdkJson: () => cdkJson,
|
|
421
|
+
cmsStack: () => cmsStack,
|
|
367
422
|
dockerfileCms: () => dockerfileCms,
|
|
368
423
|
dockerignore: () => dockerignore,
|
|
369
424
|
editPage: () => editPage,
|
|
@@ -427,21 +482,205 @@ async function nextConfig(options) {
|
|
|
427
482
|
const templateName = options.staticBuild ? "next.config-static.ts.template" : "next.config.ts.template";
|
|
428
483
|
return readTemplate(templateName);
|
|
429
484
|
}
|
|
430
|
-
async function dockerfileCms() {
|
|
431
|
-
|
|
485
|
+
async function dockerfileCms(options) {
|
|
486
|
+
const template = await readTemplate("Dockerfile.cms.template");
|
|
487
|
+
return template.replace("{{DOCKER_COPY}}", options.copy).replace("{{DOCKER_INSTALL}}", options.install).replace("{{DOCKER_BUILD}}", options.build);
|
|
432
488
|
}
|
|
433
489
|
async function dockerignore() {
|
|
434
490
|
return readTemplate("dockerignore.template");
|
|
435
491
|
}
|
|
436
|
-
async function githubWorkflowCms() {
|
|
437
|
-
|
|
492
|
+
async function githubWorkflowCms(options) {
|
|
493
|
+
const template = await readTemplate("deploy-cms.yml.template");
|
|
494
|
+
return template.replace("{{DEFAULT_BRANCH}}", options.defaultBranch).replace("{{LOCKFILE}}", options.lockfile).replace("{{CI_INSTALL}}", options.ciInstall).replaceAll("{{ADD_DEV}}", options.addDev).replace("{{STACK_NAME}}", SCAFFOLD_STACK_NAME);
|
|
495
|
+
}
|
|
496
|
+
async function cdkJson() {
|
|
497
|
+
return readTemplate("cdk.json.template");
|
|
438
498
|
}
|
|
439
|
-
|
|
499
|
+
async function cdkApp(options) {
|
|
500
|
+
const template = await readTemplate("cdk-app.ts.template");
|
|
501
|
+
return template.replace("{{STACK_NAME}}", SCAFFOLD_STACK_NAME).replace("{{GITHUB_OWNER}}", options.githubOwner).replace("{{GITHUB_REPO}}", options.githubRepo);
|
|
502
|
+
}
|
|
503
|
+
async function cmsStack() {
|
|
504
|
+
return readTemplate("cms-stack.ts.template");
|
|
505
|
+
}
|
|
506
|
+
var __dirname, TEMPLATES_DIR, SCAFFOLD_STACK_NAME;
|
|
440
507
|
var init_templates = __esm({
|
|
441
508
|
"dist/cli/templates.js"() {
|
|
442
509
|
"use strict";
|
|
443
510
|
__dirname = path2.dirname(fileURLToPath(import.meta.url));
|
|
444
511
|
TEMPLATES_DIR = path2.join(__dirname, "template-files");
|
|
512
|
+
SCAFFOLD_STACK_NAME = "CanopyCms";
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
// dist/cli/project-detect.js
|
|
517
|
+
var project_detect_exports = {};
|
|
518
|
+
__export(project_detect_exports, {
|
|
519
|
+
CDK_DEPENDENCIES: () => CDK_DEPENDENCIES,
|
|
520
|
+
commandsFor: () => commandsFor,
|
|
521
|
+
detectDefaultBranch: () => detectDefaultBranch,
|
|
522
|
+
detectGitHubRepo: () => detectGitHubRepo,
|
|
523
|
+
detectPackageManager: () => detectPackageManager,
|
|
524
|
+
missingCdkDependencies: () => missingCdkDependencies,
|
|
525
|
+
readPackageJson: () => readPackageJson
|
|
526
|
+
});
|
|
527
|
+
import fs3 from "node:fs/promises";
|
|
528
|
+
import path3 from "node:path";
|
|
529
|
+
import { simpleGit } from "simple-git";
|
|
530
|
+
function commandsFor(manager) {
|
|
531
|
+
return COMMANDS[manager];
|
|
532
|
+
}
|
|
533
|
+
async function detectPackageManager(projectDir) {
|
|
534
|
+
for (const dir of await workspaceSearchPath(projectDir)) {
|
|
535
|
+
const declared = await readDeclaredPackageManager(dir);
|
|
536
|
+
if (declared)
|
|
537
|
+
return declared;
|
|
538
|
+
if (await filePathExists(path3.join(dir, "pnpm-lock.yaml")))
|
|
539
|
+
return "pnpm";
|
|
540
|
+
if (await filePathExists(path3.join(dir, "yarn.lock"))) {
|
|
541
|
+
return await isYarnBerryLockfile(dir) ? "yarn-berry" : "yarn";
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
return "npm";
|
|
545
|
+
}
|
|
546
|
+
async function workspaceSearchPath(projectDir) {
|
|
547
|
+
const start = path3.resolve(projectDir);
|
|
548
|
+
const dirs = [start];
|
|
549
|
+
if (!await filePathExists(path3.join(start, "package.json")))
|
|
550
|
+
return dirs;
|
|
551
|
+
let dir = start;
|
|
552
|
+
for (let depth = 0; depth < MAX_WORKSPACE_DEPTH; depth++) {
|
|
553
|
+
if (await filePathExists(path3.join(dir, ".git")))
|
|
554
|
+
break;
|
|
555
|
+
const parent = path3.dirname(dir);
|
|
556
|
+
if (parent === dir)
|
|
557
|
+
break;
|
|
558
|
+
dir = parent;
|
|
559
|
+
dirs.push(dir);
|
|
560
|
+
}
|
|
561
|
+
return dirs;
|
|
562
|
+
}
|
|
563
|
+
async function readDeclaredPackageManager(projectDir) {
|
|
564
|
+
const pkg = await readPackageJson(projectDir);
|
|
565
|
+
const declared = pkg?.["packageManager"];
|
|
566
|
+
if (typeof declared !== "string")
|
|
567
|
+
return null;
|
|
568
|
+
if (declared.startsWith("pnpm@"))
|
|
569
|
+
return "pnpm";
|
|
570
|
+
if (declared.startsWith("npm@"))
|
|
571
|
+
return "npm";
|
|
572
|
+
if (declared.startsWith("yarn@")) {
|
|
573
|
+
const major = Number.parseInt(declared.slice("yarn@".length), 10);
|
|
574
|
+
if (Number.isFinite(major) && major >= 2)
|
|
575
|
+
return "yarn-berry";
|
|
576
|
+
if (Number.isFinite(major))
|
|
577
|
+
return "yarn";
|
|
578
|
+
return await isYarnBerryLockfile(projectDir) ? "yarn-berry" : "yarn";
|
|
579
|
+
}
|
|
580
|
+
return null;
|
|
581
|
+
}
|
|
582
|
+
async function isYarnBerryLockfile(projectDir) {
|
|
583
|
+
try {
|
|
584
|
+
const content = await fs3.readFile(path3.join(projectDir, "yarn.lock"), "utf-8");
|
|
585
|
+
return content.includes("__metadata:");
|
|
586
|
+
} catch {
|
|
587
|
+
return false;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
async function detectDefaultBranch(projectDir) {
|
|
591
|
+
const head = await gitRaw(projectDir, ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"]);
|
|
592
|
+
if (!head)
|
|
593
|
+
return "main";
|
|
594
|
+
const slash = head.indexOf("/");
|
|
595
|
+
const branch = slash === -1 ? head : head.slice(slash + 1);
|
|
596
|
+
return branch || "main";
|
|
597
|
+
}
|
|
598
|
+
async function detectGitHubRepo(projectDir) {
|
|
599
|
+
const url = await gitRaw(projectDir, ["remote", "get-url", "origin"]);
|
|
600
|
+
if (!url)
|
|
601
|
+
return null;
|
|
602
|
+
const match = /github\.com[:/]+([^/]+)\/(.+?)(?:\.git)?\/?$/.exec(url);
|
|
603
|
+
if (!match)
|
|
604
|
+
return null;
|
|
605
|
+
return { owner: match[1], repo: match[2] };
|
|
606
|
+
}
|
|
607
|
+
async function gitRaw(projectDir, args) {
|
|
608
|
+
try {
|
|
609
|
+
const output = await simpleGit({ baseDir: projectDir }).raw(args);
|
|
610
|
+
const trimmed = output.trim();
|
|
611
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
612
|
+
} catch {
|
|
613
|
+
return null;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
async function readPackageJson(projectDir) {
|
|
617
|
+
try {
|
|
618
|
+
const raw = await fs3.readFile(path3.join(projectDir, "package.json"), "utf-8");
|
|
619
|
+
const parsed = JSON.parse(raw);
|
|
620
|
+
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
621
|
+
} catch {
|
|
622
|
+
return null;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
async function missingCdkDependencies(projectDir) {
|
|
626
|
+
const pkg = await readPackageJson(projectDir);
|
|
627
|
+
const declared = /* @__PURE__ */ new Set();
|
|
628
|
+
for (const field of ["dependencies", "devDependencies", "peerDependencies"]) {
|
|
629
|
+
const section = pkg?.[field];
|
|
630
|
+
if (typeof section === "object" && section !== null) {
|
|
631
|
+
for (const name of Object.keys(section))
|
|
632
|
+
declared.add(name);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return CDK_DEPENDENCIES.filter((name) => !declared.has(name));
|
|
636
|
+
}
|
|
637
|
+
var COMMANDS, MAX_WORKSPACE_DEPTH, CDK_DEPENDENCIES;
|
|
638
|
+
var init_project_detect = __esm({
|
|
639
|
+
"dist/cli/project-detect.js"() {
|
|
640
|
+
"use strict";
|
|
641
|
+
init_fs();
|
|
642
|
+
COMMANDS = {
|
|
643
|
+
npm: {
|
|
644
|
+
lockfile: "package-lock.json",
|
|
645
|
+
ciInstall: "npm ci",
|
|
646
|
+
dockerCopy: "COPY package*.json ./",
|
|
647
|
+
dockerInstall: "RUN npm ci",
|
|
648
|
+
build: "npm run build",
|
|
649
|
+
addDev: "npm install --save-dev"
|
|
650
|
+
},
|
|
651
|
+
pnpm: {
|
|
652
|
+
lockfile: "pnpm-lock.yaml",
|
|
653
|
+
ciInstall: "corepack enable && pnpm install --frozen-lockfile",
|
|
654
|
+
dockerCopy: "COPY package.json pnpm-lock.yaml ./",
|
|
655
|
+
dockerInstall: "RUN corepack enable && pnpm install --frozen-lockfile",
|
|
656
|
+
build: "pnpm run build",
|
|
657
|
+
addDev: "pnpm add -D"
|
|
658
|
+
},
|
|
659
|
+
yarn: {
|
|
660
|
+
lockfile: "yarn.lock",
|
|
661
|
+
ciInstall: "corepack enable && yarn install --frozen-lockfile",
|
|
662
|
+
dockerCopy: "COPY package.json yarn.lock ./",
|
|
663
|
+
dockerInstall: "RUN corepack enable && yarn install --frozen-lockfile",
|
|
664
|
+
build: "yarn build",
|
|
665
|
+
addDev: "yarn add -D"
|
|
666
|
+
},
|
|
667
|
+
"yarn-berry": {
|
|
668
|
+
lockfile: "yarn.lock",
|
|
669
|
+
ciInstall: "corepack enable && yarn install --immutable",
|
|
670
|
+
dockerCopy: "COPY package.json yarn.lock .yarnrc.yml ./",
|
|
671
|
+
dockerInstall: "RUN corepack enable && yarn install --immutable",
|
|
672
|
+
build: "yarn build",
|
|
673
|
+
addDev: "yarn add -D"
|
|
674
|
+
}
|
|
675
|
+
};
|
|
676
|
+
MAX_WORKSPACE_DEPTH = 8;
|
|
677
|
+
CDK_DEPENDENCIES = [
|
|
678
|
+
"canopycms-cdk",
|
|
679
|
+
"aws-cdk-lib",
|
|
680
|
+
"constructs",
|
|
681
|
+
"tsx",
|
|
682
|
+
"aws-cdk"
|
|
683
|
+
];
|
|
445
684
|
}
|
|
446
685
|
});
|
|
447
686
|
|
|
@@ -450,15 +689,15 @@ var task_queue_config_exports = {};
|
|
|
450
689
|
__export(task_queue_config_exports, {
|
|
451
690
|
getTaskQueueDir: () => getTaskQueueDir
|
|
452
691
|
});
|
|
453
|
-
import
|
|
692
|
+
import path4 from "node:path";
|
|
454
693
|
function getTaskQueueDir(config) {
|
|
455
694
|
switch (config.mode) {
|
|
456
695
|
case "prod": {
|
|
457
696
|
const workspace = process.env.CANOPYCMS_WORKSPACE_ROOT ?? DEFAULT_PROD_WORKSPACE;
|
|
458
|
-
return
|
|
697
|
+
return path4.join(path4.resolve(workspace), ".tasks");
|
|
459
698
|
}
|
|
460
699
|
case "dev": {
|
|
461
|
-
return
|
|
700
|
+
return path4.join(process.cwd(), ".canopy-dev", ".tasks");
|
|
462
701
|
}
|
|
463
702
|
}
|
|
464
703
|
}
|
|
@@ -495,10 +734,21 @@ var init_debug = __esm({
|
|
|
495
734
|
const minLevel = this.options.minLevel ?? "DEBUG";
|
|
496
735
|
return LOG_LEVELS[level] >= LOG_LEVELS[minLevel];
|
|
497
736
|
}
|
|
737
|
+
/**
|
|
738
|
+
* The ISO-8601 timestamp leads the line BARE - not wrapped in brackets as it
|
|
739
|
+
* once was. `CANOPYCMS_DEBUG=true` can be set on the EC2 worker, whose stdout
|
|
740
|
+
* appends to /var/log/canopy-worker/worker.log; the CloudWatch agent's
|
|
741
|
+
* `multi_line_start_pattern` matches the timestamp at the START of a line
|
|
742
|
+
* (see worker/log.ts's INVARIANT and cms-service.ts's agent config), so a
|
|
743
|
+
* leading `[` meant every debug line was silently folded into the previous
|
|
744
|
+
* event instead of starting its own. The bracketed `[prefix:category]` and
|
|
745
|
+
* `[level]` fields still follow, so the human-readable shape is unchanged
|
|
746
|
+
* apart from those two characters.
|
|
747
|
+
*/
|
|
498
748
|
formatMessage(level, category, message) {
|
|
499
749
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
500
750
|
const prefix = this.options.prefix ?? "CanopyCMS";
|
|
501
|
-
return
|
|
751
|
+
return `${timestamp} [${prefix}:${category}] [${level}] ${message}`;
|
|
502
752
|
}
|
|
503
753
|
debug(category, message, data) {
|
|
504
754
|
if (this.shouldLog("DEBUG")) {
|
|
@@ -567,17 +817,17 @@ var init_debug = __esm({
|
|
|
567
817
|
});
|
|
568
818
|
|
|
569
819
|
// dist/utils/atomic-write.js
|
|
570
|
-
import
|
|
571
|
-
import
|
|
820
|
+
import fs4 from "node:fs/promises";
|
|
821
|
+
import path5 from "node:path";
|
|
572
822
|
async function atomicWriteFile(filePath, content) {
|
|
573
|
-
const dir =
|
|
574
|
-
await
|
|
823
|
+
const dir = path5.dirname(filePath);
|
|
824
|
+
await fs4.mkdir(dir, { recursive: true });
|
|
575
825
|
const tempPath = `${filePath}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
576
|
-
await
|
|
826
|
+
await fs4.writeFile(tempPath, content, typeof content === "string" ? "utf-8" : void 0);
|
|
577
827
|
try {
|
|
578
|
-
await
|
|
828
|
+
await fs4.rename(tempPath, filePath);
|
|
579
829
|
} catch (err) {
|
|
580
|
-
await
|
|
830
|
+
await fs4.unlink(tempPath).catch(() => {
|
|
581
831
|
});
|
|
582
832
|
throw err;
|
|
583
833
|
}
|
|
@@ -589,15 +839,15 @@ var init_atomic_write = __esm({
|
|
|
589
839
|
});
|
|
590
840
|
|
|
591
841
|
// dist/task-queue/task-queue.js
|
|
592
|
-
import
|
|
593
|
-
import
|
|
842
|
+
import fs5 from "node:fs/promises";
|
|
843
|
+
import path6 from "node:path";
|
|
594
844
|
import crypto from "node:crypto";
|
|
595
845
|
function isNotFoundError2(err) {
|
|
596
846
|
return err instanceof Error && "code" in err && err.code === "ENOENT";
|
|
597
847
|
}
|
|
598
848
|
async function enqueueTask(taskDir, task, logger = nullLogger) {
|
|
599
849
|
const id = crypto.randomUUID();
|
|
600
|
-
const pendingDir =
|
|
850
|
+
const pendingDir = path6.join(taskDir, "pending");
|
|
601
851
|
const queuedTask = {
|
|
602
852
|
id,
|
|
603
853
|
action: task.action,
|
|
@@ -607,17 +857,17 @@ async function enqueueTask(taskDir, task, logger = nullLogger) {
|
|
|
607
857
|
retryCount: 0,
|
|
608
858
|
maxRetries: task.maxRetries ?? DEFAULT_MAX_RETRIES
|
|
609
859
|
};
|
|
610
|
-
const filePath =
|
|
860
|
+
const filePath = path6.join(pendingDir, `${id}.json`);
|
|
611
861
|
await atomicWriteFile(filePath, JSON.stringify(queuedTask, null, 2));
|
|
612
862
|
logger.debug("Enqueued task", { id, action: task.action });
|
|
613
863
|
return id;
|
|
614
864
|
}
|
|
615
865
|
async function dequeueTask(taskDir, logger = nullLogger) {
|
|
616
|
-
const pendingDir =
|
|
617
|
-
const processingDir =
|
|
866
|
+
const pendingDir = path6.join(taskDir, "pending");
|
|
867
|
+
const processingDir = path6.join(taskDir, "processing");
|
|
618
868
|
let files;
|
|
619
869
|
try {
|
|
620
|
-
files = await
|
|
870
|
+
files = await fs5.readdir(pendingDir);
|
|
621
871
|
} catch {
|
|
622
872
|
return null;
|
|
623
873
|
}
|
|
@@ -628,7 +878,7 @@ async function dequeueTask(taskDir, logger = nullLogger) {
|
|
|
628
878
|
const tasks = [];
|
|
629
879
|
for (const fileName of jsonFiles) {
|
|
630
880
|
try {
|
|
631
|
-
const content = await
|
|
881
|
+
const content = await fs5.readFile(path6.join(pendingDir, fileName), "utf-8");
|
|
632
882
|
const task = parseTaskJson(content);
|
|
633
883
|
if (!task) {
|
|
634
884
|
await moveToCorrupt(taskDir, pendingDir, fileName, "Invalid JSON", logger);
|
|
@@ -649,17 +899,17 @@ async function dequeueTask(taskDir, logger = nullLogger) {
|
|
|
649
899
|
tasks.sort((a, b) => a.task.createdAt.localeCompare(b.task.createdAt) || a.task.id.localeCompare(b.task.id));
|
|
650
900
|
for (const { fileName, task } of tasks) {
|
|
651
901
|
if (await taskExistsIn(taskDir, task.id, ["completed", "failed"])) {
|
|
652
|
-
await
|
|
902
|
+
await fs5.unlink(path6.join(pendingDir, fileName)).catch(() => {
|
|
653
903
|
});
|
|
654
904
|
logger.debug("Skipped already-finished task", { id: task.id });
|
|
655
905
|
continue;
|
|
656
906
|
}
|
|
657
|
-
const sourcePath =
|
|
658
|
-
const destPath =
|
|
907
|
+
const sourcePath = path6.join(pendingDir, fileName);
|
|
908
|
+
const destPath = path6.join(processingDir, fileName);
|
|
659
909
|
try {
|
|
660
910
|
task.status = "processing";
|
|
661
911
|
await atomicWriteFile(destPath, JSON.stringify(task, null, 2));
|
|
662
|
-
await
|
|
912
|
+
await fs5.unlink(sourcePath);
|
|
663
913
|
logger.debug("Dequeued task", { id: task.id, action: task.action });
|
|
664
914
|
return task;
|
|
665
915
|
} catch (err) {
|
|
@@ -671,16 +921,16 @@ async function dequeueTask(taskDir, logger = nullLogger) {
|
|
|
671
921
|
return null;
|
|
672
922
|
}
|
|
673
923
|
async function completeTask(taskDir, taskId, result, logger = nullLogger) {
|
|
674
|
-
const processingPath =
|
|
675
|
-
const completedDir =
|
|
676
|
-
const completedPath =
|
|
924
|
+
const processingPath = path6.join(taskDir, "processing", `${taskId}.json`);
|
|
925
|
+
const completedDir = path6.join(taskDir, "completed");
|
|
926
|
+
const completedPath = path6.join(completedDir, `${taskId}.json`);
|
|
677
927
|
let task;
|
|
678
928
|
try {
|
|
679
|
-
const content = await
|
|
929
|
+
const content = await fs5.readFile(processingPath, "utf-8");
|
|
680
930
|
const parsed = parseTaskJson(content);
|
|
681
931
|
if (!parsed) {
|
|
682
932
|
logger.debug("Corrupt task file in processing, removing", { id: taskId });
|
|
683
|
-
await
|
|
933
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
684
934
|
});
|
|
685
935
|
return;
|
|
686
936
|
}
|
|
@@ -694,21 +944,21 @@ async function completeTask(taskDir, taskId, result, logger = nullLogger) {
|
|
|
694
944
|
task.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
695
945
|
task.result = result;
|
|
696
946
|
await atomicWriteFile(completedPath, JSON.stringify(task, null, 2));
|
|
697
|
-
await
|
|
947
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
698
948
|
});
|
|
699
949
|
logger.debug("Completed task", { id: taskId });
|
|
700
950
|
}
|
|
701
951
|
async function failTask(taskDir, taskId, error, logger = nullLogger) {
|
|
702
|
-
const processingPath =
|
|
703
|
-
const failedDir =
|
|
704
|
-
const failedPath =
|
|
952
|
+
const processingPath = path6.join(taskDir, "processing", `${taskId}.json`);
|
|
953
|
+
const failedDir = path6.join(taskDir, "failed");
|
|
954
|
+
const failedPath = path6.join(failedDir, `${taskId}.json`);
|
|
705
955
|
let task;
|
|
706
956
|
try {
|
|
707
|
-
const content = await
|
|
957
|
+
const content = await fs5.readFile(processingPath, "utf-8");
|
|
708
958
|
const parsed = parseTaskJson(content);
|
|
709
959
|
if (!parsed) {
|
|
710
960
|
logger.debug("Corrupt task file in processing, removing", { id: taskId });
|
|
711
|
-
await
|
|
961
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
712
962
|
});
|
|
713
963
|
return;
|
|
714
964
|
}
|
|
@@ -722,21 +972,21 @@ async function failTask(taskDir, taskId, error, logger = nullLogger) {
|
|
|
722
972
|
task.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
723
973
|
task.error = error;
|
|
724
974
|
await atomicWriteFile(failedPath, JSON.stringify(task, null, 2));
|
|
725
|
-
await
|
|
975
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
726
976
|
});
|
|
727
977
|
logger.debug("Failed task", { id: taskId, error });
|
|
728
978
|
}
|
|
729
979
|
async function retryTask(taskDir, taskId, error, logger = nullLogger) {
|
|
730
|
-
const processingPath =
|
|
731
|
-
const pendingDir =
|
|
732
|
-
const pendingPath =
|
|
980
|
+
const processingPath = path6.join(taskDir, "processing", `${taskId}.json`);
|
|
981
|
+
const pendingDir = path6.join(taskDir, "pending");
|
|
982
|
+
const pendingPath = path6.join(pendingDir, `${taskId}.json`);
|
|
733
983
|
let task;
|
|
734
984
|
try {
|
|
735
|
-
const content = await
|
|
985
|
+
const content = await fs5.readFile(processingPath, "utf-8");
|
|
736
986
|
const parsed = parseTaskJson(content);
|
|
737
987
|
if (!parsed) {
|
|
738
988
|
logger.debug("Corrupt task file in processing, removing", { id: taskId });
|
|
739
|
-
await
|
|
989
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
740
990
|
});
|
|
741
991
|
return;
|
|
742
992
|
}
|
|
@@ -753,15 +1003,15 @@ async function retryTask(taskDir, taskId, error, logger = nullLogger) {
|
|
|
753
1003
|
task.retryAfter = new Date(Date.now() + backoffMs).toISOString();
|
|
754
1004
|
task.error = error;
|
|
755
1005
|
await atomicWriteFile(pendingPath, JSON.stringify(task, null, 2));
|
|
756
|
-
await
|
|
1006
|
+
await fs5.unlink(processingPath).catch(() => {
|
|
757
1007
|
});
|
|
758
1008
|
logger.debug("Retrying task", { id: taskId, retryCount, backoffMs });
|
|
759
1009
|
}
|
|
760
1010
|
async function requeueFailedTask(taskDir, taskId, logger = nullLogger) {
|
|
761
|
-
const failedPath =
|
|
1011
|
+
const failedPath = path6.join(taskDir, "failed", `${taskId}.json`);
|
|
762
1012
|
let content;
|
|
763
1013
|
try {
|
|
764
|
-
content = await
|
|
1014
|
+
content = await fs5.readFile(failedPath, "utf-8");
|
|
765
1015
|
} catch (err) {
|
|
766
1016
|
if (isNotFoundError2(err))
|
|
767
1017
|
return { error: "not-found" };
|
|
@@ -780,37 +1030,37 @@ async function requeueFailedTask(taskDir, taskId, logger = nullLogger) {
|
|
|
780
1030
|
retryCount: 0,
|
|
781
1031
|
maxRetries: original.maxRetries
|
|
782
1032
|
};
|
|
783
|
-
const pendingPath =
|
|
1033
|
+
const pendingPath = path6.join(taskDir, "pending", `${newTaskId}.json`);
|
|
784
1034
|
await atomicWriteFile(pendingPath, JSON.stringify(newTask, null, 2));
|
|
785
|
-
await
|
|
1035
|
+
await fs5.unlink(failedPath).catch(() => {
|
|
786
1036
|
});
|
|
787
1037
|
logger.debug("Requeued failed task", { originalId: taskId, newTaskId });
|
|
788
1038
|
return { newTaskId };
|
|
789
1039
|
}
|
|
790
1040
|
async function recoverOrphanedTasks(taskDir, maxAgeMs = 5 * 6e4, logger = nullLogger) {
|
|
791
|
-
const processingDir =
|
|
792
|
-
const pendingDir =
|
|
1041
|
+
const processingDir = path6.join(taskDir, "processing");
|
|
1042
|
+
const pendingDir = path6.join(taskDir, "pending");
|
|
793
1043
|
let files;
|
|
794
1044
|
try {
|
|
795
|
-
files = await
|
|
1045
|
+
files = await fs5.readdir(processingDir);
|
|
796
1046
|
} catch {
|
|
797
1047
|
return 0;
|
|
798
1048
|
}
|
|
799
1049
|
const now = Date.now();
|
|
800
1050
|
let recovered = 0;
|
|
801
1051
|
for (const fileName of files.filter((f) => f.endsWith(".json"))) {
|
|
802
|
-
const filePath =
|
|
1052
|
+
const filePath = path6.join(processingDir, fileName);
|
|
803
1053
|
try {
|
|
804
|
-
const stat = await
|
|
1054
|
+
const stat = await fs5.stat(filePath);
|
|
805
1055
|
if (now - stat.mtimeMs >= maxAgeMs) {
|
|
806
|
-
const content = await
|
|
1056
|
+
const content = await fs5.readFile(filePath, "utf-8");
|
|
807
1057
|
const task = parseTaskJson(content);
|
|
808
1058
|
if (!task) {
|
|
809
1059
|
await moveToCorrupt(taskDir, processingDir, fileName, "Invalid JSON during recovery", logger);
|
|
810
1060
|
continue;
|
|
811
1061
|
}
|
|
812
1062
|
if (await taskExistsIn(taskDir, task.id, ["completed", "failed"])) {
|
|
813
|
-
await
|
|
1063
|
+
await fs5.unlink(filePath).catch(() => {
|
|
814
1064
|
});
|
|
815
1065
|
logger.debug("Cleaned up orphaned task (already finished)", {
|
|
816
1066
|
id: task.id
|
|
@@ -818,8 +1068,8 @@ async function recoverOrphanedTasks(taskDir, maxAgeMs = 5 * 6e4, logger = nullLo
|
|
|
818
1068
|
continue;
|
|
819
1069
|
}
|
|
820
1070
|
task.status = "pending";
|
|
821
|
-
await atomicWriteFile(
|
|
822
|
-
await
|
|
1071
|
+
await atomicWriteFile(path6.join(pendingDir, fileName), JSON.stringify(task, null, 2));
|
|
1072
|
+
await fs5.unlink(filePath);
|
|
823
1073
|
logger.debug("Recovered orphaned task", {
|
|
824
1074
|
id: task.id,
|
|
825
1075
|
action: task.action
|
|
@@ -838,19 +1088,19 @@ async function cleanupOldTasks(taskDir, maxAgeMs = 30 * 24 * 60 * 6e4, logger =
|
|
|
838
1088
|
const now = Date.now();
|
|
839
1089
|
let cleaned = 0;
|
|
840
1090
|
for (const subdir of ["completed", "failed"]) {
|
|
841
|
-
const dir =
|
|
1091
|
+
const dir = path6.join(taskDir, subdir);
|
|
842
1092
|
let files;
|
|
843
1093
|
try {
|
|
844
|
-
files = await
|
|
1094
|
+
files = await fs5.readdir(dir);
|
|
845
1095
|
} catch {
|
|
846
1096
|
continue;
|
|
847
1097
|
}
|
|
848
1098
|
for (const fileName of files.filter((f) => f.endsWith(".json"))) {
|
|
849
1099
|
try {
|
|
850
|
-
const filePath =
|
|
851
|
-
const stat = await
|
|
1100
|
+
const filePath = path6.join(dir, fileName);
|
|
1101
|
+
const stat = await fs5.stat(filePath);
|
|
852
1102
|
if (now - stat.mtimeMs >= maxAgeMs) {
|
|
853
|
-
await
|
|
1103
|
+
await fs5.unlink(filePath);
|
|
854
1104
|
cleaned++;
|
|
855
1105
|
}
|
|
856
1106
|
} catch {
|
|
@@ -864,9 +1114,9 @@ async function cleanupOldTasks(taskDir, maxAgeMs = 30 * 24 * 60 * 6e4, logger =
|
|
|
864
1114
|
}
|
|
865
1115
|
async function getTask(taskDir, taskId) {
|
|
866
1116
|
for (const subdir of ["completed", "failed", "processing", "pending"]) {
|
|
867
|
-
const filePath =
|
|
1117
|
+
const filePath = path6.join(taskDir, subdir, `${taskId}.json`);
|
|
868
1118
|
try {
|
|
869
|
-
const content = await
|
|
1119
|
+
const content = await fs5.readFile(filePath, "utf-8");
|
|
870
1120
|
return parseTaskJson(content);
|
|
871
1121
|
} catch {
|
|
872
1122
|
continue;
|
|
@@ -875,10 +1125,10 @@ async function getTask(taskDir, taskId) {
|
|
|
875
1125
|
return null;
|
|
876
1126
|
}
|
|
877
1127
|
async function listTasks(taskDir, status, limit = 100) {
|
|
878
|
-
const dir =
|
|
1128
|
+
const dir = path6.join(taskDir, status);
|
|
879
1129
|
let files;
|
|
880
1130
|
try {
|
|
881
|
-
files = await
|
|
1131
|
+
files = await fs5.readdir(dir);
|
|
882
1132
|
} catch {
|
|
883
1133
|
return [];
|
|
884
1134
|
}
|
|
@@ -887,7 +1137,7 @@ async function listTasks(taskDir, status, limit = 100) {
|
|
|
887
1137
|
if (tasks.length >= limit)
|
|
888
1138
|
break;
|
|
889
1139
|
try {
|
|
890
|
-
const content = await
|
|
1140
|
+
const content = await fs5.readFile(path6.join(dir, fileName), "utf-8");
|
|
891
1141
|
const task = parseTaskJson(content);
|
|
892
1142
|
if (task)
|
|
893
1143
|
tasks.push(task);
|
|
@@ -907,9 +1157,9 @@ async function getQueueStats(taskDir) {
|
|
|
907
1157
|
corrupt: 0
|
|
908
1158
|
};
|
|
909
1159
|
for (const status of ["pending", "processing", "completed", "failed", "corrupt"]) {
|
|
910
|
-
const dir =
|
|
1160
|
+
const dir = path6.join(taskDir, status);
|
|
911
1161
|
try {
|
|
912
|
-
const files = await
|
|
1162
|
+
const files = await fs5.readdir(dir);
|
|
913
1163
|
stats[status] = files.filter((f) => f.endsWith(".json")).length;
|
|
914
1164
|
} catch {
|
|
915
1165
|
}
|
|
@@ -917,10 +1167,10 @@ async function getQueueStats(taskDir) {
|
|
|
917
1167
|
return stats;
|
|
918
1168
|
}
|
|
919
1169
|
async function listCorruptTaskFiles(taskDir, limit = 50, logger = nullLogger) {
|
|
920
|
-
const corruptDir =
|
|
1170
|
+
const corruptDir = path6.join(taskDir, "corrupt");
|
|
921
1171
|
let files;
|
|
922
1172
|
try {
|
|
923
|
-
files = await
|
|
1173
|
+
files = await fs5.readdir(corruptDir);
|
|
924
1174
|
} catch (err) {
|
|
925
1175
|
if (isNotFoundError2(err))
|
|
926
1176
|
return [];
|
|
@@ -928,9 +1178,9 @@ async function listCorruptTaskFiles(taskDir, limit = 50, logger = nullLogger) {
|
|
|
928
1178
|
}
|
|
929
1179
|
const entries = [];
|
|
930
1180
|
for (const fileName of files.filter((f) => f.endsWith(".json"))) {
|
|
931
|
-
const filePath =
|
|
1181
|
+
const filePath = path6.join(corruptDir, fileName);
|
|
932
1182
|
try {
|
|
933
|
-
const stat = await
|
|
1183
|
+
const stat = await fs5.stat(filePath);
|
|
934
1184
|
entries.push({
|
|
935
1185
|
fileName,
|
|
936
1186
|
size: stat.size,
|
|
@@ -947,7 +1197,7 @@ async function listCorruptTaskFiles(taskDir, limit = 50, logger = nullLogger) {
|
|
|
947
1197
|
return entries.slice(0, limit);
|
|
948
1198
|
}
|
|
949
1199
|
async function readSnippet(filePath, maxBytes) {
|
|
950
|
-
const handle = await
|
|
1200
|
+
const handle = await fs5.open(filePath, "r");
|
|
951
1201
|
try {
|
|
952
1202
|
const buffer = Buffer.alloc(maxBytes);
|
|
953
1203
|
const { bytesRead } = await handle.read(buffer, 0, maxBytes, 0);
|
|
@@ -970,7 +1220,7 @@ function parseTaskJson(content) {
|
|
|
970
1220
|
async function taskExistsIn(taskDir, taskId, subdirs) {
|
|
971
1221
|
for (const subdir of subdirs) {
|
|
972
1222
|
try {
|
|
973
|
-
await
|
|
1223
|
+
await fs5.stat(path6.join(taskDir, subdir, `${taskId}.json`));
|
|
974
1224
|
return true;
|
|
975
1225
|
} catch {
|
|
976
1226
|
}
|
|
@@ -978,13 +1228,13 @@ async function taskExistsIn(taskDir, taskId, subdirs) {
|
|
|
978
1228
|
return false;
|
|
979
1229
|
}
|
|
980
1230
|
async function moveToCorrupt(taskDir, sourceDir, fileName, reason, logger) {
|
|
981
|
-
const corruptDir =
|
|
1231
|
+
const corruptDir = path6.join(taskDir, "corrupt");
|
|
982
1232
|
try {
|
|
983
|
-
await
|
|
984
|
-
await
|
|
1233
|
+
await fs5.mkdir(corruptDir, { recursive: true });
|
|
1234
|
+
await fs5.rename(path6.join(sourceDir, fileName), path6.join(corruptDir, fileName));
|
|
985
1235
|
logger.debug("Moved corrupt task file", { fileName, reason });
|
|
986
1236
|
} catch {
|
|
987
|
-
await
|
|
1237
|
+
await fs5.unlink(path6.join(sourceDir, fileName)).catch(() => {
|
|
988
1238
|
});
|
|
989
1239
|
}
|
|
990
1240
|
}
|
|
@@ -1041,8 +1291,8 @@ var init_task_queue3 = __esm({
|
|
|
1041
1291
|
});
|
|
1042
1292
|
|
|
1043
1293
|
// dist/cli/init.js
|
|
1044
|
-
import
|
|
1045
|
-
import
|
|
1294
|
+
import fs6 from "node:fs/promises";
|
|
1295
|
+
import path7 from "node:path";
|
|
1046
1296
|
import * as p from "@clack/prompts";
|
|
1047
1297
|
import { createJiti } from "jiti";
|
|
1048
1298
|
|
|
@@ -1112,6 +1362,33 @@ var DevClientSafeStrategy = class {
|
|
|
1112
1362
|
|
|
1113
1363
|
// dist/operating-mode/client-unsafe-strategy.js
|
|
1114
1364
|
import path from "node:path";
|
|
1365
|
+
|
|
1366
|
+
// dist/utils/logger.js
|
|
1367
|
+
var active = console;
|
|
1368
|
+
function canopyLogWarn(...args) {
|
|
1369
|
+
active.warn(...args);
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
// dist/operating-mode/deployment-name.js
|
|
1373
|
+
var warned = false;
|
|
1374
|
+
var VALID_DEPLOYMENT_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
1375
|
+
var isValidDeploymentName = (name) => VALID_DEPLOYMENT_NAME.test(name) && !name.includes("..") && !name.endsWith(".") && !name.endsWith(".lock");
|
|
1376
|
+
function resolveDeploymentName(config, modeDefault) {
|
|
1377
|
+
const envValue = process.env.CANOPYCMS_DEPLOYMENT_NAME?.trim();
|
|
1378
|
+
const configValue = config.deploymentName;
|
|
1379
|
+
if (envValue && configValue && envValue !== configValue && !warned) {
|
|
1380
|
+
canopyLogWarn(`CanopyCMS: CANOPYCMS_DEPLOYMENT_NAME ("${envValue}") differs from config.deploymentName ("${configValue}") \u2014 using the env var (infra-stamped env wins over shared-repo config by design; see resolveDeploymentName's doc comment). Update config.deploymentName to match if this mismatch was unintentional.`);
|
|
1381
|
+
warned = true;
|
|
1382
|
+
}
|
|
1383
|
+
const resolved = envValue || configValue || modeDefault;
|
|
1384
|
+
if (!isValidDeploymentName(resolved)) {
|
|
1385
|
+
const source = envValue ? "CANOPYCMS_DEPLOYMENT_NAME" : configValue ? "config.deploymentName" : "the mode default";
|
|
1386
|
+
throw new Error(`CanopyCMS: invalid deploymentName ${JSON.stringify(resolved)} (from ${source}). It is interpolated into the settings branch name (canopycms-settings-<deploymentName>), so it must start with a letter or digit, contain only letters, digits, '.', '_' or '-', and must not contain '..' or end with '.' or '.lock'.`);
|
|
1387
|
+
}
|
|
1388
|
+
return resolved;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
// dist/operating-mode/client-unsafe-strategy.js
|
|
1115
1392
|
init_config2();
|
|
1116
1393
|
var ProdStrategy = class extends ProdClientSafeStrategy {
|
|
1117
1394
|
// All client-safe methods inherited automatically from ProdClientSafeStrategy:
|
|
@@ -1122,8 +1399,8 @@ var ProdStrategy = class extends ProdClientSafeStrategy {
|
|
|
1122
1399
|
getWorkspaceRoot(_sourceRoot) {
|
|
1123
1400
|
return path.resolve(process.env.CANOPYCMS_WORKSPACE_ROOT ?? DEFAULT_PROD_WORKSPACE);
|
|
1124
1401
|
}
|
|
1125
|
-
getContentRoot(sourceRoot) {
|
|
1126
|
-
return path.resolve(sourceRoot ?? process.cwd(),
|
|
1402
|
+
getContentRoot(contentRoot, sourceRoot) {
|
|
1403
|
+
return path.resolve(sourceRoot ?? process.cwd(), contentRoot);
|
|
1127
1404
|
}
|
|
1128
1405
|
getContentBranchesRoot(sourceRoot) {
|
|
1129
1406
|
return path.join(this.getWorkspaceRoot(sourceRoot), "content-branches");
|
|
@@ -1154,8 +1431,7 @@ var ProdStrategy = class extends ProdClientSafeStrategy {
|
|
|
1154
1431
|
getSettingsBranchName(config) {
|
|
1155
1432
|
if (config.settingsBranch)
|
|
1156
1433
|
return config.settingsBranch;
|
|
1157
|
-
|
|
1158
|
-
return `canopycms-settings-${deploymentName}`;
|
|
1434
|
+
return `canopycms-settings-${resolveDeploymentName(config, "prod")}`;
|
|
1159
1435
|
}
|
|
1160
1436
|
getSettingsRoot(sourceRoot) {
|
|
1161
1437
|
return path.join(this.getWorkspaceRoot(sourceRoot), "settings");
|
|
@@ -1177,8 +1453,8 @@ var DevStrategy = class extends DevClientSafeStrategy {
|
|
|
1177
1453
|
getWorkspaceRoot(sourceRoot) {
|
|
1178
1454
|
return path.resolve(sourceRoot ?? process.cwd(), ".canopy-dev");
|
|
1179
1455
|
}
|
|
1180
|
-
getContentRoot(sourceRoot) {
|
|
1181
|
-
return path.resolve(sourceRoot ?? process.cwd(),
|
|
1456
|
+
getContentRoot(contentRoot, sourceRoot) {
|
|
1457
|
+
return path.resolve(sourceRoot ?? process.cwd(), contentRoot);
|
|
1182
1458
|
}
|
|
1183
1459
|
getContentBranchesRoot(sourceRoot) {
|
|
1184
1460
|
return path.join(this.getWorkspaceRoot(sourceRoot), "content-branches");
|
|
@@ -1208,8 +1484,7 @@ var DevStrategy = class extends DevClientSafeStrategy {
|
|
|
1208
1484
|
getSettingsBranchName(config) {
|
|
1209
1485
|
if (config.settingsBranch)
|
|
1210
1486
|
return config.settingsBranch;
|
|
1211
|
-
|
|
1212
|
-
return `canopycms-settings-${deploymentName}`;
|
|
1487
|
+
return `canopycms-settings-${resolveDeploymentName(config, "local")}`;
|
|
1213
1488
|
}
|
|
1214
1489
|
getSettingsRoot(sourceRoot) {
|
|
1215
1490
|
return path.join(this.getWorkspaceRoot(sourceRoot), "settings");
|
|
@@ -1252,41 +1527,11 @@ function assertAuthPluginAllowedForMode(plugin, mode) {
|
|
|
1252
1527
|
}
|
|
1253
1528
|
}
|
|
1254
1529
|
|
|
1255
|
-
// dist/utils/fs.js
|
|
1256
|
-
import fs from "node:fs/promises";
|
|
1257
|
-
|
|
1258
|
-
// dist/utils/error.js
|
|
1259
|
-
function getErrorMessage(err) {
|
|
1260
|
-
if (err instanceof Error) {
|
|
1261
|
-
return err.message;
|
|
1262
|
-
}
|
|
1263
|
-
if (typeof err === "string") {
|
|
1264
|
-
return err;
|
|
1265
|
-
}
|
|
1266
|
-
return String(err);
|
|
1267
|
-
}
|
|
1268
|
-
function isNodeError(err) {
|
|
1269
|
-
return err instanceof Error && "code" in err;
|
|
1270
|
-
}
|
|
1271
|
-
function isNotFoundError(err) {
|
|
1272
|
-
return isNodeError(err) && err.code === "ENOENT";
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
// dist/utils/fs.js
|
|
1276
|
-
async function filePathExists(filePath) {
|
|
1277
|
-
try {
|
|
1278
|
-
await fs.stat(filePath);
|
|
1279
|
-
return true;
|
|
1280
|
-
} catch (err) {
|
|
1281
|
-
if (isNotFoundError(err))
|
|
1282
|
-
return false;
|
|
1283
|
-
throw err;
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
1530
|
// dist/cli/init.js
|
|
1531
|
+
init_fs();
|
|
1532
|
+
init_error();
|
|
1288
1533
|
async function writeFile(filePath, content, options) {
|
|
1289
|
-
const relativePath =
|
|
1534
|
+
const relativePath = path7.relative(process.cwd(), filePath);
|
|
1290
1535
|
if (await filePathExists(filePath)) {
|
|
1291
1536
|
if (options.force) {
|
|
1292
1537
|
} else if (options.nonInteractive) {
|
|
@@ -1303,8 +1548,8 @@ async function writeFile(filePath, content, options) {
|
|
|
1303
1548
|
}
|
|
1304
1549
|
}
|
|
1305
1550
|
}
|
|
1306
|
-
await
|
|
1307
|
-
await
|
|
1551
|
+
await fs6.mkdir(path7.dirname(filePath), { recursive: true });
|
|
1552
|
+
await fs6.writeFile(filePath, content, "utf-8");
|
|
1308
1553
|
p.log.success(`created: ${relativePath}`);
|
|
1309
1554
|
return true;
|
|
1310
1555
|
}
|
|
@@ -1356,24 +1601,24 @@ async function init(options) {
|
|
|
1356
1601
|
}
|
|
1357
1602
|
const serverPageExt = staticBuild ? "page.server.tsx" : "page.tsx";
|
|
1358
1603
|
const serverRouteExt = staticBuild ? "route.server.ts" : "route.ts";
|
|
1359
|
-
await writeFile(
|
|
1360
|
-
await writeFile(
|
|
1361
|
-
await writeFile(
|
|
1362
|
-
await writeFile(
|
|
1604
|
+
await writeFile(path7.join(projectDir, "canopycms.config.ts"), await canopyCmsConfig2({ mode, staticBuild }), writeOpts);
|
|
1605
|
+
await writeFile(path7.join(projectDir, appDir, "lib/canopy.ts"), await canopyContext2({ configImport: configImportPath(appDir, 1), authProvider }), writeOpts);
|
|
1606
|
+
await writeFile(path7.join(projectDir, appDir, "schemas.ts"), await schemasTemplate2(), writeOpts);
|
|
1607
|
+
await writeFile(path7.join(projectDir, appDir, `api/canopycms/[...canopycms]/${serverRouteExt}`), await apiRoute2({
|
|
1363
1608
|
canopyImport: "../".repeat(3) + "lib/canopy"
|
|
1364
1609
|
}), writeOpts);
|
|
1365
|
-
await writeFile(
|
|
1610
|
+
await writeFile(path7.join(projectDir, appDir, `edit/${serverPageExt}`), await editPage2({ configImport: configImportPath(appDir, 1), authProvider }), writeOpts);
|
|
1366
1611
|
if (ai) {
|
|
1367
|
-
await writeFile(
|
|
1368
|
-
await writeFile(
|
|
1612
|
+
await writeFile(path7.join(projectDir, appDir, "ai/config.ts"), await aiConfig2(), writeOpts);
|
|
1613
|
+
await writeFile(path7.join(projectDir, appDir, `ai/[...path]/${serverRouteExt}`), await aiRoute2({ configImport: configImportPath(appDir, 2) }), writeOpts);
|
|
1369
1614
|
}
|
|
1370
|
-
await writeFile(
|
|
1371
|
-
await writeFile(
|
|
1372
|
-
const gitignorePath =
|
|
1615
|
+
await writeFile(path7.join(projectDir, "next.config.ts"), await nextConfig2({ staticBuild }), writeOpts);
|
|
1616
|
+
await writeFile(path7.join(projectDir, "middleware.ts"), await middleware2({ authProvider }), writeOpts);
|
|
1617
|
+
const gitignorePath = path7.join(projectDir, ".gitignore");
|
|
1373
1618
|
if (await filePathExists(gitignorePath)) {
|
|
1374
|
-
const content = await
|
|
1619
|
+
const content = await fs6.readFile(gitignorePath, "utf-8");
|
|
1375
1620
|
if (!content.includes(".canopy-dev")) {
|
|
1376
|
-
await
|
|
1621
|
+
await fs6.appendFile(gitignorePath, "\n# CanopyCMS\n.canopy-dev/\n");
|
|
1377
1622
|
p.log.success("updated: .gitignore");
|
|
1378
1623
|
}
|
|
1379
1624
|
}
|
|
@@ -1398,34 +1643,78 @@ async function init(options) {
|
|
|
1398
1643
|
async function initDeployAws(options) {
|
|
1399
1644
|
const { projectDir, force, nonInteractive } = options;
|
|
1400
1645
|
const writeOpts = { force, nonInteractive };
|
|
1401
|
-
const { dockerfileCms: dockerfileCms2, dockerignore: dockerignore2, githubWorkflowCms: githubWorkflowCms2 } = await Promise.resolve().then(() => (init_templates(), templates_exports));
|
|
1646
|
+
const { dockerfileCms: dockerfileCms2, dockerignore: dockerignore2, githubWorkflowCms: githubWorkflowCms2, cdkJson: cdkJson2, cdkApp: cdkApp2, cmsStack: cmsStack2 } = await Promise.resolve().then(() => (init_templates(), templates_exports));
|
|
1647
|
+
const { detectPackageManager: detectPackageManager2, detectDefaultBranch: detectDefaultBranch2, detectGitHubRepo: detectGitHubRepo2, commandsFor: commandsFor2, missingCdkDependencies: missingCdkDependencies2, CDK_DEPENDENCIES: CDK_DEPENDENCIES2 } = await Promise.resolve().then(() => (init_project_detect(), project_detect_exports));
|
|
1402
1648
|
p.intro("CanopyCMS init-deploy aws");
|
|
1403
|
-
|
|
1404
|
-
const
|
|
1649
|
+
const packageManager = await detectPackageManager2(projectDir);
|
|
1650
|
+
const pm = commandsFor2(packageManager);
|
|
1651
|
+
const defaultBranch = await detectDefaultBranch2(projectDir);
|
|
1652
|
+
const repo = await detectGitHubRepo2(projectDir);
|
|
1653
|
+
await writeFile(path7.join(projectDir, "Dockerfile.cms"), await dockerfileCms2({ copy: pm.dockerCopy, install: pm.dockerInstall, build: pm.build }), writeOpts);
|
|
1654
|
+
const dockerignoreWritten = await writeFile(path7.join(projectDir, ".dockerignore"), await dockerignore2(), writeOpts);
|
|
1405
1655
|
if (!dockerignoreWritten) {
|
|
1406
|
-
p.log.warn("Existing .dockerignore kept \u2014 verify it excludes .env* (secrets would otherwise enter the build context) and does NOT exclude vendor/ (needed
|
|
1656
|
+
p.log.warn("Existing .dockerignore kept \u2014 verify it excludes .env* (secrets would otherwise enter the build context) and does NOT exclude vendor/ (needed by the Dockerfile.cms install step with file: deps).");
|
|
1657
|
+
}
|
|
1658
|
+
await writeFile(path7.join(projectDir, ".github/workflows/deploy-cms.yml"), await githubWorkflowCms2({
|
|
1659
|
+
defaultBranch,
|
|
1660
|
+
lockfile: pm.lockfile,
|
|
1661
|
+
ciInstall: pm.ciInstall,
|
|
1662
|
+
addDev: pm.addDev
|
|
1663
|
+
}), writeOpts);
|
|
1664
|
+
const cdkJsonPath = path7.join(projectDir, "cdk.json");
|
|
1665
|
+
const existingCdkJson = await filePathExists(cdkJsonPath) ? await fs6.readFile(cdkJsonPath, "utf-8") : null;
|
|
1666
|
+
const cdkJsonWritten = await writeFile(cdkJsonPath, await cdkJson2(), writeOpts);
|
|
1667
|
+
await writeFile(path7.join(projectDir, "infrastructure/bin/app.ts"), await cdkApp2({
|
|
1668
|
+
githubOwner: repo?.owner ?? "your-org",
|
|
1669
|
+
githubRepo: repo?.repo ?? "your-docs-site"
|
|
1670
|
+
}), writeOpts);
|
|
1671
|
+
await writeFile(path7.join(projectDir, "infrastructure/lib/cms-stack.ts"), await cmsStack2(), writeOpts);
|
|
1672
|
+
if (!cdkJsonWritten && existingCdkJson && !existingCdkJson.includes("infrastructure/bin/app.ts")) {
|
|
1673
|
+
p.log.warn("Existing cdk.json kept, and it does not point at infrastructure/bin/app.ts \u2014 the scaffolded CDK app will not be deployed. Either wire CmsStack into your own app entry point, or re-run with --force to replace cdk.json.");
|
|
1407
1674
|
}
|
|
1408
|
-
|
|
1409
|
-
const
|
|
1410
|
-
const nextConfigMjsPath = path6.join(projectDir, "next.config.mjs");
|
|
1675
|
+
const nextConfigPath = path7.join(projectDir, "next.config.ts");
|
|
1676
|
+
const nextConfigMjsPath = path7.join(projectDir, "next.config.mjs");
|
|
1411
1677
|
const configPath = await filePathExists(nextConfigPath) ? nextConfigPath : await filePathExists(nextConfigMjsPath) ? nextConfigMjsPath : null;
|
|
1412
1678
|
if (configPath) {
|
|
1413
|
-
const content = await
|
|
1679
|
+
const content = await fs6.readFile(configPath, "utf-8");
|
|
1414
1680
|
if (!content.includes("CANOPY_BUILD")) {
|
|
1415
1681
|
p.note([
|
|
1416
|
-
`Add dual build support to ${
|
|
1682
|
+
`Add dual build support to ${path7.basename(configPath)}:`,
|
|
1417
1683
|
"",
|
|
1418
1684
|
" output: process.env.CANOPY_BUILD === 'cms' ? 'standalone' : 'export',"
|
|
1419
1685
|
].join("\n"), "Manual step");
|
|
1420
1686
|
}
|
|
1421
1687
|
}
|
|
1422
|
-
|
|
1688
|
+
if (packageManager === "yarn" || packageManager === "yarn-berry") {
|
|
1689
|
+
p.log.warn(`Yarn detected (${packageManager === "yarn-berry" ? "Berry" : "classic"}). The generated install lines are a best effort and are not exercised by CanopyCMS tests \u2014 review them in Dockerfile.cms and .github/workflows/deploy-cms.yml.` + (packageManager === "yarn-berry" ? " Berry additionally requires nodeLinker: node-modules; PnP is incompatible with Next.js standalone output, which the CMS image's runner stage copies." : ""));
|
|
1690
|
+
}
|
|
1691
|
+
const missing = await missingCdkDependencies2(projectDir);
|
|
1692
|
+
if (missing.length > 0) {
|
|
1693
|
+
p.log.warn(`Not installed: ${missing.join(", ")}. cdk.json runs \`node --import tsx infrastructure/bin/app.ts\`, so the deploy fails without them:
|
|
1694
|
+
${pm.addDev} ${CDK_DEPENDENCIES2.join(" ")}`);
|
|
1695
|
+
}
|
|
1696
|
+
p.note([
|
|
1697
|
+
"1. Install the CDK dependencies (if you have not already):",
|
|
1698
|
+
` ${pm.addDev} ${CDK_DEPENDENCIES2.join(" ")}`,
|
|
1699
|
+
"",
|
|
1700
|
+
"2. Fill in infrastructure/lib/cms-stack.ts and infrastructure/bin/app.ts",
|
|
1701
|
+
` (worker repo currently set to ${repo ? `${repo.owner}/${repo.repo}` : "your-org/your-docs-site"})`,
|
|
1702
|
+
"",
|
|
1703
|
+
"3. Bootstrap CDK in the target account/region: cdk bootstrap",
|
|
1704
|
+
"",
|
|
1705
|
+
"4. Set the repository secrets and variables listed at the top of",
|
|
1706
|
+
" .github/workflows/deploy-cms.yml \u2014 the deploy fails at synth without them.",
|
|
1707
|
+
"",
|
|
1708
|
+
`Deploys trigger on pushes to '${defaultBranch}'; edit the workflow to change that.`,
|
|
1709
|
+
"",
|
|
1710
|
+
"Full walkthrough: docs/deploying-to-aws.md"
|
|
1711
|
+
].join("\n"), "AWS deployment");
|
|
1423
1712
|
p.outro("Done!");
|
|
1424
1713
|
}
|
|
1425
1714
|
async function detectMode(projectDir) {
|
|
1426
|
-
const cfgPath =
|
|
1715
|
+
const cfgPath = path7.join(projectDir, "canopycms.config.ts");
|
|
1427
1716
|
try {
|
|
1428
|
-
await
|
|
1717
|
+
await fs6.stat(cfgPath);
|
|
1429
1718
|
} catch (err) {
|
|
1430
1719
|
if (isNotFoundError(err))
|
|
1431
1720
|
return "dev";
|
|
@@ -1456,7 +1745,7 @@ async function workerRunOnce(options) {
|
|
|
1456
1745
|
assertAuthPluginAllowedForMode(options.authPlugin, mode);
|
|
1457
1746
|
}
|
|
1458
1747
|
const taskDir = getTaskQueueDir2({ mode });
|
|
1459
|
-
const cachePath = process.env.CANOPY_AUTH_CACHE_PATH ??
|
|
1748
|
+
const cachePath = process.env.CANOPY_AUTH_CACHE_PATH ?? path7.join(operatingStrategy(mode).getWorkspaceRoot(options.projectDir), ".cache");
|
|
1460
1749
|
let refreshAuthCache;
|
|
1461
1750
|
const authMode = process.env.CANOPY_AUTH_MODE || "dev";
|
|
1462
1751
|
if (options.authPlugin?.createCacheRefresher) {
|