@sourcepress/astro 0.1.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.
Files changed (66) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-test.log +18 -0
  3. package/LICENSE +21 -0
  4. package/dist/__tests__/client.test.d.ts +2 -0
  5. package/dist/__tests__/client.test.d.ts.map +1 -0
  6. package/dist/__tests__/client.test.js +62 -0
  7. package/dist/__tests__/client.test.js.map +1 -0
  8. package/dist/__tests__/component-registry.test.d.ts +2 -0
  9. package/dist/__tests__/component-registry.test.d.ts.map +1 -0
  10. package/dist/__tests__/component-registry.test.js +38 -0
  11. package/dist/__tests__/component-registry.test.js.map +1 -0
  12. package/dist/__tests__/content-syncer.test.d.ts +2 -0
  13. package/dist/__tests__/content-syncer.test.d.ts.map +1 -0
  14. package/dist/__tests__/content-syncer.test.js +153 -0
  15. package/dist/__tests__/content-syncer.test.js.map +1 -0
  16. package/dist/__tests__/integration.test.d.ts +2 -0
  17. package/dist/__tests__/integration.test.d.ts.map +1 -0
  18. package/dist/__tests__/integration.test.js +141 -0
  19. package/dist/__tests__/integration.test.js.map +1 -0
  20. package/dist/__tests__/schema-generator.test.d.ts +2 -0
  21. package/dist/__tests__/schema-generator.test.d.ts.map +1 -0
  22. package/dist/__tests__/schema-generator.test.js +139 -0
  23. package/dist/__tests__/schema-generator.test.js.map +1 -0
  24. package/dist/client.d.ts +14 -0
  25. package/dist/client.d.ts.map +1 -0
  26. package/dist/client.js +44 -0
  27. package/dist/client.js.map +1 -0
  28. package/dist/component-registry.d.ts +12 -0
  29. package/dist/component-registry.d.ts.map +1 -0
  30. package/dist/component-registry.js +17 -0
  31. package/dist/component-registry.js.map +1 -0
  32. package/dist/content-syncer.d.ts +23 -0
  33. package/dist/content-syncer.d.ts.map +1 -0
  34. package/dist/content-syncer.js +95 -0
  35. package/dist/content-syncer.js.map +1 -0
  36. package/dist/index.d.ts +9 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +7 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/integration.d.ts +4 -0
  41. package/dist/integration.d.ts.map +1 -0
  42. package/dist/integration.js +52 -0
  43. package/dist/integration.js.map +1 -0
  44. package/dist/schema-generator.d.ts +3 -0
  45. package/dist/schema-generator.d.ts.map +1 -0
  46. package/dist/schema-generator.js +77 -0
  47. package/dist/schema-generator.js.map +1 -0
  48. package/dist/types.d.ts +35 -0
  49. package/dist/types.d.ts.map +1 -0
  50. package/dist/types.js +2 -0
  51. package/dist/types.js.map +1 -0
  52. package/package.json +33 -0
  53. package/src/__tests__/client.test.ts +82 -0
  54. package/src/__tests__/component-registry.test.ts +49 -0
  55. package/src/__tests__/content-syncer.test.ts +174 -0
  56. package/src/__tests__/integration.test.ts +169 -0
  57. package/src/__tests__/schema-generator.test.ts +156 -0
  58. package/src/client.ts +54 -0
  59. package/src/component-registry.ts +19 -0
  60. package/src/content-syncer.ts +110 -0
  61. package/src/index.ts +8 -0
  62. package/src/integration.ts +61 -0
  63. package/src/schema-generator.ts +80 -0
  64. package/src/types.ts +40 -0
  65. package/tsconfig.json +8 -0
  66. package/vitest.config.ts +7 -0
