@sandboxsonny/ace-kit 0.4.0 → 0.6.0
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/CHANGELOG.md +17 -0
- package/README.md +1 -1
- package/dist/astro-integration.d.ts +3 -3
- package/dist/astro-integration.js +7 -4
- package/dist/chunk-7M26C36M.js +35 -0
- package/dist/{chunk-O3NAJNUN.js → chunk-G5FGBOFT.js} +7 -7
- package/dist/chunk-N5DIMG3X.js +16 -0
- package/dist/cli.js +14 -1169
- package/dist/environment-T5K5ZJ2M.js +222 -0
- package/dist/main-YRQQWLHX.js +1454 -0
- package/dist/react-router-server.js +3 -2
- package/dist/vite.js +2 -1
- package/docs/astro.md +12 -6
- package/docs/command-line.md +34 -5
- package/docs/dev-sites.md +2 -2
- package/docs/getting-started.md +8 -0
- package/docs/react-router.md +7 -5
- package/docs/sections.md +1 -1
- package/docs/typed-content.md +3 -3
- package/package.json +5 -2
- package/templates/astro/.dockerignore +7 -0
- package/templates/astro/.github/dependabot.yml +19 -0
- package/templates/astro/.github/workflows/ci.yml +23 -0
- package/templates/astro/.prettierignore +6 -0
- package/templates/astro/.prettierrc.json +20 -0
- package/templates/astro/.vscode/extensions.json +4 -0
- package/templates/astro/.vscode/launch.json +11 -0
- package/templates/astro/AGENTS.md +22 -0
- package/templates/astro/Dockerfile +17 -0
- package/templates/astro/_gitignore +26 -0
- package/templates/astro/astro.config.mjs +18 -0
- package/templates/astro/eslint.config.js +56 -0
- package/templates/astro/package.json +41 -0
- package/templates/astro/public/favicon.ico +0 -0
- package/templates/astro/public/favicon.svg +9 -0
- package/templates/astro/src/ace-kit.generated.d.ts +24 -0
- package/templates/astro/src/components/PageContent.astro +113 -0
- package/templates/astro/src/components/SiteFooter.astro +19 -0
- package/templates/astro/src/components/SiteHeader.astro +121 -0
- package/templates/astro/src/components/sections/Faq.astro +54 -0
- package/templates/astro/src/components/sections/Faq.schema.ts +17 -0
- package/templates/astro/src/components/sections/Gallery.astro +74 -0
- package/templates/astro/src/components/sections/Gallery.schema.ts +20 -0
- package/templates/astro/src/components/sections/Hero.astro +58 -0
- package/templates/astro/src/components/sections/Hero.schema.ts +14 -0
- package/templates/astro/src/layouts/BaseLayout.astro +36 -0
- package/templates/astro/src/pages/[...slug].astro +31 -0
- package/templates/astro/src/styles/global.css +56 -0
- package/templates/astro/src/types/page.d.ts +4 -0
- package/templates/astro/tsconfig.json +11 -0
- package/templates/astro/vitest.config.ts +4 -0
- package/templates/astro.section-types.json +109 -0
- package/templates/react-router/.prettierignore +5 -0
- package/templates/react-router/.prettierrc.json +11 -0
- package/templates/react-router/_gitignore +7 -0
- package/templates/react-router/app/ace-kit.generated.d.ts +18 -0
- package/templates/react-router/app/app.css +172 -0
- package/templates/react-router/app/components/page-content.tsx +32 -0
- package/templates/react-router/app/components/site-footer.tsx +9 -0
- package/templates/react-router/app/components/site-header.tsx +49 -0
- package/templates/react-router/app/entry.server.tsx +1 -0
- package/templates/react-router/app/root.tsx +75 -0
- package/templates/react-router/app/routes/page.test.tsx +64 -0
- package/templates/react-router/app/routes/page.tsx +22 -0
- package/templates/react-router/app/routes.ts +4 -0
- package/templates/react-router/app/types/page.d.ts +4 -0
- package/templates/react-router/eslint.config.js +76 -0
- package/templates/react-router/package.json +51 -0
- package/templates/react-router/public/favicon.svg +9 -0
- package/templates/react-router/react-router.config.ts +6 -0
- package/templates/react-router/tsconfig.json +22 -0
- package/templates/react-router/vite.config.ts +10 -0
- package/templates/react-router/vitest.config.ts +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @sandboxsonny/ace-kit
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6235a3b: Add `ace-kit create <folder> <domain>`: signs you in, makes the site in CMS Ace with starter content (a Pages type, Home, About and Contact, a main menu and example sections), and copies an Astro or React Router starter into the folder (`--framework`, `--name`). Needs a CMS Ace that lets a command-line login set up the site it just made.
|
|
8
|
+
|
|
9
|
+
## 0.5.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 88e17be: CMS Ace is a hosted platform, so a site no longer has to say where it is.
|
|
14
|
+
|
|
15
|
+
- `ACE_API_URL` now defaults to `https://api.ace-cms.co.uk` and `ACE_PREVIEW_ADMIN_ORIGIN` to `https://app.ace-cms.co.uk` (the Astro integration, the React Router adapter and the command line). **If you develop against a CMS on your own machine, set `ACE_API_URL=http://localhost:8080` and `ACE_PREVIEW_ADMIN_ORIGIN=http://localhost:5173` in `.env`**, where before they were the defaults.
|
|
16
|
+
- A site names itself with Astro's own `site` setting (`site: "https://www.example.com"`, or `astro dev --site https://www.example.com`). `ACE_SITE_DOMAIN`, when set, still wins.
|
|
17
|
+
- `ace-kit sync` and `ace-kit generate` take `--site example.com` (a domain or a web address); `--domain` still works.
|
|
18
|
+
- `ace-kit login` and `whoami` need no flags: with no address given they use the hosted CMS Ace.
|
|
19
|
+
|
|
3
20
|
## 0.4.0
|
|
4
21
|
|
|
5
22
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ const page = await loadPage(cms, { slug: "pages/about", url: new URL(request.url
|
|
|
24
24
|
if (page.kind === "entry") console.log(page.entry.title, page.entry.values);
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
On Astro there is nothing to wire up by hand: add the integration to `astro.config.mjs` (`integrations: [ace()]`), set `
|
|
27
|
+
On Astro there is nothing to wire up by hand: add the integration to `astro.config.mjs` (`integrations: [ace()]`), set your site's domain (`site: "https://www.example.com"` in the Astro config, or `ACE_SITE_DOMAIN`), and read the CMS straight from a page:
|
|
28
28
|
|
|
29
29
|
```astro
|
|
30
30
|
---
|
|
@@ -13,9 +13,9 @@ import { AstroIntegration } from 'astro';
|
|
|
13
13
|
*
|
|
14
14
|
* | Setting | Default | Meaning |
|
|
15
15
|
* | -------------------------- | ----------------------- | -------------------------------------------------------- |
|
|
16
|
-
* | `ACE_API_URL` | `
|
|
17
|
-
* | `ACE_SITE_DOMAIN` | `localhost`
|
|
18
|
-
* | `ACE_PREVIEW_ADMIN_ORIGIN` | `
|
|
16
|
+
* | `ACE_API_URL` | `https://api.ace-cms.co.uk` | where the CMS Ace API lives (set it for a CMS on your machine) |
|
|
17
|
+
* | `ACE_SITE_DOMAIN` | the host of Astro's `site` setting, else `localhost` | the domain this site has in the CMS |
|
|
18
|
+
* | `ACE_PREVIEW_ADMIN_ORIGIN` | `https://app.ace-cms.co.uk` | where the CMS admin app runs (may frame the site) |
|
|
19
19
|
*/
|
|
20
20
|
declare function ace(): AstroIntegration;
|
|
21
21
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { startDevSite, sectionSync } from './chunk-
|
|
1
|
+
import { startDevSite, sectionSync } from './chunk-G5FGBOFT.js';
|
|
2
|
+
import { domainFromSite, hostedAdminOrigin, hostedApiUrl } from './chunk-N5DIMG3X.js';
|
|
2
3
|
import { envField } from 'astro/config';
|
|
3
4
|
import { fileURLToPath } from 'url';
|
|
4
5
|
|
|
@@ -8,10 +9,12 @@ function ace() {
|
|
|
8
9
|
name: "ace-kit",
|
|
9
10
|
hooks: {
|
|
10
11
|
"astro:config:setup": async ({ command, config, logger, updateConfig, addMiddleware }) => {
|
|
12
|
+
const siteDomain = config.site ? domainFromSite(config.site) : "localhost";
|
|
11
13
|
if (command === "dev") {
|
|
12
14
|
devSite = await startDevSite({
|
|
13
15
|
root: fileURLToPath(config.root),
|
|
14
16
|
mode: "development",
|
|
17
|
+
siteDomain,
|
|
15
18
|
log: { info: (text) => logger.info(text), warn: (text) => logger.warn(text) }
|
|
16
19
|
});
|
|
17
20
|
}
|
|
@@ -19,12 +22,12 @@ function ace() {
|
|
|
19
22
|
env: {
|
|
20
23
|
schema: {
|
|
21
24
|
// "secret" only because Astro reads secrets when the server starts, while "public" values are baked into the build.
|
|
22
|
-
ACE_API_URL: envField.string({ context: "server", access: "secret", default:
|
|
23
|
-
ACE_SITE_DOMAIN: envField.string({ context: "server", access: "secret", default:
|
|
25
|
+
ACE_API_URL: envField.string({ context: "server", access: "secret", default: hostedApiUrl }),
|
|
26
|
+
ACE_SITE_DOMAIN: envField.string({ context: "server", access: "secret", default: siteDomain }),
|
|
24
27
|
ACE_PREVIEW_ADMIN_ORIGIN: envField.string({
|
|
25
28
|
context: "server",
|
|
26
29
|
access: "secret",
|
|
27
|
-
default:
|
|
30
|
+
default: hostedAdminOrigin
|
|
28
31
|
})
|
|
29
32
|
}
|
|
30
33
|
},
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/auth/login-store.ts
|
|
4
|
+
function normaliseApiUrl(address) {
|
|
5
|
+
let parsed;
|
|
6
|
+
try {
|
|
7
|
+
parsed = new URL(address.trim());
|
|
8
|
+
} catch {
|
|
9
|
+
throw new Error(`"${address}" is not a web address. Write the API address like http://localhost:8080.`);
|
|
10
|
+
}
|
|
11
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
12
|
+
throw new Error(`The API address must start with http:// or https:// (it was "${address}").`);
|
|
13
|
+
}
|
|
14
|
+
if (parsed.username || parsed.password) {
|
|
15
|
+
throw new Error("The API address must not contain a username or password.");
|
|
16
|
+
}
|
|
17
|
+
return `${parsed.origin}${parsed.pathname.replace(/\/+$/, "")}`;
|
|
18
|
+
}
|
|
19
|
+
function hasExpired(login, now) {
|
|
20
|
+
const endsAt = Date.parse(login.expiresAt);
|
|
21
|
+
return Number.isNaN(endsAt) || endsAt <= now;
|
|
22
|
+
}
|
|
23
|
+
function parseStoredLogin(value) {
|
|
24
|
+
if (typeof value !== "object" || value === null) return null;
|
|
25
|
+
const { token, expiresAt, email } = value;
|
|
26
|
+
if (typeof token !== "string" || token === "" || typeof expiresAt !== "string" || typeof email !== "string")
|
|
27
|
+
return null;
|
|
28
|
+
return { token, expiresAt, email };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
normaliseApiUrl,
|
|
33
|
+
hasExpired,
|
|
34
|
+
parseStoredLogin
|
|
35
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { hostedApiUrl } from './chunk-N5DIMG3X.js';
|
|
1
2
|
import { loadEnv } from 'vite';
|
|
2
3
|
import { readdir, readFile, mkdir, writeFile, rename } from 'fs/promises';
|
|
3
4
|
import { homedir } from 'os';
|
|
@@ -5,8 +6,6 @@ import { join, relative, dirname } from 'path';
|
|
|
5
6
|
import { spawn } from 'child_process';
|
|
6
7
|
import { fileURLToPath } from 'url';
|
|
7
8
|
|
|
8
|
-
// src/dev-site/start-dev-site.ts
|
|
9
|
-
|
|
10
9
|
// src/auth/login-store.ts
|
|
11
10
|
function normaliseApiUrl(address) {
|
|
12
11
|
let parsed;
|
|
@@ -282,18 +281,19 @@ async function prepareDevSite(options) {
|
|
|
282
281
|
}
|
|
283
282
|
|
|
284
283
|
// src/dev-site/start-dev-site.ts
|
|
285
|
-
var defaultApiUrl = "http://localhost:8080";
|
|
286
284
|
async function startDevSite(options) {
|
|
287
285
|
const { root, mode, log } = options;
|
|
288
286
|
if (mode === "test" || process.env.VITEST) return null;
|
|
289
|
-
const
|
|
287
|
+
const base = options.environment?.variables ?? { ...loadEnv(mode, root, "ACE_"), ...process.env };
|
|
288
|
+
const realDomain = base.ACE_SITE_DOMAIN?.trim() || options.siteDomain?.trim() || "localhost";
|
|
289
|
+
const variables = { ...base, ACE_SITE_DOMAIN: realDomain };
|
|
290
290
|
let apiUrl;
|
|
291
291
|
try {
|
|
292
|
-
apiUrl = normaliseApiUrl(variables.ACE_API_URL ??
|
|
292
|
+
apiUrl = normaliseApiUrl(variables.ACE_API_URL ?? hostedApiUrl);
|
|
293
293
|
} catch {
|
|
294
294
|
return null;
|
|
295
295
|
}
|
|
296
|
-
const environment = options.environment
|
|
296
|
+
const environment = options.environment ? { ...options.environment, variables } : {
|
|
297
297
|
variables,
|
|
298
298
|
store: await chooseLoginStore({ platform: process.platform, variables, run: runCommand }),
|
|
299
299
|
now: Date.now,
|
|
@@ -317,7 +317,7 @@ async function startDevSite(options) {
|
|
|
317
317
|
log.info(
|
|
318
318
|
outcome.created ? `Made you a dev site, "${outcome.site.name}", as a copy of the live site (${outcome.site.domain}). This dev server reads and syncs to it; the live site is not touched.` : `Using your dev site, "${outcome.site.name}" (${outcome.site.domain}). The live site is not touched.`
|
|
319
319
|
);
|
|
320
|
-
const siteDomain =
|
|
320
|
+
const siteDomain = realDomain;
|
|
321
321
|
return {
|
|
322
322
|
domain: outcome.site.domain,
|
|
323
323
|
setPreviewUrl: async (previewUrl) => {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/helpers/platform.ts
|
|
2
|
+
var hostedApiUrl = "https://api.ace-cms.co.uk";
|
|
3
|
+
var hostedAdminOrigin = "https://app.ace-cms.co.uk";
|
|
4
|
+
function domainFromSite(site) {
|
|
5
|
+
const trimmed = site.trim();
|
|
6
|
+
if (trimmed.includes("://")) {
|
|
7
|
+
try {
|
|
8
|
+
return new URL(trimmed).hostname.toLowerCase();
|
|
9
|
+
} catch {
|
|
10
|
+
return trimmed.toLowerCase();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return trimmed.replace(/\/.*$/, "").replace(/:\d+$/, "").toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { domainFromSite, hostedAdminOrigin, hostedApiUrl };
|