ignotum 0.0.0 → 0.0.2

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 (57) hide show
  1. package/README.md +161 -0
  2. package/dist/cli/bin.d.mts +1 -0
  3. package/dist/cli/bin.mjs +1696 -0
  4. package/dist/cli/bin.mjs.map +1 -0
  5. package/dist/runtime/api-BXXIZc_Q.js +119 -0
  6. package/dist/runtime/api-BXXIZc_Q.js.map +1 -0
  7. package/dist/runtime/api-Cpx57mk3.d.ts +47 -0
  8. package/dist/runtime/client/jsx-dev-runtime.d.ts +2 -0
  9. package/dist/runtime/client/jsx-dev-runtime.js +2 -0
  10. package/dist/runtime/client/jsx-runtime.d.ts +2 -0
  11. package/dist/runtime/client/jsx-runtime.js +2 -0
  12. package/dist/runtime/client.d.ts +29 -0
  13. package/dist/runtime/client.js +364 -0
  14. package/dist/runtime/client.js.map +1 -0
  15. package/dist/runtime/index-BgWROoyk.d.ts +249 -0
  16. package/dist/runtime/internal/api.d.ts +2 -0
  17. package/dist/runtime/internal/api.js +2 -0
  18. package/dist/runtime/internal/server.d.ts +6 -0
  19. package/dist/runtime/internal/server.js +7 -0
  20. package/dist/runtime/internal/server.js.map +1 -0
  21. package/dist/runtime/internal/types.d.ts +2 -0
  22. package/dist/runtime/internal/types.js +2 -0
  23. package/dist/runtime/result-B2W-z2wG.js +136 -0
  24. package/dist/runtime/result-B2W-z2wG.js.map +1 -0
  25. package/dist/runtime/result-C1ZdsM6Y.d.ts +106 -0
  26. package/dist/runtime/schema-CNEVLF7D.js +116 -0
  27. package/dist/runtime/schema-CNEVLF7D.js.map +1 -0
  28. package/dist/runtime/server.d.ts +9 -0
  29. package/dist/runtime/server.js +9 -0
  30. package/dist/runtime/server.js.map +1 -0
  31. package/package.json +81 -2
  32. package/src/cli/agent-files.ts +35 -0
  33. package/src/cli/bin.ts +5 -0
  34. package/src/cli/client-plugin.ts +66 -0
  35. package/src/cli/codegen.ts +203 -0
  36. package/src/cli/command.ts +155 -0
  37. package/src/cli/dev.ts +206 -0
  38. package/src/cli/new-project.ts +377 -0
  39. package/src/cli/package-manager.ts +55 -0
  40. package/src/client/errors.ts +83 -0
  41. package/src/client/hooks.ts +141 -0
  42. package/src/client/index.ts +90 -0
  43. package/src/client/jsx-dev-runtime.ts +2 -0
  44. package/src/client/jsx-runtime.ts +2 -0
  45. package/src/client/query.ts +17 -0
  46. package/src/client/sync.ts +487 -0
  47. package/src/dev-runtime/database.ts +374 -0
  48. package/src/dev-runtime/dev-database.ts +199 -0
  49. package/src/dev-runtime/functions.ts +293 -0
  50. package/src/dev-runtime/id.ts +11 -0
  51. package/src/dev-runtime/sync.ts +473 -0
  52. package/src/internal/api.ts +141 -0
  53. package/src/internal/http-paths.ts +5 -0
  54. package/src/internal/server.ts +3 -0
  55. package/src/internal/types.ts +2 -0
  56. package/src/raw.d.ts +4 -0
  57. package/src/server/index.ts +8 -0
