clawfire 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 (87) hide show
  1. package/README.md +182 -0
  2. package/dist/admin.cjs +309 -0
  3. package/dist/admin.cjs.map +1 -0
  4. package/dist/admin.d.cts +93 -0
  5. package/dist/admin.d.ts +93 -0
  6. package/dist/admin.js +274 -0
  7. package/dist/admin.js.map +1 -0
  8. package/dist/auth-DQ3cifhb.d.cts +55 -0
  9. package/dist/auth-DtnUPbXT.d.ts +55 -0
  10. package/dist/chunk-37Y2XI7X.js +75 -0
  11. package/dist/chunk-YGIPORYL.js +339 -0
  12. package/dist/cli.js +241 -0
  13. package/dist/client.cjs +97 -0
  14. package/dist/client.cjs.map +1 -0
  15. package/dist/client.d.cts +4 -0
  16. package/dist/client.d.ts +4 -0
  17. package/dist/client.js +68 -0
  18. package/dist/client.js.map +1 -0
  19. package/dist/codegen.cjs +648 -0
  20. package/dist/codegen.cjs.map +1 -0
  21. package/dist/codegen.d.cts +25 -0
  22. package/dist/codegen.d.ts +25 -0
  23. package/dist/codegen.js +617 -0
  24. package/dist/codegen.js.map +1 -0
  25. package/dist/config-QMBJRn9G.d.cts +46 -0
  26. package/dist/config-QMBJRn9G.d.ts +46 -0
  27. package/dist/dev-server-QAVWINAT.js +973 -0
  28. package/dist/dev.cjs +1388 -0
  29. package/dist/dev.cjs.map +1 -0
  30. package/dist/dev.d.cts +111 -0
  31. package/dist/dev.d.ts +111 -0
  32. package/dist/dev.js +1349 -0
  33. package/dist/dev.js.map +1 -0
  34. package/dist/discover-BPMAZFBD.js +9 -0
  35. package/dist/discover-DYNqz_ym.d.cts +28 -0
  36. package/dist/discover-DYNqz_ym.d.ts +28 -0
  37. package/dist/errors-s_mP7rs9.d.cts +33 -0
  38. package/dist/errors-s_mP7rs9.d.ts +33 -0
  39. package/dist/functions.cjs +1156 -0
  40. package/dist/functions.cjs.map +1 -0
  41. package/dist/functions.d.cts +115 -0
  42. package/dist/functions.d.ts +115 -0
  43. package/dist/functions.js +1108 -0
  44. package/dist/functions.js.map +1 -0
  45. package/dist/hosting-7WVFHAYJ.js +85 -0
  46. package/dist/html-PCUCJGBH.js +7 -0
  47. package/dist/index.cjs +349 -0
  48. package/dist/index.cjs.map +1 -0
  49. package/dist/index.d.cts +22 -0
  50. package/dist/index.d.ts +22 -0
  51. package/dist/index.js +312 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/playground.cjs +364 -0
  54. package/dist/playground.cjs.map +1 -0
  55. package/dist/playground.d.cts +12 -0
  56. package/dist/playground.d.ts +12 -0
  57. package/dist/playground.js +337 -0
  58. package/dist/playground.js.map +1 -0
  59. package/dist/router-BVB_I-tu.d.ts +65 -0
  60. package/dist/router-Cikk8Heq.d.cts +65 -0
  61. package/dist/schema-BJsictSV.d.cts +172 -0
  62. package/dist/schema-BJsictSV.d.ts +172 -0
  63. package/package.json +150 -0
  64. package/templates/CLAUDE.md +71 -0
  65. package/templates/app/routes/auth/login.ts +35 -0
  66. package/templates/app/routes/health.ts +20 -0
  67. package/templates/app/schemas/user.ts +26 -0
  68. package/templates/clawfire.config.ts +25 -0
  69. package/templates/functions/index.ts +43 -0
  70. package/templates/starter/.claude/skills/clawfire-api/SKILL.md +131 -0
  71. package/templates/starter/.claude/skills/clawfire-auth/SKILL.md +111 -0
  72. package/templates/starter/.claude/skills/clawfire-deploy/SKILL.md +95 -0
  73. package/templates/starter/.claude/skills/clawfire-diagnose/SKILL.md +99 -0
  74. package/templates/starter/.claude/skills/clawfire-model/SKILL.md +128 -0
  75. package/templates/starter/CLAUDE.md +227 -0
  76. package/templates/starter/app/routes/health.ts +20 -0
  77. package/templates/starter/app/routes/todos/create.ts +25 -0
  78. package/templates/starter/app/routes/todos/delete.ts +20 -0
  79. package/templates/starter/app/routes/todos/list.ts +26 -0
  80. package/templates/starter/app/routes/todos/update.ts +32 -0
  81. package/templates/starter/app/schemas/todo.ts +16 -0
  82. package/templates/starter/app/store.ts +56 -0
  83. package/templates/starter/clawfire.config.ts +25 -0
  84. package/templates/starter/dev.ts +12 -0
  85. package/templates/starter/package.json +19 -0
  86. package/templates/starter/public/index.html +365 -0
  87. package/templates/starter/tsconfig.json +17 -0
