pagewrite-astro 0.1.7
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/CLI.md +100 -0
- package/README.md +143 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +138 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +17 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +164 -0
- package/dist/client.js.map +1 -0
- package/dist/frontmatter.d.ts +3 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +76 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/fs.d.ts +3 -0
- package/dist/fs.d.ts.map +1 -0
- package/dist/fs.js +8 -0
- package/dist/fs.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/token.d.ts +4 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +22 -0
- package/dist/token.js.map +1 -0
- package/dist/types.d.ts +83 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +96 -0
- package/dist/utils.js.map +1 -0
- package/package.json +52 -0
package/CLI.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Pagewrite Content CLI
|
|
2
|
+
|
|
3
|
+
`pagewrite-astro` fetches Pagewrite CMS content without running an Astro build. Use it in CI, predeploy steps, or local checks when you want MDX files written into an Astro content directory ahead of time.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
The CLI is included with `@lakshmanshankar/pagwrite-astro`:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @lakshmanshankar/pagwrite-astro
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
After installation, run it through your package manager:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm pagewrite-astro --help
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Authentication
|
|
20
|
+
|
|
21
|
+
Pass the build token directly using the `--token` option:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pagewrite-astro fetch --site-id your-site-id --token rmx_live_xxxxxxxxxxxx
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pagewrite-astro fetch --site-id <siteId> [options]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The `fetch` command stages the site content by fetching the static file tree and paginated file documents, adding `title` and `slug` frontmatter, and writing `.mdx` files to the output directory.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pagewrite-astro fetch --site-id your-site-id --out src/content/docs
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Options
|
|
40
|
+
|
|
41
|
+
| Option | Default | Description |
|
|
42
|
+
| ------ | ------- | ----------- |
|
|
43
|
+
| `--site-id <id>` | required | Pagewrite site id to fetch. |
|
|
44
|
+
| `--out <dir>` | `src/content/docs` | Output directory for generated MDX files. |
|
|
45
|
+
| `--output-dir <dir>` | `src/content/docs` | Alias for `--out`. |
|
|
46
|
+
| `--token <token>` | required | Build token value. |
|
|
47
|
+
| `--clean` | `false` | Remove the output directory before writing files. |
|
|
48
|
+
| `--dry-run` | `false` | Fetch and validate content, then remove temporary output. |
|
|
49
|
+
| `--page-size <number>` | `100` | File document page size. |
|
|
50
|
+
| `--timeout-ms <number>` | `30000` | Request timeout in milliseconds. |
|
|
51
|
+
| `-h`, `--help` | none | Show CLI help. |
|
|
52
|
+
|
|
53
|
+
## Examples
|
|
54
|
+
|
|
55
|
+
Fetch content into the default Astro content directory:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pagewrite-astro fetch --site-id your-site-id
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Fetch into a custom collection directory:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pagewrite-astro fetch --site-id your-site-id --out src/content/blog
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Clean the target directory before writing fresh content:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pagewrite-astro fetch --site-id your-site-id --out src/content/docs --clean
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
Validate remote content without keeping files on disk:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pagewrite-astro fetch --site-id your-site-id --dry-run
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## CI Integration
|
|
81
|
+
|
|
82
|
+
Run the CLI before your framework build:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"scripts": {
|
|
87
|
+
"content:fetch": "pagewrite-astro fetch --site-id $PAGEWRITE_SITE_ID --token $PAGEWRITE_BUILD_TOKEN --out src/content/docs --clean",
|
|
88
|
+
"prebuild": "pnpm content:fetch",
|
|
89
|
+
"build": "astro build"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Make sure `PAGEWRITE_BUILD_TOKEN` and `PAGEWRITE_SITE_ID` are configured as CI secrets or environment variables.
|
|
95
|
+
|
|
96
|
+
## Notes
|
|
97
|
+
|
|
98
|
+
- Build tokens should be read-only and scoped to fetch site content.
|
|
99
|
+
- `--clean` is ignored during `--dry-run`; dry runs write to a temporary directory and remove it afterward.
|
|
100
|
+
- Unsafe absolute paths and path traversal entries from the remote file tree are rejected before files are written.
|
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# @lakshmanshankar/pagwrite-astro
|
|
2
|
+
|
|
3
|
+
Astro integration for fetching Pagewrite CMS content at build time and writing it as MDX files into your Astro content directory.
|
|
4
|
+
|
|
5
|
+
This package is currently focused on the Astro fetch/write integration. The lower-level fetch and staging functions are exported so they can later be reused by another adapter, such as Next.js or Fumadocs.
|
|
6
|
+
|
|
7
|
+
## How It Works
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
Pagewrite CMS User's Astro project
|
|
11
|
+
------------- --------------------
|
|
12
|
+
siteId, token ---> @lakshmanshankar/pagwrite-astro config
|
|
13
|
+
|
|
|
14
|
+
v
|
|
15
|
+
astro build
|
|
16
|
+
|
|
|
17
|
+
v
|
|
18
|
+
fetch static file tree
|
|
19
|
+
fetch paginated file documents
|
|
20
|
+
|
|
|
21
|
+
v
|
|
22
|
+
src/content/docs/*.mdx
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add @lakshmanshankar/pagwrite-astro
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Setup
|
|
32
|
+
|
|
33
|
+
Configure the integration before content-related integrations in `astro.config.mjs`:
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
import { defineConfig } from "astro/config";
|
|
37
|
+
import mdx from "@astrojs/mdx";
|
|
38
|
+
import pagewriteAstro from "@lakshmanshankar/pagwrite-astro";
|
|
39
|
+
|
|
40
|
+
import { loadEnv } from "vite";
|
|
41
|
+
const env = loadEnv(process.env.NODE_ENV!, process.cwd(), "");
|
|
42
|
+
|
|
43
|
+
export default defineConfig({
|
|
44
|
+
integrations: [
|
|
45
|
+
pagewriteAstro({
|
|
46
|
+
siteId: "your-site-id",
|
|
47
|
+
token: env.PAGEWRITE_BUILD_TOKEN, // or Pagewrite build token
|
|
48
|
+
}),
|
|
49
|
+
mdx(),
|
|
50
|
+
],
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Options
|
|
55
|
+
|
|
56
|
+
| Option | Type | Default | Description |
|
|
57
|
+
| ------ | ---- | ------- | ----------- |
|
|
58
|
+
| `siteId` | `string` | required | Pagewrite site to fetch and stage. |
|
|
59
|
+
| `token` | `string` | required | Build token value. |
|
|
60
|
+
| `outputDir` | `string` | `src/content/docs` | Directory where MDX files are written, relative to the Astro project root. |
|
|
61
|
+
| `clean` | `boolean` | `false` | Remove `outputDir` before writing fetched files. |
|
|
62
|
+
| `verbose` | `boolean` | `false` | Reserved for more detailed sync logging. |
|
|
63
|
+
|
|
64
|
+
## Examples
|
|
65
|
+
|
|
66
|
+
### Custom Output Directory
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
pagewriteAstro({
|
|
70
|
+
siteId: "your-site-id",
|
|
71
|
+
outputDir: "src/content/blog",
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Clean Sync For CI
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
pagewriteAstro({
|
|
79
|
+
siteId: "your-site-id",
|
|
80
|
+
clean: true,
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
## Ad-Hoc Fetching
|
|
87
|
+
|
|
88
|
+
You can fetch content outside the Astro build by running the CLI in a predeploy step, CI job, or local verification command:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pagewrite-astro fetch --site-id your-site-id --token rmx_live_xxxxxxxxxxxx --out src/content/docs
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
For CI, wire it before your framework build:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"scripts": {
|
|
99
|
+
"content:fetch": "pagewrite-astro fetch --site-id $PAGEWRITE_SITE_ID --token $PAGEWRITE_BUILD_TOKEN --out src/content/docs --clean",
|
|
100
|
+
"prebuild": "pnpm content:fetch",
|
|
101
|
+
"build": "astro build"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
To verify the remote content without keeping files on disk, use dry run:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
pagewrite-astro fetch --site-id your-site-id --token rmx_live_xxxxxxxxxxxx --dry-run
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
CLI options mirror the integration defaults: `--token`, `--clean`, `--page-size`, and `--timeout-ms` are available.
|
|
113
|
+
|
|
114
|
+
See [CLI.md](./CLI.md) for the full command reference and CI examples.
|
|
115
|
+
|
|
116
|
+
## Lower-Level API
|
|
117
|
+
|
|
118
|
+
The package also exports the reusable content staging primitives:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import {
|
|
122
|
+
fetchStaticFileTree,
|
|
123
|
+
fetchAllFileDocuments,
|
|
124
|
+
stageSiteContent,
|
|
125
|
+
} from "@lakshmanshankar/pagwrite-astro";
|
|
126
|
+
|
|
127
|
+
await stageSiteContent("your-site-id", "rmx_live_xxxxxxxxxxxx", "./content/docs");
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`stageSiteContent` fetches the static file tree and paginated file documents, converts file tree paths into safe MDX file paths, upserts `title` and `slug` frontmatter, and writes files to the target directory.
|
|
131
|
+
|
|
132
|
+
## Publishing
|
|
133
|
+
|
|
134
|
+
Package publishing is handled by GitHub Actions. Configure an `NPM_TOKEN` repository secret with permission to publish `@lakshmanshankar/pagwrite-astro`, then publish a GitHub release to run the npm publish workflow.
|
|
135
|
+
|
|
136
|
+
The workflow installs dependencies with pnpm, runs typecheck, tests, and build, then publishes to the npm registry with provenance enabled. It can also be started manually from the Actions tab with `workflow_dispatch`.
|
|
137
|
+
|
|
138
|
+
## Security Notes
|
|
139
|
+
|
|
140
|
+
- Never commit build tokens.
|
|
141
|
+
- Build tokens should be read-only and scoped to fetch site content.
|
|
142
|
+
- File tree paths are normalized and checked before writing.
|
|
143
|
+
- Missing tokens, API failures, invalid tree responses, and disk write errors fail the Astro build.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { stageSiteContent } from "./client.js";
|
|
5
|
+
import { resolveToken } from "./token.js";
|
|
6
|
+
const HELP = `Usage:
|
|
7
|
+
pagewrite-astro fetch --site-id <siteId> [options]
|
|
8
|
+
|
|
9
|
+
Options:
|
|
10
|
+
--site-id <id> Pagewrite site id to fetch. Required.
|
|
11
|
+
--out <dir> Output directory. Default: src/content/docs
|
|
12
|
+
--token <token> Build token. Defaults to env lookup.
|
|
13
|
+
--token-env <name> Token env var. Default: REMOTE_MDX_TOKEN
|
|
14
|
+
--clean Remove output directory before writing.
|
|
15
|
+
--dry-run Fetch and validate content without keeping written files.
|
|
16
|
+
--page-size <number> File document page size. Default: 100
|
|
17
|
+
--timeout-ms <number> Request timeout in milliseconds. Default: 30000
|
|
18
|
+
-h, --help Show this help.
|
|
19
|
+
`;
|
|
20
|
+
async function main(argv) {
|
|
21
|
+
const options = parseArgs(argv);
|
|
22
|
+
if (options.command === "help") {
|
|
23
|
+
console.log(HELP);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (!options.siteId) {
|
|
27
|
+
throw new Error("Missing required --site-id option.");
|
|
28
|
+
}
|
|
29
|
+
const token = resolveToken({
|
|
30
|
+
siteId: options.siteId,
|
|
31
|
+
token: options.token,
|
|
32
|
+
tokenEnvVar: options.tokenEnvVar,
|
|
33
|
+
});
|
|
34
|
+
const outputDir = path.resolve(process.cwd(), options.outDir);
|
|
35
|
+
const targetDir = options.dryRun
|
|
36
|
+
? await fs.mkdtemp(path.join(await fs.realpath("/tmp"), "pagewrite-astro-"))
|
|
37
|
+
: outputDir;
|
|
38
|
+
try {
|
|
39
|
+
if (options.clean && !options.dryRun) {
|
|
40
|
+
await fs.rm(targetDir, { recursive: true, force: true });
|
|
41
|
+
}
|
|
42
|
+
const result = await stageSiteContent(options.siteId, token, targetDir, {
|
|
43
|
+
logger: createConsoleLogger(),
|
|
44
|
+
pageSize: options.pageSize,
|
|
45
|
+
timeoutMs: options.timeoutMs,
|
|
46
|
+
});
|
|
47
|
+
if (options.dryRun) {
|
|
48
|
+
console.log(`Pagewrite dry run complete: fetched ${result.files.length} file(s) for site ${options.siteId}.`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
console.log(`Pagewrite fetch complete: wrote ${result.files.length} file(s) to ${outputDir}.`);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
if (options.dryRun) {
|
|
55
|
+
await fs.rm(targetDir, { recursive: true, force: true });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function parseArgs(argv) {
|
|
60
|
+
const options = {
|
|
61
|
+
command: "fetch",
|
|
62
|
+
outDir: "src/content/docs",
|
|
63
|
+
clean: false,
|
|
64
|
+
dryRun: false,
|
|
65
|
+
};
|
|
66
|
+
const [firstArg, ...rest] = argv;
|
|
67
|
+
const args = firstArg === "fetch" ? rest : argv;
|
|
68
|
+
if (firstArg === "help" || firstArg === "--help" || firstArg === "-h") {
|
|
69
|
+
return { ...options, command: "help" };
|
|
70
|
+
}
|
|
71
|
+
if (firstArg && firstArg !== "fetch" && firstArg.startsWith("-") === false) {
|
|
72
|
+
throw new Error(`Unknown command: ${firstArg}`);
|
|
73
|
+
}
|
|
74
|
+
for (let index = 0; index < args.length; index++) {
|
|
75
|
+
const arg = args[index];
|
|
76
|
+
switch (arg) {
|
|
77
|
+
case "--site-id":
|
|
78
|
+
options.siteId = readValue(args, ++index, arg);
|
|
79
|
+
break;
|
|
80
|
+
case "--out":
|
|
81
|
+
case "--output-dir":
|
|
82
|
+
options.outDir = readValue(args, ++index, arg);
|
|
83
|
+
break;
|
|
84
|
+
case "--token":
|
|
85
|
+
options.token = readValue(args, ++index, arg);
|
|
86
|
+
break;
|
|
87
|
+
case "--token-env":
|
|
88
|
+
case "--token-env-var":
|
|
89
|
+
options.tokenEnvVar = readValue(args, ++index, arg);
|
|
90
|
+
break;
|
|
91
|
+
case "--clean":
|
|
92
|
+
options.clean = true;
|
|
93
|
+
break;
|
|
94
|
+
case "--dry-run":
|
|
95
|
+
options.dryRun = true;
|
|
96
|
+
break;
|
|
97
|
+
case "--page-size":
|
|
98
|
+
options.pageSize = parsePositiveInteger(readValue(args, ++index, arg), arg);
|
|
99
|
+
break;
|
|
100
|
+
case "--timeout-ms":
|
|
101
|
+
options.timeoutMs = parsePositiveInteger(readValue(args, ++index, arg), arg);
|
|
102
|
+
break;
|
|
103
|
+
case "--help":
|
|
104
|
+
case "-h":
|
|
105
|
+
return { ...options, command: "help" };
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return options;
|
|
111
|
+
}
|
|
112
|
+
function readValue(args, index, option) {
|
|
113
|
+
const value = args[index];
|
|
114
|
+
if (!value || value.startsWith("--")) {
|
|
115
|
+
throw new Error(`Missing value for ${option}.`);
|
|
116
|
+
}
|
|
117
|
+
return value;
|
|
118
|
+
}
|
|
119
|
+
function parsePositiveInteger(value, option) {
|
|
120
|
+
const parsed = Number(value);
|
|
121
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
122
|
+
throw new Error(`${option} must be a positive integer.`);
|
|
123
|
+
}
|
|
124
|
+
return parsed;
|
|
125
|
+
}
|
|
126
|
+
function createConsoleLogger() {
|
|
127
|
+
return {
|
|
128
|
+
info: (message) => console.info(`[pagewrite-astro] ${message}`),
|
|
129
|
+
warn: (message) => console.warn(`[pagewrite-astro] ${message}`),
|
|
130
|
+
error: (message) => console.error(`[pagewrite-astro] ${message}`),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
main(process.argv.slice(2)).catch((error) => {
|
|
134
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
135
|
+
console.error(`[pagewrite-astro] ${message}`);
|
|
136
|
+
process.exitCode = 1;
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FileDocument, RemoteMdxLogger, SitePages, StagedSiteContent, SiteSchema } from "./types.js";
|
|
2
|
+
export declare const API_BASE_URL = "https://us-central1-sanity-freeform.cloudfunctions.net";
|
|
3
|
+
export declare const STATIC_FILE_TREE_ENDPOINT = "https://us-central1-sanity-freeform.cloudfunctions.net/getStaticFileTree";
|
|
4
|
+
export declare const PAGINATED_FILE_DOCUMENTS_ENDPOINT = "https://us-central1-sanity-freeform.cloudfunctions.net/getPaginatedFileDocuments";
|
|
5
|
+
export declare const SITE_SCHEMAS_ENDPOINT = "https://us-central1-sanity-freeform.cloudfunctions.net/getSiteSchemas";
|
|
6
|
+
export declare const DEFAULT_PAGE_SIZE = 100;
|
|
7
|
+
export interface FetchSiteContentOptions {
|
|
8
|
+
fetchImpl?: typeof fetch;
|
|
9
|
+
logger?: Pick<RemoteMdxLogger, "info" | "warn" | "error">;
|
|
10
|
+
pageSize?: number;
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function fetchSiteSchemas(siteId: string, token: string, options?: FetchSiteContentOptions): Promise<Map<string, SiteSchema>>;
|
|
14
|
+
export declare function fetchStaticFileTree(siteId: string, token: string, options?: FetchSiteContentOptions): Promise<SitePages>;
|
|
15
|
+
export declare function fetchAllFileDocuments(siteId: string, token: string, options?: FetchSiteContentOptions): Promise<Map<string, FileDocument>>;
|
|
16
|
+
export declare function stageSiteContent(siteId: string, token: string, contentDir: string, options?: FetchSiteContentOptions): Promise<StagedSiteContent>;
|
|
17
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EAEZ,eAAe,EACf,SAAS,EACT,iBAAiB,EAEjB,UAAU,EACX,MAAM,YAAY,CAAC;AAUpB,eAAO,MAAM,YAAY,2DAA2D,CAAC;AACrF,eAAO,MAAM,yBAAyB,6EAAsC,CAAC;AAC7E,eAAO,MAAM,iCAAiC,qFAA8C,CAAC;AAC7F,eAAO,MAAM,qBAAqB,0EAAmC,CAAC;AACtE,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,MAAM,WAAW,uBAAuB;IACtC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,MAAM,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyCD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAclC;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,SAAS,CAAC,CAiDpB;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CA0BpC;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,iBAAiB,CAAC,CAgF5B"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { ensureDir, writeTextFile } from "./fs.js";
|
|
3
|
+
import { flattenFileNodes, generatePageMap, safeRelativePath, toSegment, toSlug, } from "./utils.js";
|
|
4
|
+
import { buildMdxWithSchema } from "./frontmatter.js";
|
|
5
|
+
export const API_BASE_URL = "https://us-central1-sanity-freeform.cloudfunctions.net";
|
|
6
|
+
export const STATIC_FILE_TREE_ENDPOINT = `${API_BASE_URL}/getStaticFileTree`;
|
|
7
|
+
export const PAGINATED_FILE_DOCUMENTS_ENDPOINT = `${API_BASE_URL}/getPaginatedFileDocuments`;
|
|
8
|
+
export const SITE_SCHEMAS_ENDPOINT = `${API_BASE_URL}/getSiteSchemas`;
|
|
9
|
+
export const DEFAULT_PAGE_SIZE = 100;
|
|
10
|
+
async function fetchJson(url, token, body, errorPrefix, options = {}) {
|
|
11
|
+
const controller = new AbortController();
|
|
12
|
+
const timeoutId = setTimeout(() => controller.abort(), options.timeoutMs ?? 30_000);
|
|
13
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
14
|
+
try {
|
|
15
|
+
const response = await fetchImpl(url, {
|
|
16
|
+
method: "POST",
|
|
17
|
+
headers: {
|
|
18
|
+
"Content-Type": "application/json",
|
|
19
|
+
Authorization: `Bearer ${token}`,
|
|
20
|
+
},
|
|
21
|
+
body: JSON.stringify(body),
|
|
22
|
+
signal: controller.signal,
|
|
23
|
+
});
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
const errorText = await response.text();
|
|
26
|
+
throw new Error(`${errorPrefix}: ${response.status} - ${errorText}`);
|
|
27
|
+
}
|
|
28
|
+
return (await response.json());
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
32
|
+
throw new Error(`${errorPrefix}: request timed out after ${options.timeoutMs ?? 30_000}ms`);
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
clearTimeout(timeoutId);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export async function fetchSiteSchemas(siteId, token, options = {}) {
|
|
41
|
+
const responseData = await fetchJson(SITE_SCHEMAS_ENDPOINT, token, { siteId }, "Failed to fetch site schemas", options);
|
|
42
|
+
const schemas = new Map();
|
|
43
|
+
for (const schema of responseData.schemas ?? []) {
|
|
44
|
+
schemas.set(schema.id, schema);
|
|
45
|
+
}
|
|
46
|
+
return schemas;
|
|
47
|
+
}
|
|
48
|
+
export async function fetchStaticFileTree(siteId, token, options = {}) {
|
|
49
|
+
const responseData = await fetchJson(STATIC_FILE_TREE_ENDPOINT, token, { siteId }, "Failed to fetch static file tree", options);
|
|
50
|
+
const root = responseData.root;
|
|
51
|
+
if (!root || !root.isFolder) {
|
|
52
|
+
throw new Error("Invalid file tree response: root folder is missing");
|
|
53
|
+
}
|
|
54
|
+
const walkFolder = (children, parentPath, parentFolderId) => children.map((child) => {
|
|
55
|
+
const title = typeof child.title === "string" && child.title.trim().length > 0 ? child.title : child.id;
|
|
56
|
+
const childPath = parentPath ? `${parentPath}/${toSegment(title, child.id)}` : toSegment(title, child.id);
|
|
57
|
+
if (child.isFolder) {
|
|
58
|
+
return {
|
|
59
|
+
id: child.id,
|
|
60
|
+
type: "folder",
|
|
61
|
+
title,
|
|
62
|
+
path: childPath,
|
|
63
|
+
databaseType: child.databaseType,
|
|
64
|
+
lang: child.lang,
|
|
65
|
+
schemaId: child.schemaId,
|
|
66
|
+
children: walkFolder(child.children ?? [], childPath, child.id),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
id: child.id,
|
|
71
|
+
type: "file",
|
|
72
|
+
title,
|
|
73
|
+
path: childPath,
|
|
74
|
+
storageFile: "",
|
|
75
|
+
parentFolderId,
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
siteId,
|
|
80
|
+
rootFolderId: root.id,
|
|
81
|
+
rootSchemaId: root.schemaId,
|
|
82
|
+
pages: walkFolder(root.children ?? [], "", root.id),
|
|
83
|
+
tags: {},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export async function fetchAllFileDocuments(siteId, token, options = {}) {
|
|
87
|
+
const documents = new Map();
|
|
88
|
+
let pageToken = null;
|
|
89
|
+
do {
|
|
90
|
+
const responseData = await fetchJson(PAGINATED_FILE_DOCUMENTS_ENDPOINT, token, {
|
|
91
|
+
siteId,
|
|
92
|
+
pageSize: options.pageSize ?? DEFAULT_PAGE_SIZE,
|
|
93
|
+
pageToken,
|
|
94
|
+
}, "Failed to fetch paginated file documents", options);
|
|
95
|
+
for (const document of responseData.documents ?? []) {
|
|
96
|
+
documents.set(document.id, document);
|
|
97
|
+
}
|
|
98
|
+
pageToken = responseData.nextPageToken ?? null;
|
|
99
|
+
} while (pageToken);
|
|
100
|
+
return documents;
|
|
101
|
+
}
|
|
102
|
+
export async function stageSiteContent(siteId, token, contentDir, options = {}) {
|
|
103
|
+
const [sitePages, documents, schemas] = await Promise.all([
|
|
104
|
+
fetchStaticFileTree(siteId, token, options),
|
|
105
|
+
fetchAllFileDocuments(siteId, token, options),
|
|
106
|
+
fetchSiteSchemas(siteId, token, options),
|
|
107
|
+
]);
|
|
108
|
+
const fileNodes = flattenFileNodes(sitePages.pages);
|
|
109
|
+
await ensureDir(contentDir);
|
|
110
|
+
const folderSchemaMap = new Map();
|
|
111
|
+
if (sitePages.rootSchemaId) {
|
|
112
|
+
folderSchemaMap.set(sitePages.rootFolderId, sitePages.rootSchemaId);
|
|
113
|
+
}
|
|
114
|
+
const mapSchemas = (nodes, inheritedSchemaId) => {
|
|
115
|
+
for (const node of nodes) {
|
|
116
|
+
if (node.type === "folder") {
|
|
117
|
+
const activeSchemaId = node.schemaId ?? inheritedSchemaId;
|
|
118
|
+
if (activeSchemaId) {
|
|
119
|
+
folderSchemaMap.set(node.id, activeSchemaId);
|
|
120
|
+
}
|
|
121
|
+
mapSchemas(node.children, activeSchemaId);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
mapSchemas(sitePages.pages, sitePages.rootSchemaId);
|
|
126
|
+
let skippedCount = 0;
|
|
127
|
+
const files = [];
|
|
128
|
+
for (const fileNode of fileNodes) {
|
|
129
|
+
const normalizedPath = safeRelativePath(fileNode.path);
|
|
130
|
+
const relPath = `${normalizedPath}.mdx`;
|
|
131
|
+
const absolutePath = path.join(contentDir, relPath);
|
|
132
|
+
const document = documents.get(fileNode.id);
|
|
133
|
+
if (!document) {
|
|
134
|
+
options.logger?.warn(`Document not found for file node: ${fileNode.id} (${fileNode.title})`);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (document.metadata?.pageStatus !== "published") {
|
|
138
|
+
skippedCount++;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const slug = toSlug(normalizedPath);
|
|
142
|
+
const schemaId = fileNode.parentFolderId ? folderSchemaMap.get(fileNode.parentFolderId) : undefined;
|
|
143
|
+
const schema = schemaId ? schemas.get(schemaId) : undefined;
|
|
144
|
+
const contentWithFrontmatter = buildMdxWithSchema(document, schema, fileNode.title, slug);
|
|
145
|
+
await ensureDir(path.dirname(absolutePath));
|
|
146
|
+
await writeTextFile(absolutePath, contentWithFrontmatter);
|
|
147
|
+
files.push({
|
|
148
|
+
id: fileNode.id,
|
|
149
|
+
relPath,
|
|
150
|
+
absolutePath,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (skippedCount > 0) {
|
|
154
|
+
options.logger?.info?.(`Skipped ${skippedCount} non-published page(s).`);
|
|
155
|
+
}
|
|
156
|
+
const pagemap = generatePageMap(sitePages.pages);
|
|
157
|
+
const pagemapPath = path.join(contentDir, "pagemap.json");
|
|
158
|
+
await writeTextFile(pagemapPath, JSON.stringify(pagemap, null, 2));
|
|
159
|
+
return {
|
|
160
|
+
sitePages,
|
|
161
|
+
files,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAwB3D,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,UAAU,GAAG,SAAS,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,MAAM,CA4DR"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { stringify } from "yaml";
|
|
2
|
+
import { upsertFrontmatter } from "./utils.js";
|
|
3
|
+
function toCamelCase(str) {
|
|
4
|
+
return str
|
|
5
|
+
.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
|
|
6
|
+
return index === 0 ? word.toLowerCase() : word.toUpperCase();
|
|
7
|
+
})
|
|
8
|
+
.replace(/\s+/g, "");
|
|
9
|
+
}
|
|
10
|
+
function extractBody(content) {
|
|
11
|
+
const normalizedContent = content.replace(/^\uFEFF/, "");
|
|
12
|
+
if (!normalizedContent.startsWith("---\n")) {
|
|
13
|
+
return normalizedContent;
|
|
14
|
+
}
|
|
15
|
+
const endIndex = normalizedContent.indexOf("\n---", 4);
|
|
16
|
+
if (endIndex === -1) {
|
|
17
|
+
return normalizedContent;
|
|
18
|
+
}
|
|
19
|
+
const bodyStart = normalizedContent.startsWith("\n", endIndex + 4) ? endIndex + 5 : endIndex + 4;
|
|
20
|
+
return normalizedContent.slice(bodyStart);
|
|
21
|
+
}
|
|
22
|
+
export function buildMdxWithSchema(document, schema, fallbackTitle, slug) {
|
|
23
|
+
if (!schema) {
|
|
24
|
+
// Fallback to standard metadata processing
|
|
25
|
+
return upsertFrontmatter(document.mdxString ?? "", fallbackTitle, slug, document.id);
|
|
26
|
+
}
|
|
27
|
+
const frontmatter = {};
|
|
28
|
+
const rawMetadata = document.metadata ?? {};
|
|
29
|
+
// Include standard static fields from metadata
|
|
30
|
+
const staticFields = [
|
|
31
|
+
"title",
|
|
32
|
+
"id",
|
|
33
|
+
"datePublished",
|
|
34
|
+
"metaDescription",
|
|
35
|
+
"pageStatus",
|
|
36
|
+
"slug",
|
|
37
|
+
"metaKeywords",
|
|
38
|
+
"metaTitle"
|
|
39
|
+
];
|
|
40
|
+
for (const key of staticFields) {
|
|
41
|
+
if (key in rawMetadata && rawMetadata[key] !== undefined) {
|
|
42
|
+
frontmatter[key] = rawMetadata[key];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Process schema fields
|
|
46
|
+
for (const field of schema.fields) {
|
|
47
|
+
const camelKey = toCamelCase(field.name);
|
|
48
|
+
// Look up by field.id for custom schema properties
|
|
49
|
+
if (field.id in rawMetadata) {
|
|
50
|
+
// Type coercion if necessary
|
|
51
|
+
let value = rawMetadata[field.id];
|
|
52
|
+
// Basic coercion placeholder (can be expanded based on exact field types)
|
|
53
|
+
if (field.type === "date" || field.type === "date_range") {
|
|
54
|
+
if (value && typeof value === "string") {
|
|
55
|
+
// Keep as string or parse date, YAML stringifier handles both nicely
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else if (field.type === "multi_select") {
|
|
59
|
+
if (Array.isArray(value)) {
|
|
60
|
+
// Array is fine, YAML stringifier handles it
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
frontmatter[camelKey] = value;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Merge system-level metadata fallback
|
|
67
|
+
frontmatter.title = frontmatter.title ?? fallbackTitle;
|
|
68
|
+
frontmatter.slug = frontmatter.slug ?? slug;
|
|
69
|
+
if (!frontmatter.id && document.id) {
|
|
70
|
+
frontmatter.id = document.id;
|
|
71
|
+
}
|
|
72
|
+
const yamlString = stringify(frontmatter);
|
|
73
|
+
const mdxBody = extractBody(document.mdxString ?? "");
|
|
74
|
+
return `---\n${yamlString.trim()}\n---\n\n${mdxBody}`;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=frontmatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"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"}
|
package/dist/fs.d.ts
ADDED
package/dist/fs.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAEA,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpF"}
|
package/dist/fs.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
export async function ensureDir(dirPath) {
|
|
3
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
4
|
+
}
|
|
5
|
+
export async function writeTextFile(filePath, content) {
|
|
6
|
+
await fs.writeFile(filePath, content, "utf8");
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=fs.js.map
|
package/dist/fs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,OAAe;IACnE,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAChD,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AstroIntegration } from "astro";
|
|
2
|
+
import type { RemoteMdxOptions } from "./types.js";
|
|
3
|
+
export type { FileDocument, PageMapNode, PageTreeFileNode, PageTreeFolderNode, PageTreeNode, RemoteMdxOptions, SitePages, StagedSiteContent, StaticTreeChild, } from "./types.js";
|
|
4
|
+
export { DEFAULT_PAGE_SIZE, PAGINATED_FILE_DOCUMENTS_ENDPOINT, STATIC_FILE_TREE_ENDPOINT, SITE_SCHEMAS_ENDPOINT, fetchAllFileDocuments, fetchStaticFileTree, stageSiteContent, } from "./client.js";
|
|
5
|
+
export { resolveToken } from "./token.js";
|
|
6
|
+
export { flattenFileNodes, generatePageMap, safeRelativePath, toSegment, toSlug, upsertFrontmatter } from "./utils.js";
|
|
7
|
+
export default function pagewriteAstro(options: RemoteMdxOptions): AstroIntegration;
|
|
8
|
+
export declare function remoteMdx(options: RemoteMdxOptions): AstroIntegration;
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAM9C,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEpE,YAAY,EACV,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,iBAAiB,EACjB,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,iBAAiB,EACjB,iCAAiC,EACjC,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEvH,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAElF;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CA0BrE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { loadEnv } from "vite";
|
|
5
|
+
import { stageSiteContent } from "./client.js";
|
|
6
|
+
import { resolveToken } from "./token.js";
|
|
7
|
+
export { DEFAULT_PAGE_SIZE, PAGINATED_FILE_DOCUMENTS_ENDPOINT, STATIC_FILE_TREE_ENDPOINT, SITE_SCHEMAS_ENDPOINT, fetchAllFileDocuments, fetchStaticFileTree, stageSiteContent, } from "./client.js";
|
|
8
|
+
export { resolveToken } from "./token.js";
|
|
9
|
+
export { flattenFileNodes, generatePageMap, safeRelativePath, toSegment, toSlug, upsertFrontmatter } from "./utils.js";
|
|
10
|
+
export default function pagewriteAstro(options) {
|
|
11
|
+
return remoteMdx(options);
|
|
12
|
+
}
|
|
13
|
+
export function remoteMdx(options) {
|
|
14
|
+
return {
|
|
15
|
+
name: "@lakshmanshankar/pagwrite-astro",
|
|
16
|
+
hooks: {
|
|
17
|
+
"astro:config:setup": async ({ config, command, logger }) => {
|
|
18
|
+
const integrationLogger = createLogger(logger);
|
|
19
|
+
const root = fileURLToPath(config.root);
|
|
20
|
+
const env = loadEnv(command === "dev" ? "development" : "production", root, "");
|
|
21
|
+
const token = resolveToken(options, env);
|
|
22
|
+
const outputDir = path.resolve(root, options.outputDir ?? "src/content/docs");
|
|
23
|
+
if (options.clean ?? false) {
|
|
24
|
+
logger.info(`Cleaning Pagewrite content directory: ${outputDir}`);
|
|
25
|
+
await fs.rm(outputDir, { recursive: true, force: true });
|
|
26
|
+
}
|
|
27
|
+
logger.info("Fetching Pagewrite site content");
|
|
28
|
+
const result = await stageSiteContent(options.siteId, token, outputDir, {
|
|
29
|
+
logger: integrationLogger,
|
|
30
|
+
});
|
|
31
|
+
logger.info(`Pagewrite content sync complete: ${result.files.length} file(s) written`);
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function createLogger(logger) {
|
|
37
|
+
return {
|
|
38
|
+
info: (message) => logger.info(message),
|
|
39
|
+
warn: (message) => logger.warn(message),
|
|
40
|
+
error: (message) => logger.error(message),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAe1C,OAAO,EACL,iBAAiB,EACjB,iCAAiC,EACjC,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEvH,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,OAAyB;IAC9D,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAyB;IACjD,OAAO;QACL,IAAI,EAAE,iCAAiC;QACvC,KAAK,EAAE;YACL,oBAAoB,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC1D,MAAM,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;gBAC/C,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACxC,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;gBAChF,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAC,CAAC;gBAE9E,IAAI,OAAO,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;oBAC3B,MAAM,CAAC,IAAI,CAAC,yCAAyC,SAAS,EAAE,CAAC,CAAC;oBAClE,MAAM,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3D,CAAC;gBAED,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;gBAE/C,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;oBACtE,MAAM,EAAE,iBAAiB;iBAC1B,CAAC,CAAC;gBAEH,MAAM,CAAC,IAAI,CAAC,oCAAoC,MAAM,CAAC,KAAK,CAAC,MAAM,kBAAkB,CAAC,CAAC;YACzF,CAAC;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,MAIrB;IACC,OAAO;QACL,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QACvC,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QACvC,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;KAC1C,CAAC;AACJ,CAAC"}
|
package/dist/token.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RemoteMdxOptions } from "./types.js";
|
|
2
|
+
export declare const DEFAULT_TOKEN_ENV_VAR = "REMOTE_MDX_TOKEN";
|
|
3
|
+
export declare function resolveToken(options: RemoteMdxOptions, env?: Record<string, string | undefined> | string): string;
|
|
4
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,wBAAgB,YAAY,CAC1B,OAAO,EAAE,gBAAgB,EACzB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAChD,MAAM,CA2BR"}
|
package/dist/token.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const DEFAULT_TOKEN_ENV_VAR = "REMOTE_MDX_TOKEN";
|
|
2
|
+
export function resolveToken(options, env) {
|
|
3
|
+
if (options.token?.trim()) {
|
|
4
|
+
return options.token.trim();
|
|
5
|
+
}
|
|
6
|
+
if (typeof env === "string" && env.trim()) {
|
|
7
|
+
return env.trim();
|
|
8
|
+
}
|
|
9
|
+
const envVar = options.tokenEnvVar ?? DEFAULT_TOKEN_ENV_VAR;
|
|
10
|
+
let token;
|
|
11
|
+
if (typeof env === "object" && env !== null) {
|
|
12
|
+
token = env[envVar]?.trim();
|
|
13
|
+
}
|
|
14
|
+
if (!token) {
|
|
15
|
+
token = process.env[envVar]?.trim();
|
|
16
|
+
}
|
|
17
|
+
if (token) {
|
|
18
|
+
return token;
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`[pagewrite:astro] Build token not found. Set ${envVar} or pass token in the integration options.`);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAExD,MAAM,UAAU,YAAY,CAC1B,OAAyB,EACzB,GAAiD;IAEjD,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1C,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,IAAI,qBAAqB,CAAC;IAC5D,IAAI,KAAyB,CAAC;IAE9B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC;IACtC,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,IAAI,KAAK,CACb,gDAAgD,MAAM,4CAA4C,CACnG,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export interface RemoteMdxOptions {
|
|
2
|
+
siteId: string;
|
|
3
|
+
token?: string;
|
|
4
|
+
tokenEnvVar?: string;
|
|
5
|
+
outputDir?: string;
|
|
6
|
+
clean?: boolean;
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface SchemaField {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
type: string;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface SiteSchema {
|
|
17
|
+
id: string;
|
|
18
|
+
name?: string;
|
|
19
|
+
fields: SchemaField[];
|
|
20
|
+
}
|
|
21
|
+
export interface StaticTreeChild {
|
|
22
|
+
id: string;
|
|
23
|
+
title?: string;
|
|
24
|
+
isFolder: boolean;
|
|
25
|
+
children?: StaticTreeChild[];
|
|
26
|
+
databaseType?: string;
|
|
27
|
+
lang?: string;
|
|
28
|
+
schemaId?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface PageTreeFolderNode {
|
|
31
|
+
id: string;
|
|
32
|
+
type: "folder";
|
|
33
|
+
title: string;
|
|
34
|
+
path: string;
|
|
35
|
+
databaseType?: string;
|
|
36
|
+
lang?: string;
|
|
37
|
+
schemaId?: string;
|
|
38
|
+
children: PageTreeNode[];
|
|
39
|
+
}
|
|
40
|
+
export interface PageTreeFileNode {
|
|
41
|
+
id: string;
|
|
42
|
+
type: "file";
|
|
43
|
+
title: string;
|
|
44
|
+
path: string;
|
|
45
|
+
storageFile: string;
|
|
46
|
+
parentFolderId?: string;
|
|
47
|
+
}
|
|
48
|
+
export type PageTreeNode = PageTreeFolderNode | PageTreeFileNode;
|
|
49
|
+
export interface PageMapNode {
|
|
50
|
+
id: string;
|
|
51
|
+
title: string;
|
|
52
|
+
slug: string;
|
|
53
|
+
children?: PageMapNode[];
|
|
54
|
+
}
|
|
55
|
+
export interface SitePages {
|
|
56
|
+
siteId: string;
|
|
57
|
+
rootFolderId: string;
|
|
58
|
+
rootSchemaId?: string;
|
|
59
|
+
pages: PageTreeNode[];
|
|
60
|
+
tags: Record<string, unknown>;
|
|
61
|
+
}
|
|
62
|
+
export interface FileDocument {
|
|
63
|
+
id: string;
|
|
64
|
+
mdxString?: string;
|
|
65
|
+
parentFolderId?: string;
|
|
66
|
+
metadata?: Record<string, unknown>;
|
|
67
|
+
[key: string]: unknown;
|
|
68
|
+
}
|
|
69
|
+
export interface StagedSiteContentFile {
|
|
70
|
+
id: string;
|
|
71
|
+
relPath: string;
|
|
72
|
+
absolutePath: string;
|
|
73
|
+
}
|
|
74
|
+
export interface StagedSiteContent {
|
|
75
|
+
sitePages: SitePages;
|
|
76
|
+
files: StagedSiteContentFile[];
|
|
77
|
+
}
|
|
78
|
+
export interface RemoteMdxLogger {
|
|
79
|
+
info(message: string): void;
|
|
80
|
+
warn(message: string): void;
|
|
81
|
+
error(message: string): void;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PageMapNode, PageTreeFileNode, PageTreeNode } from "./types.js";
|
|
2
|
+
export declare function generatePageMap(nodes: PageTreeNode[]): PageMapNode[];
|
|
3
|
+
export declare function flattenFileNodes(nodes: PageTreeNode[]): PageTreeFileNode[];
|
|
4
|
+
export declare function safeRelativePath(value: string): string;
|
|
5
|
+
export declare function toSegment(title: string, fallback: string): string;
|
|
6
|
+
export declare function toSlug(relativePath: string): string;
|
|
7
|
+
export declare function upsertFrontmatter(content: string, title: string, slug: string, id?: string): string;
|
|
8
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE9E,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,WAAW,EAAE,CAiBpE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,gBAAgB,EAAE,CAY1E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAuBtD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGjE;AAED,wBAAgB,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAKnD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CA8BnG"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
export function generatePageMap(nodes) {
|
|
3
|
+
return nodes.map((node) => {
|
|
4
|
+
const slug = toSlug(safeRelativePath(node.path));
|
|
5
|
+
if (node.type === "folder") {
|
|
6
|
+
return {
|
|
7
|
+
id: node.id,
|
|
8
|
+
title: node.title,
|
|
9
|
+
slug,
|
|
10
|
+
children: generatePageMap(node.children),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
id: node.id,
|
|
15
|
+
title: node.title,
|
|
16
|
+
slug,
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export function flattenFileNodes(nodes) {
|
|
21
|
+
const files = [];
|
|
22
|
+
for (const node of nodes) {
|
|
23
|
+
if (node.type === "file") {
|
|
24
|
+
files.push(node);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
files.push(...flattenFileNodes(node.children));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return files;
|
|
31
|
+
}
|
|
32
|
+
export function safeRelativePath(value) {
|
|
33
|
+
const normalizedSlashes = value.replace(/\\/g, "/").trim();
|
|
34
|
+
if (!normalizedSlashes || normalizedSlashes.includes("\0")) {
|
|
35
|
+
throw new Error("Invalid empty content path");
|
|
36
|
+
}
|
|
37
|
+
if (path.posix.isAbsolute(normalizedSlashes)) {
|
|
38
|
+
throw new Error(`Unsafe absolute content path: ${value}`);
|
|
39
|
+
}
|
|
40
|
+
const normalized = path.posix.normalize(normalizedSlashes);
|
|
41
|
+
if (normalized === "." ||
|
|
42
|
+
normalized === ".." ||
|
|
43
|
+
normalized.startsWith("../") ||
|
|
44
|
+
normalized.includes("/../")) {
|
|
45
|
+
throw new Error(`Unsafe relative content path: ${value}`);
|
|
46
|
+
}
|
|
47
|
+
return normalized;
|
|
48
|
+
}
|
|
49
|
+
export function toSegment(title, fallback) {
|
|
50
|
+
const slug = slugify(title);
|
|
51
|
+
return slug || slugify(fallback) || fallback;
|
|
52
|
+
}
|
|
53
|
+
export function toSlug(relativePath) {
|
|
54
|
+
return safeRelativePath(relativePath)
|
|
55
|
+
.split("/")
|
|
56
|
+
.map((segment) => toSegment(segment, segment))
|
|
57
|
+
.join("/");
|
|
58
|
+
}
|
|
59
|
+
export function upsertFrontmatter(content, title, slug, id) {
|
|
60
|
+
const normalizedContent = content.replace(/^\uFEFF/, "");
|
|
61
|
+
const titleLine = `title: ${quoteYamlString(title)}`;
|
|
62
|
+
const slugLine = `slug: ${quoteYamlString(slug)}`;
|
|
63
|
+
const idLine = id ? `id: ${quoteYamlString(id)}` : "";
|
|
64
|
+
const lines = [titleLine, slugLine];
|
|
65
|
+
if (idLine) {
|
|
66
|
+
lines.push(idLine);
|
|
67
|
+
}
|
|
68
|
+
if (!normalizedContent.startsWith("---\n")) {
|
|
69
|
+
return `---\n${lines.join("\n")}\n---\n\n${normalizedContent}`;
|
|
70
|
+
}
|
|
71
|
+
const endIndex = normalizedContent.indexOf("\n---", 4);
|
|
72
|
+
if (endIndex === -1) {
|
|
73
|
+
return `---\n${lines.join("\n")}\n---\n\n${normalizedContent}`;
|
|
74
|
+
}
|
|
75
|
+
const existingFrontmatter = normalizedContent.slice(4, endIndex);
|
|
76
|
+
const bodyStart = normalizedContent.startsWith("\n", endIndex + 4) ? endIndex + 5 : endIndex + 4;
|
|
77
|
+
const body = normalizedContent.slice(bodyStart);
|
|
78
|
+
const remainingLines = existingFrontmatter
|
|
79
|
+
.split("\n")
|
|
80
|
+
.filter((line) => !/^title\s*:/.test(line) && !/^slug\s*:/.test(line) && (id ? !/^id\s*:/.test(line) : true))
|
|
81
|
+
.filter((line, index, lines) => line.trim() !== "" || index < lines.length - 1);
|
|
82
|
+
const nextFrontmatter = [...lines, ...remainingLines].join("\n").trim();
|
|
83
|
+
return `---\n${nextFrontmatter}\n---${body.startsWith("\n") ? "" : "\n"}${body}`;
|
|
84
|
+
}
|
|
85
|
+
function slugify(value) {
|
|
86
|
+
return value
|
|
87
|
+
.normalize("NFKD")
|
|
88
|
+
.replace(/[\u0300-\u036f]/g, "")
|
|
89
|
+
.toLowerCase()
|
|
90
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
91
|
+
.replace(/^-+|-+$/g, "");
|
|
92
|
+
}
|
|
93
|
+
function quoteYamlString(value) {
|
|
94
|
+
return JSON.stringify(value);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pagewrite-astro",
|
|
3
|
+
"version": "0.1.7",
|
|
4
|
+
"description": "Astro integration for fetching Pagewrite MDX content at build time.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md",
|
|
17
|
+
"CLI.md"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"astro",
|
|
21
|
+
"mdx",
|
|
22
|
+
"pagewrite"
|
|
23
|
+
],
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"astro": ">=4.0.0 || >=5.0.0",
|
|
27
|
+
"vite": ">=4.0.0 || >=5.0.0 || >=6.0.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^20.14.0",
|
|
31
|
+
"astro": "^5.0.0",
|
|
32
|
+
"tsx": "^4.19.0",
|
|
33
|
+
"typescript": "^5.5.0",
|
|
34
|
+
"vite": "^8.0.16",
|
|
35
|
+
"vitest": "^2.0.0"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18.17.0"
|
|
39
|
+
},
|
|
40
|
+
"bin": {
|
|
41
|
+
"pagewrite-astro": "./dist/cli.js"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"yaml": "^2.9.0"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "pnpm run clean && tsc -p tsconfig.json",
|
|
48
|
+
"test": "vitest run",
|
|
49
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
50
|
+
"clean": "node scripts/clean-dist.mjs"
|
|
51
|
+
}
|
|
52
|
+
}
|