@@ -0,0 +1,116 @@
1
+ import { t as ErrorBrand } from "./result-B2W-z2wG.js";
2
+ import { Schema } from "effect";
3
+ //#region ../contracts/dist/runtime/id.js
4
+ const GeneratedId = Schema.String.check(Schema.isPattern(/^[0-9a-z]{24}$/)).pipe(Schema.brand("ignotum/id"));
5
+ //#endregion
6
+ //#region ../contracts/dist/schema/values.js
7
+ const LiteralValueSchema = Schema.Union([
8
+ Schema.String,
9
+ Schema.Finite,
10
+ Schema.Boolean
11
+ ]);
12
+ const table = (fields) => {
13
+ const tableFields = fields;
14
+ return {
15
+ _tag: "Table",
16
+ fields: tableFields,
17
+ schema: Schema.Struct(tableFields)
18
+ };
19
+ };
20
+ const string = () => Schema.String;
21
+ const number = () => Schema.Finite;
22
+ const integer = () => Schema.Int;
23
+ const boolean = () => Schema.Boolean;
24
+ const date = () => Schema.DateFromMillis;
25
+ const never = () => Schema.Never;
26
+ const nullValue = () => Schema.Null;
27
+ const literal = (value) => {
28
+ Schema.decodeSync(LiteralValueSchema)(value);
29
+ return Schema.Literal(value);
30
+ };
31
+ const literals = (...members) => {
32
+ Schema.decodeSync(Schema.Array(LiteralValueSchema))(members);
33
+ return Schema.Literals(members);
34
+ };
35
+ const makeIdSchema = (tableName) => {
36
+ const identifier = `ignotum/id/${tableName}`;
37
+ return GeneratedId.pipe(Schema.brand(identifier), Schema.annotate({ "ignotum/table": tableName }));
38
+ };
39
+ const id = (tableName) => makeIdSchema(tableName);
40
+ const array = (value) => Schema.Array(value);
41
+ const object = (fields) => Schema.Struct(fields);
42
+ const optional = (value) => Schema.optional(value);
43
+ const nullable = (value) => Schema.NullOr(value);
44
+ const record = (value) => Schema.Record(Schema.String, value);
45
+ const union = (...members) => Schema.Union(members);
46
+ const error = (tag, fields) => {
47
+ if (tag === "InternalServerError") throw new Error("The error tag 'InternalServerError' is reserved by Ignotum.");
48
+ const errorFields = { ...fields };
49
+ Reflect.deleteProperty(errorFields, "_tag");
50
+ const schema = Schema.TaggedStruct(tag, errorFields).pipe(Schema.brand(ErrorBrand));
51
+ const make = (input) => schema.make(input);
52
+ const definition = Object.assign(make, schema);
53
+ Object.setPrototypeOf(definition, Object.getPrototypeOf(schema));
54
+ return definition;
55
+ };
56
+ const values = {
57
+ array,
58
+ boolean,
59
+ date,
60
+ error,
61
+ id,
62
+ integer,
63
+ literal,
64
+ literals,
65
+ never,
66
+ null: nullValue,
67
+ nullable,
68
+ number,
69
+ object,
70
+ optional,
71
+ record,
72
+ string,
73
+ union
74
+ };
75
+ const bindValues = () => values;
76
+ //#endregion
77
+ //#region ../contracts/dist/runtime/schema.js
78
+ const FunctionSchemaTypeId = Symbol.for("ignotum/runtime/schema/FunctionSchema");
79
+ const attachFunctionSchema = (schema) => (definition) => {
80
+ Object.defineProperty(definition, FunctionSchemaTypeId, {
81
+ configurable: false,
82
+ enumerable: false,
83
+ value: schema,
84
+ writable: false
85
+ });
86
+ return definition;
87
+ };
88
+ //#endregion
89
+ //#region ../contracts/dist/schema/index.js
90
+ const SchemaDefinitionTypeId = Symbol.for("ignotum/schema/SchemaDefinition");
91
+ const defineSchema = (define) => ({
92
+ _tag: "Schema",
93
+ [SchemaDefinitionTypeId]: define({
94
+ table,
95
+ values
96
+ })
97
+ });
98
+ const makeFunctionBuilder = (schema, kind) => {
99
+ const define = (definition) => attachFunctionSchema(schema)({
100
+ _tag: kind,
101
+ ...definition
102
+ });
103
+ return define;
104
+ };
105
+ const makeFunctionBuilders = (schema) => ({
106
+ mutation: makeFunctionBuilder(schema, "Mutation"),
107
+ query: makeFunctionBuilder(schema, "Query")
108
+ });
109
+ const bindSchema = (schema) => ({
110
+ values: bindValues(),
111
+ ...makeFunctionBuilders(schema)
112
+ });
113
+ //#endregion
114
+ export { bindSchema as n, defineSchema as r, SchemaDefinitionTypeId as t };
115
+
116
+ //# sourceMappingURL=schema-CNEVLF7D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-CNEVLF7D.js","names":[],"sources":["../../../contracts/dist/runtime/id.js","../../../contracts/dist/schema/values.js","../../../contracts/dist/runtime/schema.js","../../../contracts/dist/schema/index.js"],"sourcesContent":["import { Schema } from \"effect\";\n//#region src/runtime/id.ts\nconst IdAlphabet = \"0123456789abcdefghijklmnopqrstuvwxyz\";\nconst IdLength = 24;\nconst GeneratedId = Schema.String.check(Schema.isPattern(/^[0-9a-z]{24}$/)).pipe(Schema.brand(\"ignotum/id\"));\n//#endregion\nexport { GeneratedId, IdAlphabet, IdLength };\n\n//# sourceMappingURL=id.js.map","import { GeneratedId } from \"../runtime/id.js\";\nimport { ErrorBrand } from \"../runtime/result.js\";\nimport { Schema } from \"effect\";\n//#region src/schema/values.ts\nconst LiteralValueSchema = Schema.Union([\n\tSchema.String,\n\tSchema.Finite,\n\tSchema.Boolean\n]);\nconst table = (fields) => {\n\tconst tableFields = fields;\n\treturn {\n\t\t_tag: \"Table\",\n\t\tfields: tableFields,\n\t\tschema: Schema.Struct(tableFields)\n\t};\n};\nconst string = () => Schema.String;\nconst number = () => Schema.Finite;\nconst integer = () => Schema.Int;\nconst boolean = () => Schema.Boolean;\nconst date = () => Schema.DateFromMillis;\nconst never = () => Schema.Never;\nconst nullValue = () => Schema.Null;\nconst literal = (value) => {\n\tSchema.decodeSync(LiteralValueSchema)(value);\n\treturn Schema.Literal(value);\n};\nconst literals = (...members) => {\n\tSchema.decodeSync(Schema.Array(LiteralValueSchema))(members);\n\treturn Schema.Literals(members);\n};\nconst makeIdSchema = (tableName) => {\n\tconst identifier = `ignotum/id/${tableName}`;\n\treturn GeneratedId.pipe(Schema.brand(identifier), Schema.annotate({ \"ignotum/table\": tableName }));\n};\nconst id = (tableName) => makeIdSchema(tableName);\nconst array = (value) => Schema.Array(value);\nconst object = (fields) => Schema.Struct(fields);\nconst optional = (value) => Schema.optional(value);\nconst nullable = (value) => Schema.NullOr(value);\nconst record = (value) => Schema.Record(Schema.String, value);\nconst union = (...members) => Schema.Union(members);\nconst error = (tag, fields) => {\n\tif (tag === \"InternalServerError\") throw new Error(\"The error tag 'InternalServerError' is reserved by Ignotum.\");\n\tconst errorFields = { ...fields };\n\tReflect.deleteProperty(errorFields, \"_tag\");\n\tconst schema = Schema.TaggedStruct(tag, errorFields).pipe(Schema.brand(ErrorBrand));\n\tconst make = (input) => schema.make(input);\n\tconst definition = Object.assign(make, schema);\n\tObject.setPrototypeOf(definition, Object.getPrototypeOf(schema));\n\treturn definition;\n};\nconst values = {\n\tarray,\n\tboolean,\n\tdate,\n\terror,\n\tid,\n\tinteger,\n\tliteral,\n\tliterals,\n\tnever,\n\tnull: nullValue,\n\tnullable,\n\tnumber,\n\tobject,\n\toptional,\n\trecord,\n\tstring,\n\tunion\n};\nconst bindValues = () => values;\n//#endregion\nexport { bindValues, table, values };\n\n//# sourceMappingURL=values.js.map","//#region src/runtime/schema.ts\nconst FunctionSchemaTypeId = Symbol.for(\"ignotum/runtime/schema/FunctionSchema\");\nconst attachFunctionSchema = (schema) => (definition) => {\n\tObject.defineProperty(definition, FunctionSchemaTypeId, {\n\t\tconfigurable: false,\n\t\tenumerable: false,\n\t\tvalue: schema,\n\t\twritable: false\n\t});\n\treturn definition;\n};\nconst getFunctionSchema = (value) => value[FunctionSchemaTypeId];\n//#endregion\nexport { FunctionSchemaTypeId, attachFunctionSchema, getFunctionSchema };\n\n//# sourceMappingURL=schema.js.map","import { Result } from \"../runtime/result.js\";\nimport { bindValues, table, values } from \"./values.js\";\nimport { attachFunctionSchema } from \"../runtime/schema.js\";\n//#region src/schema/types.ts\nconst SchemaDefinitionTypeId = Symbol.for(\"ignotum/schema/SchemaDefinition\");\n//#endregion\n//#region src/schema/definition.ts\nconst defineSchema = (define) => ({\n\t_tag: \"Schema\",\n\t[SchemaDefinitionTypeId]: define({\n\t\ttable,\n\t\tvalues\n\t})\n});\n//#endregion\n//#region src/schema/server.ts\nconst makeFunctionBuilder = (schema, kind) => {\n\tconst define = (definition) => attachFunctionSchema(schema)({\n\t\t_tag: kind,\n\t\t...definition\n\t});\n\treturn define;\n};\nconst makeFunctionBuilders = (schema) => ({\n\tmutation: makeFunctionBuilder(schema, \"Mutation\"),\n\tquery: makeFunctionBuilder(schema, \"Query\")\n});\nconst bindSchema = (schema) => ({\n\tvalues: bindValues(),\n\t...makeFunctionBuilders(schema)\n});\n//#endregion\nexport { Result, SchemaDefinitionTypeId, bindSchema, bindValues, defineSchema, table, values };\n\n//# sourceMappingURL=index.js.map"],"mappings":";;;AAIA,MAAM,cAAc,OAAO,OAAO,MAAM,OAAO,UAAU,gBAAgB,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM,YAAY,CAAC;;;ACA3G,MAAM,qBAAqB,OAAO,MAAM;CACvC,OAAO;CACP,OAAO;CACP,OAAO;AACR,CAAC;AACD,MAAM,SAAS,WAAW;CACzB,MAAM,cAAc;CACpB,OAAO;EACN,MAAM;EACN,QAAQ;EACR,QAAQ,OAAO,OAAO,WAAW;CAClC;AACD;AACA,MAAM,eAAe,OAAO;AAC5B,MAAM,eAAe,OAAO;AAC5B,MAAM,gBAAgB,OAAO;AAC7B,MAAM,gBAAgB,OAAO;AAC7B,MAAM,aAAa,OAAO;AAC1B,MAAM,cAAc,OAAO;AAC3B,MAAM,kBAAkB,OAAO;AAC/B,MAAM,WAAW,UAAU;CAC1B,OAAO,WAAW,kBAAkB,CAAC,CAAC,KAAK;CAC3C,OAAO,OAAO,QAAQ,KAAK;AAC5B;AACA,MAAM,YAAY,GAAG,YAAY;CAChC,OAAO,WAAW,OAAO,MAAM,kBAAkB,CAAC,CAAC,CAAC,OAAO;CAC3D,OAAO,OAAO,SAAS,OAAO;AAC/B;AACA,MAAM,gBAAgB,cAAc;CACnC,MAAM,aAAa,cAAc;CACjC,OAAO,YAAY,KAAK,OAAO,MAAM,UAAU,GAAG,OAAO,SAAS,EAAE,iBAAiB,UAAU,CAAC,CAAC;AAClG;AACA,MAAM,MAAM,cAAc,aAAa,SAAS;AAChD,MAAM,SAAS,UAAU,OAAO,MAAM,KAAK;AAC3C,MAAM,UAAU,WAAW,OAAO,OAAO,MAAM;AAC/C,MAAM,YAAY,UAAU,OAAO,SAAS,KAAK;AACjD,MAAM,YAAY,UAAU,OAAO,OAAO,KAAK;AAC/C,MAAM,UAAU,UAAU,OAAO,OAAO,OAAO,QAAQ,KAAK;AAC5D,MAAM,SAAS,GAAG,YAAY,OAAO,MAAM,OAAO;AAClD,MAAM,SAAS,KAAK,WAAW;CAC9B,IAAI,QAAQ,uBAAuB,MAAM,IAAI,MAAM,6DAA6D;CAChH,MAAM,cAAc,EAAE,GAAG,OAAO;CAChC,QAAQ,eAAe,aAAa,MAAM;CAC1C,MAAM,SAAS,OAAO,aAAa,KAAK,WAAW,CAAC,CAAC,KAAK,OAAO,MAAM,UAAU,CAAC;CAClF,MAAM,QAAQ,UAAU,OAAO,KAAK,KAAK;CACzC,MAAM,aAAa,OAAO,OAAO,MAAM,MAAM;CAC7C,OAAO,eAAe,YAAY,OAAO,eAAe,MAAM,CAAC;CAC/D,OAAO;AACR;AACA,MAAM,SAAS;CACd;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,MAAM;CACN;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AACA,MAAM,mBAAmB;;;ACvEzB,MAAM,uBAAuB,OAAO,IAAI,uCAAuC;AAC/E,MAAM,wBAAwB,YAAY,eAAe;CACxD,OAAO,eAAe,YAAY,sBAAsB;EACvD,cAAc;EACd,YAAY;EACZ,OAAO;EACP,UAAU;CACX,CAAC;CACD,OAAO;AACR;;;ACNA,MAAM,yBAAyB,OAAO,IAAI,iCAAiC;AAG3E,MAAM,gBAAgB,YAAY;CACjC,MAAM;EACL,yBAAyB,OAAO;EAChC;EACA;CACD,CAAC;AACF;AAGA,MAAM,uBAAuB,QAAQ,SAAS;CAC7C,MAAM,UAAU,eAAe,qBAAqB,MAAM,CAAC,CAAC;EAC3D,MAAM;EACN,GAAG;CACJ,CAAC;CACD,OAAO;AACR;AACA,MAAM,wBAAwB,YAAY;CACzC,UAAU,oBAAoB,QAAQ,UAAU;CAChD,OAAO,oBAAoB,QAAQ,OAAO;AAC3C;AACA,MAAM,cAAc,YAAY;CAC/B,QAAQ,WAAW;CACnB,GAAG,qBAAqB,MAAM;AAC/B"}
@@ -0,0 +1,9 @@
1
+ import { r as ErrorValue, s as Result$1 } from "./result-C1ZdsM6Y.js";
2
+ import { i as defineSchema$1, n as SchemaAuthoring, t as DefinedSchema } from "./index-BgWROoyk.js";
3
+ //#region src/server/index.d.ts
4
+ declare const Result: typeof Result$1;
5
+ type Result<Success, Failure extends ErrorValue> = Result$1<Success, Failure>;
6
+ declare const defineSchema: typeof defineSchema$1;
7
+ //#endregion
8
+ export { type DefinedSchema, Result, type SchemaAuthoring, defineSchema };
9
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1,9 @@
1
+ import { n as Result$1 } from "./result-B2W-z2wG.js";
2
+ import { r as defineSchema$1 } from "./schema-CNEVLF7D.js";
3
+ //#region src/server/index.ts
4
+ const Result = Result$1;
5
+ const defineSchema = defineSchema$1;
6
+ //#endregion
7
+ export { Result, defineSchema };
8
+
9
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","names":["contractResult","defineContractSchema"],"sources":["../../src/server/index.ts"],"sourcesContent":["import { Result as contractResult } from \"@ignotum/contracts/runtime/result\";\nimport type { ErrorValue, Result as ContractResult } from \"@ignotum/contracts/runtime/result\";\nimport { defineSchema as defineContractSchema } from \"@ignotum/contracts/schema\";\n\nexport const Result: typeof contractResult = contractResult;\nexport type Result<Success, Failure extends ErrorValue> = ContractResult<Success, Failure>;\nexport const defineSchema: typeof defineContractSchema = defineContractSchema;\nexport type { DefinedSchema, SchemaAuthoring } from \"@ignotum/contracts/schema\";\n"],"mappings":";;;AAIA,MAAa,SAAgCA;AAE7C,MAAa,eAA4CC"}
package/package.json CHANGED
@@ -1,4 +1,83 @@
1
1
  {
2
2
  "name": "ignotum",
3
- "version": "0.0.0"
4
- }
3
+ "version": "0.0.2",
4
+ "description": "Ignotum is an opinionated TypeScript application cloud.",
5
+ "author": "Johannes Schießl",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/johannesschiessl/ignotum.git",
9
+ "directory": "packages/ignotum"
10
+ },
11
+ "bin": {
12
+ "ignotum": "dist/cli/bin.mjs"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "src"
17
+ ],
18
+ "type": "module",
19
+ "sideEffects": false,
20
+ "exports": {
21
+ "./server": {
22
+ "@ignotum/source": "./src/server/index.ts",
23
+ "types": "./dist/runtime/server.d.ts",
24
+ "import": "./dist/runtime/server.js"
25
+ },
26
+ "./client": {
27
+ "@ignotum/source": "./src/client/index.ts",
28
+ "types": "./dist/runtime/client.d.ts",
29
+ "import": "./dist/runtime/client.js"
30
+ },
31
+ "./client/jsx-dev-runtime": {
32
+ "@ignotum/source": "./src/client/jsx-dev-runtime.ts",
33
+ "types": "./dist/runtime/client/jsx-dev-runtime.d.ts",
34
+ "import": "./dist/runtime/client/jsx-dev-runtime.js"
35
+ },
36
+ "./client/jsx-runtime": {
37
+ "@ignotum/source": "./src/client/jsx-runtime.ts",
38
+ "types": "./dist/runtime/client/jsx-runtime.d.ts",
39
+ "import": "./dist/runtime/client/jsx-runtime.js"
40
+ },
41
+ "./internal/api": {
42
+ "@ignotum/source": "./src/internal/api.ts",
43
+ "types": "./dist/runtime/internal/api.d.ts",
44
+ "import": "./dist/runtime/internal/api.js"
45
+ },
46
+ "./internal/server": {
47
+ "@ignotum/source": "./src/internal/server.ts",
48
+ "types": "./dist/runtime/internal/server.d.ts",
49
+ "import": "./dist/runtime/internal/server.js"
50
+ },
51
+ "./internal/types": {
52
+ "@ignotum/source": "./src/internal/types.ts",
53
+ "types": "./dist/runtime/internal/types.d.ts",
54
+ "import": "./dist/runtime/internal/types.js"
55
+ }
56
+ },
57
+ "publishConfig": {
58
+ "access": "public",
59
+ "registry": "https://registry.npmjs.org/"
60
+ },
61
+ "dependencies": {
62
+ "@effect/platform-node": "4.0.0-rc.111",
63
+ "@effect/sql-sqlite-node": "4.0.0-rc.111",
64
+ "@prefresh/vite": "3.0.1",
65
+ "@tailwindcss/vite": "4.3.3",
66
+ "effect": "4.0.0-rc.111",
67
+ "nanoid": "6.0.1",
68
+ "preact": "10.29.8",
69
+ "tailwindcss": "4.3.3",
70
+ "vite": "8.2.2"
71
+ },
72
+ "devDependencies": {
73
+ "@ignotum/contracts": "0.0.0",
74
+ "@ignotum/runtime": "0.0.0"
75
+ },
76
+ "engines": {
77
+ "node": ">=22.18.0"
78
+ },
79
+ "scripts": {
80
+ "build": "vp pack",
81
+ "typecheck": "tsc -p tsconfig.json"
82
+ }
83
+ }
@@ -0,0 +1,35 @@
1
+ import agents from "../../../../docs/agent/AGENTS.md?raw";
2
+ import skill from "../../../../docs/agent/skills/ignotum/SKILL.md?raw";
3
+ import client from "../../../../docs/user/client.md?raw";
4
+ import devServer from "../../../../docs/user/dev-server.md?raw";
5
+ import gettingStarted from "../../../../docs/user/getting-started.md?raw";
6
+ import index from "../../../../docs/user/index.md?raw";
7
+ import manualSetup from "../../../../docs/user/manual-setup.md?raw";
8
+ import schema from "../../../../docs/user/schema.md?raw";
9
+ import serverFunctions from "../../../../docs/user/server-functions.md?raw";
10
+ import values from "../../../../docs/user/values.md?raw";
11
+
12
+ export interface ProjectFile {
13
+ readonly content: string;
14
+ readonly path: string;
15
+ }
16
+
17
+ const references = [
18
+ ["client.md", client],
19
+ ["dev-server.md", devServer],
20
+ ["getting-started.md", gettingStarted],
21
+ ["index.md", index],
22
+ ["manual-setup.md", manualSetup],
23
+ ["schema.md", schema],
24
+ ["server-functions.md", serverFunctions],
25
+ ["values.md", values],
26
+ ] as const;
27
+
28
+ export const agentProjectFiles: ReadonlyArray<ProjectFile> = [
29
+ { content: agents, path: "AGENTS.md" },
30
+ { content: skill, path: ".agents/skills/ignotum/SKILL.md" },
31
+ ...references.map(([name, content]) => ({
32
+ content,
33
+ path: `.agents/skills/ignotum/references/${name}`,
34
+ })),
35
+ ];
package/src/cli/bin.ts ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { main } from "./command.js";
4
+
5
+ main();
@@ -0,0 +1,66 @@
1
+ import type { Plugin } from "vite";
2
+
3
+ const clientEntryId = "virtual:ignotum/client-entry";
4
+ const resolvedClientEntryId = `\0${clientEntryId}`;
5
+
6
+ const document = `<!doctype html>
7
+ <html lang="en">
8
+ <head>
9
+ <meta charset="UTF-8" />
10
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
11
+ <title>Ignotum</title>
12
+ </head>
13
+ <body>
14
+ <div id="app"></div>
15
+ <script type="module">
16
+ import "${clientEntryId}"
17
+ </script>
18
+ </body>
19
+ </html>`;
20
+
21
+ const clientEntry = `import "preact/debug"
22
+ import { render } from "preact"
23
+ import { jsx } from "preact/jsx-runtime"
24
+
25
+ import "/styles.css"
26
+ import App from "/App.tsx"
27
+
28
+ const root = document.getElementById("app")
29
+
30
+ if (root === null) {
31
+ throw new Error("Ignotum mount element is missing.")
32
+ }
33
+
34
+ render(jsx(App, {}), root)
35
+ `;
36
+
37
+ export const ignotumClientPlugin = (): Plugin => ({
38
+ name: "ignotum:client",
39
+
40
+ configureServer: (server) => {
41
+ server.middlewares.use((request, response, next) => {
42
+ const acceptsHtml = request.headers.accept?.includes("text/html") === true;
43
+ const isNavigation = request.method === "GET" || request.method === "HEAD";
44
+
45
+ if (!acceptsHtml || !isNavigation) {
46
+ next();
47
+ return;
48
+ }
49
+
50
+ const requestUrl = request.originalUrl ?? request.url ?? "/";
51
+
52
+ void server
53
+ .transformIndexHtml(requestUrl, document)
54
+ .then((html) => {
55
+ response.statusCode = 200;
56
+ response.setHeader("Content-Type", "text/html; charset=utf-8");
57
+ response.end(request.method === "HEAD" ? undefined : html);
58
+ })
59
+ .catch(next);
60
+ });
61
+ },
62
+
63
+ load: (id) => (id === resolvedClientEntryId ? clientEntry : undefined),
64
+
65
+ resolveId: (id) => (id === clientEntryId ? resolvedClientEntryId : undefined),
66
+ });
@@ -0,0 +1,203 @@
1
+ import { Array, Effect, FileSystem, Path, Schema, String } from "effect";
2
+
3
+ import { FunctionNamePart } from "@ignotum/contracts/runtime/sync";
4
+
5
+ const generatedHeader = "// Generated by `ignotum codegen`. Do not edit.";
6
+
7
+ export class SchemaNotFound extends Schema.TaggedError<SchemaNotFound>()("SchemaNotFound", {
8
+ message: Schema.String,
9
+ path: Schema.String,
10
+ }) {}
11
+
12
+ export class InvalidFunctionModuleName extends Schema.TaggedError<InvalidFunctionModuleName>()(
13
+ "InvalidFunctionModuleName",
14
+ {
15
+ message: Schema.String,
16
+ path: Schema.String,
17
+ },
18
+ ) {}
19
+
20
+ export class GeneratedFileConflict extends Schema.TaggedError<GeneratedFileConflict>()(
21
+ "GeneratedFileConflict",
22
+ {
23
+ message: Schema.String,
24
+ path: Schema.String,
25
+ },
26
+ ) {}
27
+
28
+ interface GeneratedOutput {
29
+ readonly content: string;
30
+ readonly path: string;
31
+ }
32
+
33
+ export interface CodegenResult {
34
+ readonly functionModules: ReadonlyArray<string>;
35
+ readonly written: ReadonlyArray<string>;
36
+ readonly unchanged: ReadonlyArray<string>;
37
+ }
38
+
39
+ const isFunctionModuleFile = (fileName: string): boolean =>
40
+ fileName.endsWith(".ts") &&
41
+ !fileName.endsWith(".test.ts") &&
42
+ !fileName.endsWith(".spec.ts") &&
43
+ fileName !== "index.ts" &&
44
+ fileName !== "schema.ts" &&
45
+ !fileName.startsWith("_");
46
+
47
+ const moduleNameFromFile = (filePath: string, fileName: string) => {
48
+ const moduleName = fileName.slice(0, -".ts".length);
49
+
50
+ return Schema.decodeEffect(FunctionNamePart)(moduleName).pipe(
51
+ Effect.mapError(() =>
52
+ InvalidFunctionModuleName.make({
53
+ message: `Server function file names must be valid TypeScript identifiers. Rename ${fileName}.`,
54
+ path: filePath,
55
+ }),
56
+ ),
57
+ );
58
+ };
59
+
60
+ const renderServerBindings = (): string => `${generatedHeader}
61
+
62
+ import { bindSchema } from "ignotum/internal/server";
63
+
64
+ import schema from "../server/schema.js";
65
+
66
+ export const { mutation, query, values } = bindSchema(schema);
67
+ `;
68
+
69
+ const renderTypes = (): string => `${generatedHeader}
70
+
71
+ import type {
72
+ Document as DocumentFor,
73
+ Id as IdFor,
74
+ SchemaDefinitionOf,
75
+ } from "ignotum/internal/types";
76
+
77
+ import type schema from "../server/schema.js";
78
+
79
+ export type DataModel = SchemaDefinitionOf<typeof schema>;
80
+ export type Doc<TableName extends Extract<keyof DataModel, string>> = DocumentFor<
81
+ DataModel,
82
+ TableName
83
+ >;
84
+ export type Id<TableName extends Extract<keyof DataModel, string>> = IdFor<TableName>;
85
+ `;
86
+
87
+ const renderApi = (moduleNames: ReadonlyArray<string>): string => {
88
+ const modules = Array.match(moduleNames, {
89
+ onEmpty: () => " // No server function modules found.",
90
+ onNonEmpty: (names) =>
91
+ Array.join(
92
+ Array.map(
93
+ names,
94
+ (moduleName) => ` readonly ${moduleName}: typeof import("../server/${moduleName}.js");`,
95
+ ),
96
+ "\n",
97
+ ),
98
+ });
99
+ return `${generatedHeader}
100
+
101
+ import { createApi } from "ignotum/internal/api";
102
+
103
+ type Modules = {
104
+ ${modules}
105
+ };
106
+
107
+ export const api = createApi<Modules>();
108
+ `;
109
+ };
110
+
111
+ const inspectOutput = Effect.fn("Codegen.inspectOutput")(function* (output: GeneratedOutput) {
112
+ const fileSystem = yield* FileSystem.FileSystem;
113
+ const exists = yield* fileSystem.exists(output.path);
114
+
115
+ if (!exists) {
116
+ return "write" as const;
117
+ }
118
+
119
+ const current = yield* fileSystem.readFileString(output.path);
120
+
121
+ if (current === output.content) {
122
+ return "unchanged" as const;
123
+ }
124
+
125
+ if (!current.startsWith(generatedHeader)) {
126
+ return yield* GeneratedFileConflict.make({
127
+ message: `Refusing to overwrite ${output.path} because it was not created by Ignotum.`,
128
+ path: output.path,
129
+ });
130
+ }
131
+
132
+ return "write" as const;
133
+ });
134
+
135
+ const writeOutput = Effect.fn("Codegen.writeOutput")(function* (output: GeneratedOutput) {
136
+ const fileSystem = yield* FileSystem.FileSystem;
137
+ const path = yield* Path.Path;
138
+ const directory = path.dirname(output.path);
139
+
140
+ yield* fileSystem.makeDirectory(directory, { recursive: true });
141
+ yield* Effect.scoped(
142
+ Effect.gen(function* () {
143
+ const temporaryPath = yield* fileSystem.makeTempFileScoped({
144
+ directory,
145
+ prefix: ".ignotum-",
146
+ suffix: ".ts",
147
+ });
148
+
149
+ yield* fileSystem.writeFileString(temporaryPath, output.content);
150
+ yield* fileSystem.rename(temporaryPath, output.path);
151
+ }),
152
+ );
153
+ });
154
+
155
+ export const generate = Effect.fn("Codegen.generate")(function* (projectDirectory: string) {
156
+ const fileSystem = yield* FileSystem.FileSystem;
157
+ const path = yield* Path.Path;
158
+ const serverDirectory = path.join(projectDirectory, "server");
159
+ const schemaPath = path.join(serverDirectory, "schema.ts");
160
+ const schemaExists = yield* fileSystem.exists(schemaPath);
161
+
162
+ if (!schemaExists) {
163
+ return yield* SchemaNotFound.make({
164
+ message: `No Ignotum schema found at ${schemaPath}.`,
165
+ path: schemaPath,
166
+ });
167
+ }
168
+
169
+ const entries = yield* fileSystem.readDirectory(serverDirectory);
170
+ const functionFiles = Array.sort(String.Order)(Array.filter(entries, isFunctionModuleFile));
171
+ const functionModules = yield* Effect.forEach(functionFiles, (fileName) =>
172
+ moduleNameFromFile(path.join(serverDirectory, fileName), fileName),
173
+ );
174
+ const outputs: ReadonlyArray<GeneratedOutput> = [
175
+ {
176
+ content: renderServerBindings(),
177
+ path: path.join(projectDirectory, "_generated", "server.ts"),
178
+ },
179
+ {
180
+ content: renderApi(functionModules),
181
+ path: path.join(projectDirectory, "_generated", "api.ts"),
182
+ },
183
+ {
184
+ content: renderTypes(),
185
+ path: path.join(projectDirectory, "_generated", "types.ts"),
186
+ },
187
+ ];
188
+ const inspections = yield* Effect.forEach(outputs, inspectOutput);
189
+ const inspectedOutputs = Array.zip(outputs, inspections);
190
+ const outputsToWrite = Array.map(
191
+ Array.filter(inspectedOutputs, ([, inspection]) => inspection === "write"),
192
+ ([output]) => output,
193
+ );
194
+ const unchanged = Array.map(
195
+ Array.filter(inspectedOutputs, ([, inspection]) => inspection === "unchanged"),
196
+ ([output]) => output.path,
197
+ );
198
+ const written = Array.map(outputsToWrite, (output) => output.path);
199
+
200
+ yield* Effect.forEach(outputsToWrite, writeOutput, { discard: true });
201
+
202
+ return { functionModules, unchanged, written } satisfies CodegenResult;
203
+ });