@@ -0,0 +1,172 @@
1
+ import { ZodType, z, ZodObject, ZodRawShape } from 'zod';
2
+
3
+ /**
4
+ * Clawfire Schema & Contract System
5
+ *
6
+ * 모든 API는 input/output schema + meta + handler로 구성된 "계약(Contract)"으로 정의됩니다.
7
+ * Zod를 사용하여 타입 안전성과 런타임 검증을 동시에 보장합니다.
8
+ */
9
+
10
+ /** 인증 컨텍스트 */
11
+ interface AuthContext {
12
+ uid: string;
13
+ email?: string;
14
+ emailVerified?: boolean;
15
+ role?: string;
16
+ customClaims?: Record<string, unknown>;
17
+ token?: string;
18
+ }
19
+ /** API 핸들러에 전달되는 컨텍스트 */
20
+ interface HandlerContext {
21
+ auth: AuthContext | null;
22
+ /** 재인증 여부 (민감 작업용) */
23
+ reauthenticated?: boolean;
24
+ /** 원본 요청 헤더 */
25
+ headers?: Record<string, string>;
26
+ /** 요청 IP */
27
+ ip?: string;
28
+ }
29
+ /** 권한 수준 */
30
+ type AuthLevel = "public" | "authenticated" | "role" | "reauth";
31
+ /** API 메타데이터 */
32
+ interface APIMeta {
33
+ /** API 설명 (AI/Playground용) */
34
+ description: string;
35
+ /** 태그 (그룹화용) */
36
+ tags?: string[];
37
+ /** 인증 요구 수준 */
38
+ auth?: AuthLevel;
39
+ /** 필요 역할 (auth가 'role'일 때) */
40
+ roles?: string[];
41
+ /** 재인증 필요 여부 */
42
+ reauth?: boolean;
43
+ /** Rate limit (초당 요청 수) */
44
+ rateLimit?: number;
45
+ /** 비활성화 여부 */
46
+ deprecated?: boolean;
47
+ /** 예시 입력값 */
48
+ exampleInput?: unknown;
49
+ /** 예시 출력값 */
50
+ exampleOutput?: unknown;
51
+ }
52
+ /** API 계약 정의 */
53
+ interface APIContract<TInput extends ZodType = ZodType, TOutput extends ZodType = ZodType> {
54
+ /** 입력 스키마 */
55
+ input: TInput;
56
+ /** 출력 스키마 */
57
+ output: TOutput;
58
+ /** 메타데이터 */
59
+ meta: APIMeta;
60
+ /** 핸들러 함수 */
61
+ handler: (input: z.infer<TInput>, ctx: HandlerContext) => Promise<z.infer<TOutput>>;
62
+ }
63
+ /** 모델 필드 정의 */
64
+ interface ModelField {
65
+ type: "string" | "number" | "boolean" | "timestamp" | "array" | "map" | "reference" | "geopoint";
66
+ required?: boolean;
67
+ description?: string;
68
+ default?: unknown;
69
+ /** 배열 아이템 타입 */
70
+ items?: ModelField;
71
+ /** 맵 값 타입 */
72
+ values?: ModelField;
73
+ /** 참조 대상 컬렉션 */
74
+ ref?: string;
75
+ /** enum 값 리스트 */
76
+ enum?: string[];
77
+ }
78
+ /** 모델 정의 */
79
+ interface ModelDefinition {
80
+ /** 컬렉션 이름 */
81
+ collection: string;
82
+ /** 필드 정의 */
83
+ fields: Record<string, ModelField>;
84
+ /** 서브컬렉션 */
85
+ subcollections?: Record<string, ModelDefinition>;
86
+ /** 인덱스 */
87
+ indexes?: ModelIndex[];
88
+ /** 보안 규칙 */
89
+ rules?: ModelRules;
90
+ /** 타임스탬프 자동 생성 */
91
+ timestamps?: boolean;
92
+ /** 소프트 삭제 */
93
+ softDelete?: boolean;
94
+ }
95
+ /** Firestore 인덱스 */
96
+ interface ModelIndex {
97
+ fields: Array<{
98
+ field: string;
99
+ order?: "asc" | "desc";
100
+ }>;
101
+ }
102
+ /** 모델 보안 규칙 */
103
+ interface ModelRules {
104
+ read?: AuthLevel;
105
+ create?: AuthLevel;
106
+ update?: AuthLevel;
107
+ delete?: AuthLevel;
108
+ readRoles?: string[];
109
+ createRoles?: string[];
110
+ updateRoles?: string[];
111
+ deleteRoles?: string[];
112
+ /** 소유자만 읽기/쓰기 가능 필드 */
113
+ ownerField?: string;
114
+ }
115
+ /**
116
+ * API 계약 정의
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * export default defineAPI({
121
+ * input: z.object({ name: z.string() }),
122
+ * output: z.object({ id: z.string(), name: z.string() }),
123
+ * meta: { description: "상품 생성", auth: "authenticated" },
124
+ * handler: async (input, ctx) => {
125
+ * const id = await db.create("products", input);
126
+ * return { id, ...input };
127
+ * }
128
+ * });
129
+ * ```
130
+ */
131
+ declare function defineAPI<TInput extends ZodType, TOutput extends ZodType>(contract: APIContract<TInput, TOutput>): APIContract<TInput, TOutput>;
132
+ /**
133
+ * 모델(Firestore 컬렉션) 정의
134
+ *
135
+ * @example
136
+ * ```ts
137
+ * export const Product = defineModel({
138
+ * collection: "products",
139
+ * fields: {
140
+ * name: { type: "string", required: true },
141
+ * price: { type: "number", required: true },
142
+ * tags: { type: "array", items: { type: "string" } },
143
+ * },
144
+ * timestamps: true,
145
+ * rules: { read: "public", create: "authenticated" }
146
+ * });
147
+ * ```
148
+ */
149
+ declare function defineModel(definition: ModelDefinition): ModelDefinition;
150
+ /** Zod 스키마에서 JSON Schema 생성 (Playground/문서용) */
151
+ declare function zodToJsonSchema(schema: ZodType): Record<string, unknown>;
152
+ /** 모델 정의에서 Zod 스키마 자동 생성 */
153
+ declare function modelToZodSchema(model: ModelDefinition): ZodObject<ZodRawShape>;
154
+ /** API 매니페스트 항목 */
155
+ interface ManifestEntry {
156
+ path: string;
157
+ method: "POST";
158
+ meta: APIMeta;
159
+ inputSchema: Record<string, unknown>;
160
+ outputSchema: Record<string, unknown>;
161
+ }
162
+ /** 전체 매니페스트 */
163
+ interface Manifest {
164
+ version: string;
165
+ generatedAt: string;
166
+ apis: ManifestEntry[];
167
+ models: Record<string, ModelDefinition>;
168
+ }
169
+ /** 계약에서 매니페스트 항목 생성 */
170
+ declare function contractToManifest(path: string, contract: APIContract): ManifestEntry;
171
+
172
+ export { type APIContract as A, type HandlerContext as H, type Manifest as M, type APIMeta as a, type AuthContext as b, type AuthLevel as c, type ManifestEntry as d, type ModelDefinition as e, type ModelField as f, defineAPI as g, defineModel as h, type ModelIndex as i, type ModelRules as j, contractToManifest as k, modelToZodSchema as m, zodToJsonSchema as z };
@@ -0,0 +1,172 @@
1
+ import { ZodType, z, ZodObject, ZodRawShape } from 'zod';
2
+
3
+ /**
4
+ * Clawfire Schema & Contract System
5
+ *
6
+ * 모든 API는 input/output schema + meta + handler로 구성된 "계약(Contract)"으로 정의됩니다.
7
+ * Zod를 사용하여 타입 안전성과 런타임 검증을 동시에 보장합니다.
8
+ */
9
+
10
+ /** 인증 컨텍스트 */
11
+ interface AuthContext {
12
+ uid: string;
13
+ email?: string;
14
+ emailVerified?: boolean;
15
+ role?: string;
16
+ customClaims?: Record<string, unknown>;
17
+ token?: string;
18
+ }
19
+ /** API 핸들러에 전달되는 컨텍스트 */
20
+ interface HandlerContext {
21
+ auth: AuthContext | null;
22
+ /** 재인증 여부 (민감 작업용) */
23
+ reauthenticated?: boolean;
24
+ /** 원본 요청 헤더 */
25
+ headers?: Record<string, string>;
26
+ /** 요청 IP */
27
+ ip?: string;
28
+ }
29
+ /** 권한 수준 */
30
+ type AuthLevel = "public" | "authenticated" | "role" | "reauth";
31
+ /** API 메타데이터 */
32
+ interface APIMeta {
33
+ /** API 설명 (AI/Playground용) */
34
+ description: string;
35
+ /** 태그 (그룹화용) */
36
+ tags?: string[];
37
+ /** 인증 요구 수준 */
38
+ auth?: AuthLevel;
39
+ /** 필요 역할 (auth가 'role'일 때) */
40
+ roles?: string[];
41
+ /** 재인증 필요 여부 */
42
+ reauth?: boolean;
43
+ /** Rate limit (초당 요청 수) */
44
+ rateLimit?: number;
45
+ /** 비활성화 여부 */
46
+ deprecated?: boolean;
47
+ /** 예시 입력값 */
48
+ exampleInput?: unknown;
49
+ /** 예시 출력값 */
50
+ exampleOutput?: unknown;
51
+ }
52
+ /** API 계약 정의 */
53
+ interface APIContract<TInput extends ZodType = ZodType, TOutput extends ZodType = ZodType> {
54
+ /** 입력 스키마 */
55
+ input: TInput;
56
+ /** 출력 스키마 */
57
+ output: TOutput;
58
+ /** 메타데이터 */
59
+ meta: APIMeta;
60
+ /** 핸들러 함수 */
61
+ handler: (input: z.infer<TInput>, ctx: HandlerContext) => Promise<z.infer<TOutput>>;
62
+ }
63
+ /** 모델 필드 정의 */
64
+ interface ModelField {
65
+ type: "string" | "number" | "boolean" | "timestamp" | "array" | "map" | "reference" | "geopoint";
66
+ required?: boolean;
67
+ description?: string;
68
+ default?: unknown;
69
+ /** 배열 아이템 타입 */
70
+ items?: ModelField;
71
+ /** 맵 값 타입 */
72
+ values?: ModelField;
73
+ /** 참조 대상 컬렉션 */
74
+ ref?: string;
75
+ /** enum 값 리스트 */
76
+ enum?: string[];
77
+ }
78
+ /** 모델 정의 */
79
+ interface ModelDefinition {
80
+ /** 컬렉션 이름 */
81
+ collection: string;
82
+ /** 필드 정의 */
83
+ fields: Record<string, ModelField>;
84
+ /** 서브컬렉션 */
85
+ subcollections?: Record<string, ModelDefinition>;
86
+ /** 인덱스 */
87
+ indexes?: ModelIndex[];
88
+ /** 보안 규칙 */
89
+ rules?: ModelRules;
90
+ /** 타임스탬프 자동 생성 */
91
+ timestamps?: boolean;
92
+ /** 소프트 삭제 */
93
+ softDelete?: boolean;
94
+ }
95
+ /** Firestore 인덱스 */
96
+ interface ModelIndex {
97
+ fields: Array<{
98
+ field: string;
99
+ order?: "asc" | "desc";
100
+ }>;
101
+ }
102
+ /** 모델 보안 규칙 */
103
+ interface ModelRules {
104
+ read?: AuthLevel;
105
+ create?: AuthLevel;
106
+ update?: AuthLevel;
107
+ delete?: AuthLevel;
108
+ readRoles?: string[];
109
+ createRoles?: string[];
110
+ updateRoles?: string[];
111
+ deleteRoles?: string[];
112
+ /** 소유자만 읽기/쓰기 가능 필드 */
113
+ ownerField?: string;
114
+ }
115
+ /**
116
+ * API 계약 정의
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * export default defineAPI({
121
+ * input: z.object({ name: z.string() }),
122
+ * output: z.object({ id: z.string(), name: z.string() }),
123
+ * meta: { description: "상품 생성", auth: "authenticated" },
124
+ * handler: async (input, ctx) => {
125
+ * const id = await db.create("products", input);
126
+ * return { id, ...input };
127
+ * }
128
+ * });
129
+ * ```
130
+ */
131
+ declare function defineAPI<TInput extends ZodType, TOutput extends ZodType>(contract: APIContract<TInput, TOutput>): APIContract<TInput, TOutput>;
132
+ /**
133
+ * 모델(Firestore 컬렉션) 정의
134
+ *
135
+ * @example
136
+ * ```ts
137
+ * export const Product = defineModel({
138
+ * collection: "products",
139
+ * fields: {
140
+ * name: { type: "string", required: true },
141
+ * price: { type: "number", required: true },
142
+ * tags: { type: "array", items: { type: "string" } },
143
+ * },
144
+ * timestamps: true,
145
+ * rules: { read: "public", create: "authenticated" }
146
+ * });
147
+ * ```
148
+ */
149
+ declare function defineModel(definition: ModelDefinition): ModelDefinition;
150
+ /** Zod 스키마에서 JSON Schema 생성 (Playground/문서용) */
151
+ declare function zodToJsonSchema(schema: ZodType): Record<string, unknown>;
152
+ /** 모델 정의에서 Zod 스키마 자동 생성 */
153
+ declare function modelToZodSchema(model: ModelDefinition): ZodObject<ZodRawShape>;
154
+ /** API 매니페스트 항목 */
155
+ interface ManifestEntry {
156
+ path: string;
157
+ method: "POST";
158
+ meta: APIMeta;
159
+ inputSchema: Record<string, unknown>;
160
+ outputSchema: Record<string, unknown>;
161
+ }
162
+ /** 전체 매니페스트 */
163
+ interface Manifest {
164
+ version: string;
165
+ generatedAt: string;
166
+ apis: ManifestEntry[];
167
+ models: Record<string, ModelDefinition>;
168
+ }
169
+ /** 계약에서 매니페스트 항목 생성 */
170
+ declare function contractToManifest(path: string, contract: APIContract): ManifestEntry;
171
+
172
+ export { type APIContract as A, type HandlerContext as H, type Manifest as M, type APIMeta as a, type AuthContext as b, type AuthLevel as c, type ManifestEntry as d, type ModelDefinition as e, type ModelField as f, defineAPI as g, defineModel as h, type ModelIndex as i, type ModelRules as j, contractToManifest as k, modelToZodSchema as m, zodToJsonSchema as z };
package/package.json ADDED
@@ -0,0 +1,150 @@
1
+ {
2
+ "name": "clawfire",
3
+ "version": "0.1.0",
4
+ "description": "AI-First Firebase app framework — Speak. Build. Deploy.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "./client": {
21
+ "import": {
22
+ "types": "./dist/client.d.ts",
23
+ "default": "./dist/client.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/client.d.cts",
27
+ "default": "./dist/client.cjs"
28
+ }
29
+ },
30
+ "./functions": {
31
+ "import": {
32
+ "types": "./dist/functions.d.ts",
33
+ "default": "./dist/functions.js"
34
+ },
35
+ "require": {
36
+ "types": "./dist/functions.d.cts",
37
+ "default": "./dist/functions.cjs"
38
+ }
39
+ },
40
+ "./admin": {
41
+ "import": {
42
+ "types": "./dist/admin.d.ts",
43
+ "default": "./dist/admin.js"
44
+ },
45
+ "require": {
46
+ "types": "./dist/admin.d.cts",
47
+ "default": "./dist/admin.cjs"
48
+ }
49
+ },
50
+ "./codegen": {
51
+ "import": {
52
+ "types": "./dist/codegen.d.ts",
53
+ "default": "./dist/codegen.js"
54
+ },
55
+ "require": {
56
+ "types": "./dist/codegen.d.cts",
57
+ "default": "./dist/codegen.cjs"
58
+ }
59
+ },
60
+ "./playground": {
61
+ "import": {
62
+ "types": "./dist/playground.d.ts",
63
+ "default": "./dist/playground.js"
64
+ },
65
+ "require": {
66
+ "types": "./dist/playground.d.cts",
67
+ "default": "./dist/playground.cjs"
68
+ }
69
+ },
70
+ "./dev": {
71
+ "import": {
72
+ "types": "./dist/dev.d.ts",
73
+ "default": "./dist/dev.js"
74
+ },
75
+ "require": {
76
+ "types": "./dist/dev.d.cts",
77
+ "default": "./dist/dev.cjs"
78
+ }
79
+ }
80
+ },
81
+ "bin": {
82
+ "clawfire": "./dist/cli.js"
83
+ },
84
+ "files": [
85
+ "dist",
86
+ "templates",
87
+ "README.md"
88
+ ],
89
+ "scripts": {
90
+ "build": "tsup",
91
+ "dev": "tsup --watch",
92
+ "typecheck": "tsc --noEmit",
93
+ "prepublishOnly": "npm run build",
94
+ "release": "source .env && npm publish --access public"
95
+ },
96
+ "keywords": [
97
+ "firebase",
98
+ "ai",
99
+ "framework",
100
+ "no-code",
101
+ "clawfire",
102
+ "firestore",
103
+ "functions",
104
+ "hosting",
105
+ "zod",
106
+ "schema",
107
+ "api",
108
+ "contract"
109
+ ],
110
+ "author": "nohsangwoo <nsgr12@naver.com>",
111
+ "repository": {
112
+ "type": "git",
113
+ "url": "git+https://github.com/nohsangwoo/clawfire.git"
114
+ },
115
+ "homepage": "https://github.com/nohsangwoo/clawfire#readme",
116
+ "bugs": {
117
+ "url": "https://github.com/nohsangwoo/clawfire/issues"
118
+ },
119
+ "license": "MIT",
120
+ "dependencies": {
121
+ "zod": "^3.23.0"
122
+ },
123
+ "peerDependencies": {
124
+ "firebase": "^10.0.0 || ^11.0.0",
125
+ "firebase-admin": "^12.0.0 || ^13.0.0",
126
+ "firebase-functions": "^5.0.0 || ^6.0.0"
127
+ },
128
+ "peerDependenciesMeta": {
129
+ "firebase": {
130
+ "optional": true
131
+ },
132
+ "firebase-admin": {
133
+ "optional": true
134
+ },
135
+ "firebase-functions": {
136
+ "optional": true
137
+ }
138
+ },
139
+ "devDependencies": {
140
+ "tsup": "^8.0.0",
141
+ "typescript": "^5.5.0",
142
+ "firebase": "^11.0.0",
143
+ "firebase-admin": "^13.0.0",
144
+ "firebase-functions": "^6.0.0",
145
+ "@types/node": "^20.0.0"
146
+ },
147
+ "engines": {
148
+ "node": ">=18.0.0"
149
+ }
150
+ }
@@ -0,0 +1,71 @@
1
+ # Clawfire Project
2
+
3
+ This is a Clawfire project — an AI-First Firebase app framework.
4
+ **"Speak. Build. Deploy."**
5
+
6
+ ## Stack (Fixed — do not change)
7
+ - DB: Firestore
8
+ - Auth: Firebase Auth
9
+ - Hosting: Firebase Hosting
10
+ - Backend: Firebase Functions
11
+ - Schema: Zod
12
+ - Language: TypeScript
13
+ - Framework: Clawfire
14
+
15
+ ## Project Structure
16
+ ```
17
+ app/
18
+ routes/ ← API route handlers (file-based routing)
19
+ schemas/ ← Model definitions (Firestore collections)
20
+ generated/ ← Auto-generated files (DO NOT EDIT)
21
+ api-client.ts ← Typed API client
22
+ manifest.json ← API manifest
23
+ functions/ ← Firebase Functions entry point
24
+ public/ ← Static files for Firebase Hosting
25
+ firebase.json ← Firebase config
26
+ firestore.rules ← Firestore security rules
27
+ clawfire.config.ts ← Clawfire configuration
28
+ ```
29
+
30
+ ## Commands (AI Skills)
31
+ - `/clawfire-init` — Initialize project / connect Firebase
32
+ - `/clawfire-model` — Create/modify data models
33
+ - `/clawfire-api` — Create/modify APIs
34
+ - `/clawfire-auth` — Configure authentication & authorization
35
+ - `/clawfire-deploy` — Deploy to Firebase
36
+ - `/clawfire-diagnose` — Diagnose and fix issues
37
+
38
+ ## Key Patterns
39
+
40
+ ### API Definition
41
+ All APIs use `defineAPI` with input/output Zod schemas:
42
+ ```ts
43
+ import { defineAPI, z } from "clawfire";
44
+ export default defineAPI({
45
+ input: z.object({ ... }),
46
+ output: z.object({ ... }),
47
+ meta: { description: "...", auth: "authenticated" },
48
+ handler: async (input, ctx) => { ... },
49
+ });
50
+ ```
51
+
52
+ ### Model Definition
53
+ All Firestore collections use `defineModel`:
54
+ ```ts
55
+ import { defineModel } from "clawfire";
56
+ export const Product = defineModel({
57
+ collection: "products",
58
+ fields: { ... },
59
+ timestamps: true,
60
+ rules: { read: "public", create: "authenticated" },
61
+ });
62
+ ```
63
+
64
+ ### All APIs are POST
65
+ Clawfire does not use HTTP methods. Everything is POST with JSON body.
66
+
67
+ ### Auth Levels
68
+ - `public` — No auth required
69
+ - `authenticated` — Login required
70
+ - `role` — Specific role required
71
+ - `reauth` — Recent re-authentication required
@@ -0,0 +1,35 @@
1
+ import { defineAPI, z, Errors } from "clawfire";
2
+
3
+ export default defineAPI({
4
+ input: z.object({
5
+ idToken: z.string().min(1),
6
+ }),
7
+ output: z.object({
8
+ uid: z.string(),
9
+ email: z.string().optional(),
10
+ role: z.string().optional(),
11
+ displayName: z.string().optional(),
12
+ }),
13
+ meta: {
14
+ description: "Verify Firebase ID token and return user info",
15
+ auth: "public",
16
+ tags: ["auth"],
17
+ exampleInput: {
18
+ idToken: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
19
+ },
20
+ },
21
+ handler: async (input, ctx) => {
22
+ // In real implementation, this would use verifyToken from clawfire/functions
23
+ // and the Firebase Admin Auth instance
24
+ if (!input.idToken) {
25
+ throw Errors.unauthorized("No token provided");
26
+ }
27
+
28
+ return {
29
+ uid: "placeholder-uid",
30
+ email: "user@example.com",
31
+ role: "user",
32
+ displayName: "User",
33
+ };
34
+ },
35
+ });
@@ -0,0 +1,20 @@
1
+ import { defineAPI, z } from "clawfire";
2
+
3
+ export default defineAPI({
4
+ input: z.object({}),
5
+ output: z.object({
6
+ status: z.string(),
7
+ timestamp: z.string(),
8
+ version: z.string(),
9
+ }),
10
+ meta: {
11
+ description: "Health check endpoint",
12
+ auth: "public",
13
+ tags: ["system"],
14
+ },
15
+ handler: async () => ({
16
+ status: "ok",
17
+ timestamp: new Date().toISOString(),
18
+ version: "1.0.0",
19
+ }),
20
+ });
@@ -0,0 +1,26 @@
1
+ import { defineModel } from "clawfire";
2
+
3
+ export const User = defineModel({
4
+ collection: "users",
5
+ fields: {
6
+ email: { type: "string", required: true, description: "User email" },
7
+ displayName: { type: "string", required: true, description: "Display name" },
8
+ role: {
9
+ type: "string",
10
+ required: true,
11
+ enum: ["user", "admin", "editor"],
12
+ description: "User role",
13
+ },
14
+ photoURL: { type: "string", description: "Profile photo URL" },
15
+ bio: { type: "string", description: "User bio" },
16
+ },
17
+ timestamps: true,
18
+ rules: {
19
+ read: "authenticated",
20
+ create: "authenticated",
21
+ update: "authenticated",
22
+ delete: "role",
23
+ deleteRoles: ["admin"],
24
+ ownerField: "uid",
25
+ },
26
+ });
@@ -0,0 +1,25 @@
1
+ import { configureClawfire } from "clawfire";
2
+
3
+ export default configureClawfire({
4
+ firebase: {
5
+ apiKey: "YOUR_API_KEY",
6
+ authDomain: "YOUR_PROJECT.firebaseapp.com",
7
+ projectId: "YOUR_PROJECT_ID",
8
+ storageBucket: "YOUR_PROJECT.firebasestorage.app",
9
+ appId: "YOUR_APP_ID",
10
+ },
11
+ server: {
12
+ region: "us-central1",
13
+ cors: [],
14
+ rateLimit: 100,
15
+ },
16
+ security: {
17
+ validateInput: true,
18
+ safeHeaders: true,
19
+ maskLogs: true,
20
+ },
21
+ playground: {
22
+ enabled: true,
23
+ path: "/__playground",
24
+ },
25
+ });