@@ -0,0 +1,139 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { generateContentConfig } from "../schema-generator.js";
3
+ describe("generateContentConfig", () => {
4
+ it("produces valid TypeScript for a single collection with all field types", () => {
5
+ const collections = {
6
+ posts: {
7
+ name: "posts",
8
+ path: "content/posts",
9
+ format: "mdx",
10
+ fields: {
11
+ title: { type: "string", required: true },
12
+ draft: { type: "boolean", required: false },
13
+ views: { type: "number", required: true },
14
+ cover: { type: "image", required: false },
15
+ gallery: { type: "image", required: false, multiple: true },
16
+ author: { type: "relation-one", collection: "authors", required: false },
17
+ tags: { type: "relation-many", collection: "tags", required: false },
18
+ },
19
+ },
20
+ };
21
+ const result = generateContentConfig(collections);
22
+ expect(result).toContain(`import { defineCollection, z } from 'astro:content'`);
23
+ expect(result).toContain(`import { glob } from 'astro/loaders'`);
24
+ expect(result).toContain("defineCollection(");
25
+ expect(result).toContain("glob({ pattern:");
26
+ expect(result).toContain("z.object(");
27
+ // required string
28
+ expect(result).toContain("title: z.string(),");
29
+ // optional boolean
30
+ expect(result).toContain("draft: z.boolean().optional(),");
31
+ // required number
32
+ expect(result).toContain("views: z.number(),");
33
+ // optional image (single)
34
+ expect(result).toContain("cover: z.string().optional(),");
35
+ // optional image (multiple)
36
+ expect(result).toContain("gallery: z.array(z.string()).optional(),");
37
+ // optional relation-one
38
+ expect(result).toContain("author: z.string().optional(),");
39
+ // optional relation-many
40
+ expect(result).toContain("tags: z.array(z.string()).optional(),");
41
+ expect(result).toContain("export const collections = {");
42
+ expect(result).toContain("posts,");
43
+ });
44
+ it("uses correct glob pattern based on format", () => {
45
+ const collections = {
46
+ posts: {
47
+ name: "posts",
48
+ path: "content/posts",
49
+ format: "mdx",
50
+ fields: { title: { type: "string", required: true } },
51
+ },
52
+ data: {
53
+ name: "data",
54
+ path: "content/data",
55
+ format: "yaml",
56
+ fields: { name: { type: "string", required: true } },
57
+ },
58
+ config: {
59
+ name: "config",
60
+ path: "content/config",
61
+ format: "json",
62
+ fields: { key: { type: "string", required: true } },
63
+ },
64
+ };
65
+ const result = generateContentConfig(collections);
66
+ expect(result).toContain('pattern: "**/*.{md,mdx}", base: "src/content/posts"');
67
+ expect(result).toContain('pattern: "**/*.{yaml,yml}", base: "src/content/data"');
68
+ expect(result).toContain('pattern: "**/*.json", base: "src/content/config"');
69
+ });
70
+ it("generates correct exports object for multiple collections", () => {
71
+ const collections = {
72
+ posts: {
73
+ name: "posts",
74
+ path: "content/posts",
75
+ format: "mdx",
76
+ fields: { title: { type: "string", required: true } },
77
+ },
78
+ authors: {
79
+ name: "authors",
80
+ path: "content/authors",
81
+ format: "yaml",
82
+ fields: { name: { type: "string", required: true } },
83
+ },
84
+ };
85
+ const result = generateContentConfig(collections);
86
+ expect(result).toContain("const posts =");
87
+ expect(result).toContain("const authors =");
88
+ expect(result).toContain("posts,");
89
+ expect(result).toContain("authors,");
90
+ expect(result).toContain("export const collections = {");
91
+ });
92
+ it("produces .optional() for optional fields and no .optional() for required fields", () => {
93
+ const collections = {
94
+ articles: {
95
+ name: "articles",
96
+ path: "content/articles",
97
+ format: "md",
98
+ fields: {
99
+ title: { type: "string", required: true },
100
+ subtitle: { type: "string", required: false },
101
+ published: { type: "boolean", required: true },
102
+ featured: { type: "boolean", required: false },
103
+ score: { type: "number", required: true },
104
+ rating: { type: "number", required: false },
105
+ },
106
+ },
107
+ };
108
+ const result = generateContentConfig(collections);
109
+ expect(result).toContain("title: z.string(),");
110
+ expect(result).toContain("subtitle: z.string().optional(),");
111
+ expect(result).toContain("published: z.boolean(),");
112
+ expect(result).toContain("featured: z.boolean().optional(),");
113
+ expect(result).toContain("score: z.number(),");
114
+ expect(result).toContain("rating: z.number().optional(),");
115
+ });
116
+ it("includes default values in output", () => {
117
+ const collections = {
118
+ settings: {
119
+ name: "settings",
120
+ path: "content/settings",
121
+ format: "yaml",
122
+ fields: {
123
+ theme: { type: "string", default: "light" },
124
+ lang: { type: "string", default: "en", required: true },
125
+ },
126
+ },
127
+ };
128
+ const result = generateContentConfig(collections);
129
+ expect(result).toContain('theme: z.string().default("light"),');
130
+ expect(result).toContain('lang: z.string().default("en"),');
131
+ });
132
+ it("produces minimal valid file for empty collections record", () => {
133
+ const result = generateContentConfig({});
134
+ expect(result).toContain(`import { defineCollection, z } from 'astro:content'`);
135
+ expect(result).toContain("export const collections = {};");
136
+ expect(result).not.toContain("defineCollection(");
137
+ });
138
+ });
139
+ //# sourceMappingURL=schema-generator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-generator.test.js","sourceRoot":"","sources":["../../src/__tests__/schema-generator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ComponentDefinition, ContentListResponse, SchemaResponse } from "./types.js";
2
+ export declare class EngineClientError extends Error {
3
+ readonly status: number;
4
+ readonly body: string;
5
+ constructor(message: string, status: number, body: string);
6
+ }
7
+ export declare class EngineClient {
8
+ private readonly engineUrl;
9
+ constructor(engineUrl: string);
10
+ fetchSchema(): Promise<SchemaResponse>;
11
+ fetchContent(collection: string): Promise<ContentListResponse>;
12
+ registerComponents(components: Record<string, ComponentDefinition>): Promise<void>;
13
+ }
14
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE3F,qBAAa,iBAAkB,SAAQ,KAAK;aAG1B,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;gBAF5B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM;CAK7B;AAED,qBAAa,YAAY;IACZ,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM;IAExC,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC;IAStC,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAa9D,kBAAkB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAexF"}
package/dist/client.js ADDED
@@ -0,0 +1,44 @@
1
+ export class EngineClientError extends Error {
2
+ status;
3
+ body;
4
+ constructor(message, status, body) {
5
+ super(message);
6
+ this.status = status;
7
+ this.body = body;
8
+ this.name = "EngineClientError";
9
+ }
10
+ }
11
+ export class EngineClient {
12
+ engineUrl;
13
+ constructor(engineUrl) {
14
+ this.engineUrl = engineUrl;
15
+ }
16
+ async fetchSchema() {
17
+ const res = await fetch(`${this.engineUrl}/api/schema`);
18
+ if (!res.ok) {
19
+ const body = await res.text();
20
+ throw new EngineClientError(`fetchSchema failed with status ${res.status}`, res.status, body);
21
+ }
22
+ return res.json();
23
+ }
24
+ async fetchContent(collection) {
25
+ const res = await fetch(`${this.engineUrl}/api/content/${collection}`);
26
+ if (!res.ok) {
27
+ const body = await res.text();
28
+ throw new EngineClientError(`fetchContent(${collection}) failed with status ${res.status}`, res.status, body);
29
+ }
30
+ return res.json();
31
+ }
32
+ async registerComponents(components) {
33
+ const res = await fetch(`${this.engineUrl}/api/schema/components`, {
34
+ method: "POST",
35
+ headers: { "Content-Type": "application/json" },
36
+ body: JSON.stringify(components),
37
+ });
38
+ if (!res.ok) {
39
+ const body = await res.text();
40
+ throw new EngineClientError(`registerComponents failed with status ${res.status}`, res.status, body);
41
+ }
42
+ }
43
+ }
44
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAG1B;IACA;IAHjB,YACC,OAAe,EACC,MAAc,EACd,IAAY;QAE5B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAQ;QAG5B,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IACjC,CAAC;CACD;AAED,MAAM,OAAO,YAAY;IACK;IAA7B,YAA6B,SAAiB;QAAjB,cAAS,GAAT,SAAS,CAAQ;IAAG,CAAC;IAElD,KAAK,CAAC,WAAW;QAChB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,aAAa,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,IAAI,iBAAiB,CAAC,kCAAkC,GAAG,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/F,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,EAA6B,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,UAAkB;QACpC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,gBAAgB,UAAU,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,IAAI,iBAAiB,CAC1B,gBAAgB,UAAU,wBAAwB,GAAG,CAAC,MAAM,EAAE,EAC9D,GAAG,CAAC,MAAM,EACV,IAAI,CACJ,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,EAAkC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,UAA+C;QACvE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,wBAAwB,EAAE;YAClE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;SAChC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,IAAI,iBAAiB,CAC1B,yCAAyC,GAAG,CAAC,MAAM,EAAE,EACrD,GAAG,CAAC,MAAM,EACV,IAAI,CACJ,CAAC;QACH,CAAC;IACF,CAAC;CACD"}
@@ -0,0 +1,12 @@
1
+ import type { EngineClient } from "./client.js";
2
+ import type { ComponentDefinition } from "./types.js";
3
+ export declare class ComponentRegistry {
4
+ private client;
5
+ private components;
6
+ constructor(client: EngineClient, components: Record<string, ComponentDefinition>);
7
+ /** POST components to engine so AI clients can query them */
8
+ register(): Promise<void>;
9
+ /** Return component definitions for local dev endpoint */
10
+ getSchema(): Record<string, ComponentDefinition>;
11
+ }
12
+ //# sourceMappingURL=component-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-registry.d.ts","sourceRoot":"","sources":["../src/component-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,qBAAa,iBAAiB;IAE5B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU;gBADV,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAGxD,6DAA6D;IACvD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,0DAA0D;IAC1D,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC;CAGhD"}
@@ -0,0 +1,17 @@
1
+ export class ComponentRegistry {
2
+ client;
3
+ components;
4
+ constructor(client, components) {
5
+ this.client = client;
6
+ this.components = components;
7
+ }
8
+ /** POST components to engine so AI clients can query them */
9
+ async register() {
10
+ await this.client.registerComponents(this.components);
11
+ }
12
+ /** Return component definitions for local dev endpoint */
13
+ getSchema() {
14
+ return this.components;
15
+ }
16
+ }
17
+ //# sourceMappingURL=component-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-registry.js","sourceRoot":"","sources":["../src/component-registry.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,iBAAiB;IAEpB;IACA;IAFT,YACS,MAAoB,EACpB,UAA+C;QAD/C,WAAM,GAAN,MAAM,CAAc;QACpB,eAAU,GAAV,UAAU,CAAqC;IACrD,CAAC;IAEJ,6DAA6D;IAC7D,KAAK,CAAC,QAAQ;QACb,MAAM,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvD,CAAC;IAED,0DAA0D;IAC1D,SAAS;QACR,OAAO,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;CACD"}
@@ -0,0 +1,23 @@
1
+ import type { EngineClient } from "./client.js";
2
+ export interface SyncResult {
3
+ synced: number;
4
+ collections: Record<string, number>;
5
+ errors: string[];
6
+ }
7
+ export interface FsOperations {
8
+ mkdir: (path: string, options?: {
9
+ recursive?: boolean;
10
+ }) => Promise<void>;
11
+ writeFile: (path: string, content: string, encoding: string) => Promise<void>;
12
+ }
13
+ export declare class ContentSyncer {
14
+ private client;
15
+ private srcDir;
16
+ private contentDir;
17
+ private fs;
18
+ constructor(client: EngineClient, srcDir: string, contentDir: string, fs?: FsOperations);
19
+ sync(collections: string[]): Promise<SyncResult>;
20
+ private resolveExtension;
21
+ private renderFile;
22
+ }
23
+ //# sourceMappingURL=content-syncer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-syncer.d.ts","sourceRoot":"","sources":["../src/content-syncer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E;AAoBD,qBAAa,aAAa;IAIxB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU;IALnB,OAAO,CAAC,EAAE,CAAe;gBAGhB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAC1B,EAAE,CAAC,EAAE,YAAY;IAUZ,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAuCtD,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,UAAU;CAWlB"}
@@ -0,0 +1,95 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ function serializeFrontmatter(frontmatter) {
4
+ const lines = [];
5
+ for (const [key, value] of Object.entries(frontmatter)) {
6
+ if (typeof value === "string") {
7
+ // Quote strings that contain special YAML characters
8
+ const needsQuotes = /[:#\[\]{}&*!,|>'"?]/.test(value) || value.includes("\n");
9
+ lines.push(needsQuotes ? `${key}: ${JSON.stringify(value)}` : `${key}: ${value}`);
10
+ }
11
+ else if (value === null || value === undefined) {
12
+ lines.push(`${key}: null`);
13
+ }
14
+ else if (typeof value === "boolean" || typeof value === "number") {
15
+ lines.push(`${key}: ${value}`);
16
+ }
17
+ else {
18
+ lines.push(`${key}: ${JSON.stringify(value)}`);
19
+ }
20
+ }
21
+ return lines.join("\n");
22
+ }
23
+ export class ContentSyncer {
24
+ client;
25
+ srcDir;
26
+ contentDir;
27
+ fs;
28
+ constructor(client, srcDir, contentDir, fs) {
29
+ this.client = client;
30
+ this.srcDir = srcDir;
31
+ this.contentDir = contentDir;
32
+ this.fs = fs ?? {
33
+ mkdir: async (path, options) => {
34
+ await mkdir(path, options);
35
+ },
36
+ writeFile: (path, content, encoding) => writeFile(path, content, encoding),
37
+ };
38
+ }
39
+ async sync(collections) {
40
+ const result = {
41
+ synced: 0,
42
+ collections: {},
43
+ errors: [],
44
+ };
45
+ for (const collection of collections) {
46
+ let count = 0;
47
+ try {
48
+ const contentList = await this.client.fetchContent(collection);
49
+ const collectionDir = join(this.srcDir, this.contentDir, collection);
50
+ await this.fs.mkdir(collectionDir, { recursive: true });
51
+ for (const item of contentList.items) {
52
+ try {
53
+ const ext = this.resolveExtension(item.path);
54
+ const filePath = join(collectionDir, `${item.slug}.${ext}`);
55
+ const fileContent = this.renderFile(item.frontmatter, item.body, ext);
56
+ await this.fs.writeFile(filePath, fileContent, "utf-8");
57
+ count++;
58
+ }
59
+ catch (err) {
60
+ const msg = err instanceof Error ? err.message : String(err);
61
+ result.errors.push(`${collection}/${item.slug}: ${msg}`);
62
+ }
63
+ }
64
+ }
65
+ catch (err) {
66
+ const msg = err instanceof Error ? err.message : String(err);
67
+ result.errors.push(`${collection}: ${msg}`);
68
+ }
69
+ result.collections[collection] = count;
70
+ result.synced += count;
71
+ }
72
+ return result;
73
+ }
74
+ resolveExtension(path) {
75
+ const match = path.match(/\.([a-z]+)$/i);
76
+ if (match) {
77
+ const ext = match[1].toLowerCase();
78
+ if (["mdx", "md", "yaml", "yml", "json"].includes(ext))
79
+ return ext;
80
+ }
81
+ return "mdx";
82
+ }
83
+ renderFile(frontmatter, body, ext) {
84
+ if (ext === "json") {
85
+ return `${JSON.stringify({ ...frontmatter, body }, null, 2)}\n`;
86
+ }
87
+ if (ext === "yaml" || ext === "yml") {
88
+ return `${serializeFrontmatter({ ...frontmatter, body })}\n`;
89
+ }
90
+ // mdx / md
91
+ const fm = serializeFrontmatter(frontmatter);
92
+ return `---\n${fm}\n---\n${body}`;
93
+ }
94
+ }
95
+ //# sourceMappingURL=content-syncer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-syncer.js","sourceRoot":"","sources":["../src/content-syncer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export { default as sourcepress } from "./integration.js";
2
+ export { default } from "./integration.js";
3
+ export { EngineClient } from "./client.js";
4
+ export { generateContentConfig } from "./schema-generator.js";
5
+ export { ComponentRegistry } from "./component-registry.js";
6
+ export { ContentSyncer } from "./content-syncer.js";
7
+ export type { SourcePressAstroOptions, ComponentDefinition } from "./types.js";
8
+ export type { SyncResult } from "./content-syncer.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC/E,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { default as sourcepress } from "./integration.js";
2
+ export { default } from "./integration.js";
3
+ export { EngineClient } from "./client.js";
4
+ export { generateContentConfig } from "./schema-generator.js";
5
+ export { ComponentRegistry } from "./component-registry.js";
6
+ export { ContentSyncer } from "./content-syncer.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { AstroIntegration } from "astro";
2
+ import type { SourcePressAstroOptions } from "./types.js";
3
+ export default function sourcepress(options: SourcePressAstroOptions): AstroIntegration;
4
+ //# sourceMappingURL=integration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAK9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CAmDtF"}
@@ -0,0 +1,52 @@
1
+ import { writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { EngineClient } from "./client.js";
4
+ import { ComponentRegistry } from "./component-registry.js";
5
+ import { ContentSyncer } from "./content-syncer.js";
6
+ import { generateContentConfig } from "./schema-generator.js";
7
+ export default function sourcepress(options) {
8
+ return {
9
+ name: "@sourcepress/astro",
10
+ hooks: {
11
+ "astro:config:setup": async ({ config, logger }) => {
12
+ const client = new EngineClient(options.engine);
13
+ const contentDir = options.contentDir ?? "content";
14
+ const configPath = options.configPath ?? "src/content.config.ts";
15
+ try {
16
+ // 1. Fetch schema from engine
17
+ logger.info("Fetching schema from engine...");
18
+ const schemaResponse = await client.fetchSchema();
19
+ // 2. Generate content.config.ts and write to configPath
20
+ // Cast to CollectionDefinition shape — fields may be unknown but generateContentConfig handles it
21
+ const collections = schemaResponse.collections;
22
+ const configSource = generateContentConfig(collections, contentDir);
23
+ const configFullPath = join(config.root.pathname, configPath);
24
+ await writeFile(configFullPath, configSource, "utf-8");
25
+ logger.info(`Generated ${configPath}`);
26
+ // 3. Sync content files via ContentSyncer
27
+ const srcDir = config.srcDir.pathname;
28
+ const syncer = new ContentSyncer(client, srcDir, contentDir);
29
+ const collectionNames = Object.keys(schemaResponse.collections);
30
+ const syncResult = await syncer.sync(collectionNames);
31
+ logger.info(`Synced ${syncResult.synced} files across ${collectionNames.length} collections`);
32
+ if (syncResult.errors.length > 0) {
33
+ for (const err of syncResult.errors) {
34
+ logger.warn(`Sync warning: ${err}`);
35
+ }
36
+ }
37
+ // 4. Register components if provided
38
+ if (options.components && Object.keys(options.components).length > 0) {
39
+ const registry = new ComponentRegistry(client, options.components);
40
+ await registry.register();
41
+ logger.info(`Registered ${Object.keys(options.components).length} components`);
42
+ }
43
+ }
44
+ catch (err) {
45
+ const message = err instanceof Error ? err.message : String(err);
46
+ logger.warn(`SourcePress sync failed: ${message}. Continuing without sync.`);
47
+ }
48
+ },
49
+ },
50
+ };
51
+ }
52
+ //# sourceMappingURL=integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.js","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,OAAgC;IACnE,OAAO;QACN,IAAI,EAAE,oBAAoB;QAC1B,KAAK,EAAE;YACN,oBAAoB,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;gBAClD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAChD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,SAAS,CAAC;gBACnD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,uBAAuB,CAAC;gBAEjE,IAAI,CAAC;oBACJ,8BAA8B;oBAC9B,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;oBAC9C,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;oBAElD,wDAAwD;oBACxD,kGAAkG;oBAClG,MAAM,WAAW,GAAG,cAAc,CAAC,WAE/B,CAAC;oBACL,MAAM,YAAY,GAAG,qBAAqB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;oBACpE,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;oBAC9D,MAAM,SAAS,CAAC,cAAc,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;oBACvD,MAAM,CAAC,IAAI,CAAC,aAAa,UAAU,EAAE,CAAC,CAAC;oBAEvC,0CAA0C;oBAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;oBACtC,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;oBAC7D,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;oBAChE,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;oBACtD,MAAM,CAAC,IAAI,CACV,UAAU,UAAU,CAAC,MAAM,iBAAiB,eAAe,CAAC,MAAM,cAAc,CAChF,CAAC;oBACF,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAClC,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;4BACrC,MAAM,CAAC,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;wBACrC,CAAC;oBACF,CAAC;oBAED,qCAAqC;oBACrC,IAAI,OAAO,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACtE,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;wBACnE,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;wBAC1B,MAAM,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,aAAa,CAAC,CAAC;oBAChF,CAAC;gBACF,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACjE,MAAM,CAAC,IAAI,CAAC,4BAA4B,OAAO,4BAA4B,CAAC,CAAC;gBAC9E,CAAC;YACF,CAAC;SACD;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CollectionDefinition } from "@sourcepress/core";
2
+ export declare function generateContentConfig(collections: Record<string, CollectionDefinition>, contentDir?: string): string;
3
+ //# sourceMappingURL=schema-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-generator.d.ts","sourceRoot":"","sources":["../src/schema-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAmB,MAAM,mBAAmB,CAAC;AA+C/E,wBAAgB,qBAAqB,CACpC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,EACjD,UAAU,SAAY,GACpB,MAAM,CA6BR"}
@@ -0,0 +1,77 @@
1
+ function fieldToZodCode(fieldDef) {
2
+ switch (fieldDef.type) {
3
+ case "string": {
4
+ if (fieldDef.default !== undefined) {
5
+ return `z.string().default(${JSON.stringify(fieldDef.default)})`;
6
+ }
7
+ if (!fieldDef.required)
8
+ return "z.string().optional()";
9
+ return "z.string()";
10
+ }
11
+ case "boolean": {
12
+ if (!fieldDef.required)
13
+ return "z.boolean().optional()";
14
+ return "z.boolean()";
15
+ }
16
+ case "number": {
17
+ if (!fieldDef.required)
18
+ return "z.number().optional()";
19
+ return "z.number()";
20
+ }
21
+ case "image": {
22
+ if (fieldDef.multiple) {
23
+ if (!fieldDef.required)
24
+ return "z.array(z.string()).optional()";
25
+ return "z.array(z.string())";
26
+ }
27
+ if (!fieldDef.required)
28
+ return "z.string().optional()";
29
+ return "z.string()";
30
+ }
31
+ case "relation-one": {
32
+ if (!fieldDef.required)
33
+ return "z.string().optional()";
34
+ return "z.string()";
35
+ }
36
+ case "relation-many": {
37
+ if (!fieldDef.required)
38
+ return "z.array(z.string()).optional()";
39
+ return "z.array(z.string())";
40
+ }
41
+ }
42
+ }
43
+ function collectionToSchemaCode(collection, contentDir) {
44
+ const lines = [];
45
+ for (const [fieldName, fieldDef] of Object.entries(collection.fields)) {
46
+ lines.push(` ${fieldName}: ${fieldToZodCode(fieldDef)},`);
47
+ }
48
+ const pattern = collection.format === "json" ? "**/*.json" : collection.format === "yaml" ? "**/*.{yaml,yml}" : "**/*.{md,mdx}";
49
+ return `defineCollection({\n loader: glob({ pattern: "${pattern}", base: "src/${contentDir}/${collection.name}" }),\n schema: z.object({\n${lines.join("\n")}\n }),\n})`;
50
+ }
51
+ export function generateContentConfig(collections, contentDir = "content") {
52
+ const entries = Object.entries(collections);
53
+ if (entries.length === 0) {
54
+ return [
55
+ `import { defineCollection, z } from 'astro:content';`,
56
+ "",
57
+ "export const collections = {};",
58
+ "",
59
+ ].join("\n");
60
+ }
61
+ const collectionBlocks = entries.map(([name, def]) => {
62
+ return `const ${name} = ${collectionToSchemaCode(def, contentDir)};`;
63
+ });
64
+ const exportsMap = entries.map(([name]) => ` ${name},`).join("\n");
65
+ return [
66
+ `import { defineCollection, z } from 'astro:content';`,
67
+ `import { glob } from 'astro/loaders';`,
68
+ "",
69
+ collectionBlocks.join("\n\n"),
70
+ "",
71
+ "export const collections = {",
72
+ exportsMap,
73
+ "};",
74
+ "",
75
+ ].join("\n");
76
+ }
77
+ //# sourceMappingURL=schema-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-generator.js","sourceRoot":"","sources":["../src/schema-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export interface ComponentDefinition {
2
+ description: string;
3
+ props: Record<string, string>;
4
+ }
5
+ export interface SourcePressAstroOptions {
6
+ /** URL of the Content Engine, e.g. 'http://localhost:3000' */
7
+ engine: string;
8
+ /** UI components available for AI content generation */
9
+ components?: Record<string, ComponentDefinition>;
10
+ /** Directory to sync content into, relative to Astro srcDir. Default: 'content' */
11
+ contentDir?: string;
12
+ /** Path to generate content.config.ts. Default: 'src/content.config.ts' */
13
+ configPath?: string;
14
+ }
15
+ /** Schema response from GET /api/schema */
16
+ export interface SchemaResponse {
17
+ collections: Record<string, {
18
+ name: string;
19
+ path: string;
20
+ format: string;
21
+ fields: Record<string, unknown>;
22
+ }>;
23
+ total: number;
24
+ }
25
+ /** Content list response from GET /api/content/:collection */
26
+ export interface ContentListResponse {
27
+ items: Array<{
28
+ slug: string;
29
+ path: string;
30
+ frontmatter: Record<string, unknown>;
31
+ body: string;
32
+ }>;
33
+ total: number;
34
+ }
35
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACvC,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IACjD,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC9B,WAAW,EAAE,MAAM,CAClB,MAAM,EACN;QACC,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAChC,CACD,CAAC;IACF,KAAK,EAAE,MAAM,CAAC;CACd;AAED,8DAA8D;AAC9D,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,IAAI,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;IACH,KAAK,EAAE,MAAM,CAAC;CACd"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}