ignotum 0.0.2 → 0.0.4
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/README.md +23 -7
- package/dist/cli/bin.mjs +32313 -751
- package/dist/cli/bin.mjs.map +1 -1
- package/dist/runtime/{api-Cpx57mk3.d.ts → api-D2bsAz4T.d.ts} +3 -2
- package/dist/runtime/{api-BXXIZc_Q.js → api-DtX8qPrq.js} +58 -27
- package/dist/runtime/api-DtX8qPrq.js.map +1 -0
- package/dist/runtime/client.d.ts +11 -4
- package/dist/runtime/client.js +343 -79
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/{result-B2W-z2wG.js → descriptor-t6BOEGw9-BTHR-ZMv.js} +119 -4
- package/dist/runtime/descriptor-t6BOEGw9-BTHR-ZMv.js.map +1 -0
- package/dist/runtime/id-Btwac71X-B9OeBzvq.d.ts +9 -0
- package/dist/runtime/id-D570vudg.js +26 -0
- package/dist/runtime/id-D570vudg.js.map +1 -0
- package/dist/runtime/{index-BgWROoyk.d.ts → index-Dl_VQGmA.d.ts} +114 -31
- package/dist/runtime/internal/api.d.ts +1 -1
- package/dist/runtime/internal/api.js +1 -1
- package/dist/runtime/internal/host.d.ts +44 -0
- package/dist/runtime/internal/host.js +213 -0
- package/dist/runtime/internal/host.js.map +1 -0
- package/dist/runtime/internal/server.d.ts +1 -1
- package/dist/runtime/internal/server.js +1 -1
- package/dist/runtime/internal/types.d.ts +1 -1
- package/dist/runtime/internal/types.js +1 -1
- package/dist/runtime/{result-C1ZdsM6Y.d.ts → result-BgcHn25t.d.ts} +21 -6
- package/dist/runtime/schema-B-jMZEbs.js +227 -0
- package/dist/runtime/schema-B-jMZEbs.js.map +1 -0
- package/dist/runtime/server.d.ts +2 -2
- package/dist/runtime/server.js +2 -2
- package/package.json +15 -5
- package/src/cli/agent-files.ts +6 -2
- package/src/cli/app-configuration.ts +135 -0
- package/src/cli/bin.ts +24 -1
- package/src/cli/build/artifact.ts +95 -0
- package/src/cli/build/client.ts +103 -0
- package/src/cli/build/server.ts +526 -0
- package/src/cli/client-config.ts +141 -0
- package/src/cli/client-entry.ts +152 -0
- package/src/cli/client-plugin.ts +86 -16
- package/src/cli/codegen.ts +5 -5
- package/src/cli/command.ts +41 -9
- package/src/cli/control-client.ts +343 -0
- package/src/cli/deploy.ts +217 -0
- package/src/cli/dev.ts +43 -108
- package/src/cli/module-boundaries.ts +183 -0
- package/src/cli/{new-project.ts → new-app.ts} +86 -86
- package/src/cli/package-manager.ts +9 -9
- package/src/client/app.ts +15 -0
- package/src/client/errors.ts +1 -17
- package/src/client/index.ts +2 -0
- package/src/client/sync.ts +172 -120
- package/src/dev-runtime/database.ts +253 -96
- package/src/dev-runtime/dev-database.ts +14 -14
- package/src/dev-runtime/functions.ts +57 -88
- package/src/dev-runtime/id.ts +2 -10
- package/src/dev-runtime/migrations.ts +68 -0
- package/src/dev-runtime/sync.ts +266 -83
- package/src/internal/function-definition.ts +77 -0
- package/src/internal/host.ts +1 -0
- package/src/internal/http-paths.ts +3 -1
- package/dist/runtime/api-BXXIZc_Q.js.map +0 -1
- package/dist/runtime/result-B2W-z2wG.js.map +0 -1
- package/dist/runtime/schema-CNEVLF7D.js +0 -116
- package/dist/runtime/schema-CNEVLF7D.js.map +0 -1
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { r as GeneratedId } from "./id-D570vudg.js";
|
|
2
|
+
import { a as ErrorBrand, i as getValueDescriptor, n as attachValueDescriptor, r as descriptorFields } from "./descriptor-t6BOEGw9-BTHR-ZMv.js";
|
|
3
|
+
import { Schema, Struct } from "effect";
|
|
4
|
+
//#region ../contracts/dist/runtime/schema.js
|
|
5
|
+
const FunctionSchemaTypeId = Symbol.for("ignotum/runtime/schema/FunctionSchema");
|
|
6
|
+
const attachFunctionSchema = (schema) => (definition) => {
|
|
7
|
+
Object.defineProperty(definition, FunctionSchemaTypeId, {
|
|
8
|
+
configurable: false,
|
|
9
|
+
enumerable: false,
|
|
10
|
+
value: schema,
|
|
11
|
+
writable: false
|
|
12
|
+
});
|
|
13
|
+
return definition;
|
|
14
|
+
};
|
|
15
|
+
const getFunctionSchema = (value) => value[FunctionSchemaTypeId];
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region ../contracts/dist/schema/values.js
|
|
18
|
+
const LiteralValueSchema = Schema.Union([
|
|
19
|
+
Schema.String,
|
|
20
|
+
Schema.Finite,
|
|
21
|
+
Schema.Boolean
|
|
22
|
+
]);
|
|
23
|
+
const table = (fields) => {
|
|
24
|
+
const tableFields = fields;
|
|
25
|
+
return {
|
|
26
|
+
_tag: "Table",
|
|
27
|
+
descriptor: {
|
|
28
|
+
type: "object",
|
|
29
|
+
fields: descriptorFields(tableFields)
|
|
30
|
+
},
|
|
31
|
+
fields: tableFields,
|
|
32
|
+
schema: Schema.Struct(tableFields)
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
const fresh = (value) => value.pipe(Schema.annotate({}));
|
|
36
|
+
const string = () => attachValueDescriptor(fresh(Schema.String), { type: "string" });
|
|
37
|
+
const number = () => attachValueDescriptor(fresh(Schema.Finite), { type: "number" });
|
|
38
|
+
const integer = () => attachValueDescriptor(fresh(Schema.Int), { type: "integer" });
|
|
39
|
+
const boolean = () => attachValueDescriptor(fresh(Schema.Boolean), { type: "boolean" });
|
|
40
|
+
const date = () => attachValueDescriptor(fresh(Schema.DateFromMillis), { type: "date" });
|
|
41
|
+
const never = () => attachValueDescriptor(fresh(Schema.Never), { type: "never" });
|
|
42
|
+
const nullValue = () => attachValueDescriptor(fresh(Schema.Null), { type: "null" });
|
|
43
|
+
const literal = (value) => {
|
|
44
|
+
Schema.decodeSync(LiteralValueSchema)(value);
|
|
45
|
+
return attachValueDescriptor(Schema.Literal(value), {
|
|
46
|
+
type: "literal",
|
|
47
|
+
value
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
const literals = (...members) => {
|
|
51
|
+
Schema.decodeSync(Schema.Array(LiteralValueSchema))(members);
|
|
52
|
+
return attachValueDescriptor(Schema.Literals(members), {
|
|
53
|
+
type: "literals",
|
|
54
|
+
values: members
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
const makeIdSchema = (tableName) => {
|
|
58
|
+
const identifier = `ignotum/id/${tableName}`;
|
|
59
|
+
return attachValueDescriptor(GeneratedId.pipe(Schema.brand(identifier), Schema.annotate({ "ignotum/table": tableName })), {
|
|
60
|
+
type: "id",
|
|
61
|
+
table: tableName
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
const id = (tableName) => makeIdSchema(tableName);
|
|
65
|
+
const requireDescriptor = (value) => {
|
|
66
|
+
const descriptor = getValueDescriptor(value);
|
|
67
|
+
if (descriptor === void 0) throw new Error("Ignotum value combinators require a values validator.");
|
|
68
|
+
return descriptor;
|
|
69
|
+
};
|
|
70
|
+
const array = (value) => {
|
|
71
|
+
return attachValueDescriptor(Schema.Array(value), {
|
|
72
|
+
type: "array",
|
|
73
|
+
value: requireDescriptor(value)
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
const assertFieldsExist = (fields, keys, operation) => {
|
|
77
|
+
for (const key of keys) if (!Object.hasOwn(fields, key)) throw new Error(`Cannot ${operation} unknown field '${String(key)}'.`);
|
|
78
|
+
};
|
|
79
|
+
const fixedObject = (fields) => {
|
|
80
|
+
const pick = (...keys) => {
|
|
81
|
+
assertFieldsExist(fields, keys, "pick");
|
|
82
|
+
return fixedObject(Struct.pick(fields, keys));
|
|
83
|
+
};
|
|
84
|
+
const omit = (...keys) => {
|
|
85
|
+
assertFieldsExist(fields, keys, "omit");
|
|
86
|
+
return fixedObject(Struct.omit(fields, keys));
|
|
87
|
+
};
|
|
88
|
+
const extend = (addedFields, ..._validation) => {
|
|
89
|
+
for (const key of Reflect.ownKeys(addedFields)) if (Object.hasOwn(fields, key)) throw new Error(`Cannot extend existing field '${String(key)}'.`);
|
|
90
|
+
return fixedObject(Struct.assign(fields, addedFields));
|
|
91
|
+
};
|
|
92
|
+
const override = (overriddenFields, ..._validation) => {
|
|
93
|
+
assertFieldsExist(fields, Reflect.ownKeys(overriddenFields), "override");
|
|
94
|
+
return fixedObject(Struct.assign(fields, overriddenFields));
|
|
95
|
+
};
|
|
96
|
+
const partial = () => {
|
|
97
|
+
const partialFields = Struct.map(fields, Schema.optional);
|
|
98
|
+
for (const name of Reflect.ownKeys(fields)) {
|
|
99
|
+
const field = fields[name];
|
|
100
|
+
const partialField = partialFields[name];
|
|
101
|
+
if (field === void 0 || partialField === void 0) continue;
|
|
102
|
+
attachValueDescriptor(partialField, {
|
|
103
|
+
type: "optional",
|
|
104
|
+
value: requireDescriptor(field)
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return fixedObject(partialFields);
|
|
108
|
+
};
|
|
109
|
+
const schema = attachValueDescriptor(Schema.Struct(fields), {
|
|
110
|
+
type: "object",
|
|
111
|
+
fields: descriptorFields(fields)
|
|
112
|
+
});
|
|
113
|
+
return Object.assign(schema, {
|
|
114
|
+
extend,
|
|
115
|
+
omit,
|
|
116
|
+
override,
|
|
117
|
+
partial,
|
|
118
|
+
pick
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
const object = (fields) => fixedObject(fields);
|
|
122
|
+
const optional = (value) => {
|
|
123
|
+
return attachValueDescriptor(Schema.optional(value), {
|
|
124
|
+
type: "optional",
|
|
125
|
+
value: requireDescriptor(value)
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
const nullable = (value) => {
|
|
129
|
+
return attachValueDescriptor(Schema.NullOr(value), {
|
|
130
|
+
type: "nullable",
|
|
131
|
+
value: requireDescriptor(value)
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
const record = (value) => {
|
|
135
|
+
return attachValueDescriptor(Schema.Record(Schema.String, value), {
|
|
136
|
+
type: "record",
|
|
137
|
+
value: requireDescriptor(value)
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
const union = (...members) => {
|
|
141
|
+
return attachValueDescriptor(Schema.Union(members), {
|
|
142
|
+
type: "union",
|
|
143
|
+
members: members.map(requireDescriptor)
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
const error = (tag, fields) => {
|
|
147
|
+
if (tag === "InternalServerError") throw new Error("The error tag 'InternalServerError' is reserved by Ignotum.");
|
|
148
|
+
const errorFields = { ...fields };
|
|
149
|
+
Reflect.deleteProperty(errorFields, "_tag");
|
|
150
|
+
const schema = Schema.TaggedStruct(tag, errorFields).pipe(Schema.brand(ErrorBrand));
|
|
151
|
+
const make = (input) => schema.make(input);
|
|
152
|
+
const definition = Object.assign(make, schema);
|
|
153
|
+
Object.setPrototypeOf(definition, Object.getPrototypeOf(schema));
|
|
154
|
+
attachValueDescriptor(definition, {
|
|
155
|
+
type: "error",
|
|
156
|
+
tag,
|
|
157
|
+
fields: descriptorFields(errorFields)
|
|
158
|
+
});
|
|
159
|
+
return definition;
|
|
160
|
+
};
|
|
161
|
+
const values = {
|
|
162
|
+
array,
|
|
163
|
+
boolean,
|
|
164
|
+
date,
|
|
165
|
+
error,
|
|
166
|
+
id,
|
|
167
|
+
integer,
|
|
168
|
+
literal,
|
|
169
|
+
literals,
|
|
170
|
+
never,
|
|
171
|
+
null: nullValue,
|
|
172
|
+
nullable,
|
|
173
|
+
number,
|
|
174
|
+
object,
|
|
175
|
+
optional,
|
|
176
|
+
record,
|
|
177
|
+
string,
|
|
178
|
+
union
|
|
179
|
+
};
|
|
180
|
+
const bindValues = (definition) => {
|
|
181
|
+
const boundId = (tableName) => makeIdSchema(tableName);
|
|
182
|
+
const doc = (tableName) => {
|
|
183
|
+
const tableDefinition = definition[tableName];
|
|
184
|
+
if (tableDefinition === void 0) throw new Error(`Unknown table '${tableName}'.`);
|
|
185
|
+
const tableFields = tableDefinition.fields;
|
|
186
|
+
const systemFields = {
|
|
187
|
+
id: boundId(tableName),
|
|
188
|
+
createdAt: date(),
|
|
189
|
+
updatedAt: date()
|
|
190
|
+
};
|
|
191
|
+
return fixedObject(Struct.assign(tableFields, systemFields));
|
|
192
|
+
};
|
|
193
|
+
return {
|
|
194
|
+
...values,
|
|
195
|
+
doc,
|
|
196
|
+
id: boundId
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
//#endregion
|
|
200
|
+
//#region ../contracts/dist/schema/index.js
|
|
201
|
+
const SchemaDefinitionTypeId = Symbol.for("ignotum/schema/SchemaDefinition");
|
|
202
|
+
const defineSchema = (define) => ({
|
|
203
|
+
_tag: "Schema",
|
|
204
|
+
[SchemaDefinitionTypeId]: define({
|
|
205
|
+
table,
|
|
206
|
+
values
|
|
207
|
+
})
|
|
208
|
+
});
|
|
209
|
+
const makeFunctionBuilder = (schema, kind) => {
|
|
210
|
+
const define = (definition) => attachFunctionSchema(schema)({
|
|
211
|
+
_tag: kind,
|
|
212
|
+
...definition
|
|
213
|
+
});
|
|
214
|
+
return define;
|
|
215
|
+
};
|
|
216
|
+
const makeFunctionBuilders = (schema) => ({
|
|
217
|
+
mutation: makeFunctionBuilder(schema, "Mutation"),
|
|
218
|
+
query: makeFunctionBuilder(schema, "Query")
|
|
219
|
+
});
|
|
220
|
+
const bindSchema = (schema) => ({
|
|
221
|
+
values: bindValues(schema[SchemaDefinitionTypeId]),
|
|
222
|
+
...makeFunctionBuilders(schema)
|
|
223
|
+
});
|
|
224
|
+
//#endregion
|
|
225
|
+
export { getFunctionSchema as i, bindSchema as n, defineSchema as r, SchemaDefinitionTypeId as t };
|
|
226
|
+
|
|
227
|
+
//# sourceMappingURL=schema-B-jMZEbs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-B-jMZEbs.js","names":[],"sources":["../../../contracts/dist/runtime/schema.js","../../../contracts/dist/schema/values.js","../../../contracts/dist/schema/index.js"],"sourcesContent":["//#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 { GeneratedId } from \"../runtime/id.js\";\nimport { a as getValueDescriptor, i as descriptorFields, r as attachValueDescriptor } from \"../descriptor-t6BOEGw9.js\";\nimport { ErrorBrand } from \"../runtime/result.js\";\nimport { Schema, Struct } 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\tdescriptor: {\n\t\t\ttype: \"object\",\n\t\t\tfields: descriptorFields(tableFields)\n\t\t},\n\t\tfields: tableFields,\n\t\tschema: Schema.Struct(tableFields)\n\t};\n};\nconst fresh = (value) => value.pipe(Schema.annotate({}));\nconst string = () => attachValueDescriptor(fresh(Schema.String), { type: \"string\" });\nconst number = () => attachValueDescriptor(fresh(Schema.Finite), { type: \"number\" });\nconst integer = () => attachValueDescriptor(fresh(Schema.Int), { type: \"integer\" });\nconst boolean = () => attachValueDescriptor(fresh(Schema.Boolean), { type: \"boolean\" });\nconst date = () => attachValueDescriptor(fresh(Schema.DateFromMillis), { type: \"date\" });\nconst never = () => attachValueDescriptor(fresh(Schema.Never), { type: \"never\" });\nconst nullValue = () => attachValueDescriptor(fresh(Schema.Null), { type: \"null\" });\nconst literal = (value) => {\n\tSchema.decodeSync(LiteralValueSchema)(value);\n\treturn attachValueDescriptor(Schema.Literal(value), {\n\t\ttype: \"literal\",\n\t\tvalue\n\t});\n};\nconst literals = (...members) => {\n\tSchema.decodeSync(Schema.Array(LiteralValueSchema))(members);\n\treturn attachValueDescriptor(Schema.Literals(members), {\n\t\ttype: \"literals\",\n\t\tvalues: members\n\t});\n};\nconst makeIdSchema = (tableName) => {\n\tconst identifier = `ignotum/id/${tableName}`;\n\treturn attachValueDescriptor(GeneratedId.pipe(Schema.brand(identifier), Schema.annotate({ \"ignotum/table\": tableName })), {\n\t\ttype: \"id\",\n\t\ttable: tableName\n\t});\n};\nconst id = (tableName) => makeIdSchema(tableName);\nconst requireDescriptor = (value) => {\n\tconst descriptor = getValueDescriptor(value);\n\tif (descriptor === void 0) throw new Error(\"Ignotum value combinators require a values validator.\");\n\treturn descriptor;\n};\nconst array = (value) => {\n\treturn attachValueDescriptor(Schema.Array(value), {\n\t\ttype: \"array\",\n\t\tvalue: requireDescriptor(value)\n\t});\n};\nconst assertFieldsExist = (fields, keys, operation) => {\n\tfor (const key of keys) if (!Object.hasOwn(fields, key)) throw new Error(`Cannot ${operation} unknown field '${String(key)}'.`);\n};\nconst fixedObject = (fields) => {\n\tconst pick = (...keys) => {\n\t\tassertFieldsExist(fields, keys, \"pick\");\n\t\treturn fixedObject(Struct.pick(fields, keys));\n\t};\n\tconst omit = (...keys) => {\n\t\tassertFieldsExist(fields, keys, \"omit\");\n\t\treturn fixedObject(Struct.omit(fields, keys));\n\t};\n\tconst extend = (addedFields, ..._validation) => {\n\t\tfor (const key of Reflect.ownKeys(addedFields)) if (Object.hasOwn(fields, key)) throw new Error(`Cannot extend existing field '${String(key)}'.`);\n\t\treturn fixedObject(Struct.assign(fields, addedFields));\n\t};\n\tconst override = (overriddenFields, ..._validation) => {\n\t\tassertFieldsExist(fields, Reflect.ownKeys(overriddenFields), \"override\");\n\t\treturn fixedObject(Struct.assign(fields, overriddenFields));\n\t};\n\tconst partial = () => {\n\t\tconst partialFields = Struct.map(fields, Schema.optional);\n\t\tfor (const name of Reflect.ownKeys(fields)) {\n\t\t\tconst field = fields[name];\n\t\t\tconst partialField = partialFields[name];\n\t\t\tif (field === void 0 || partialField === void 0) continue;\n\t\t\tattachValueDescriptor(partialField, {\n\t\t\t\ttype: \"optional\",\n\t\t\t\tvalue: requireDescriptor(field)\n\t\t\t});\n\t\t}\n\t\treturn fixedObject(partialFields);\n\t};\n\tconst schema = attachValueDescriptor(Schema.Struct(fields), {\n\t\ttype: \"object\",\n\t\tfields: descriptorFields(fields)\n\t});\n\treturn Object.assign(schema, {\n\t\textend,\n\t\tomit,\n\t\toverride,\n\t\tpartial,\n\t\tpick\n\t});\n};\nconst object = (fields) => fixedObject(fields);\nconst optional = (value) => {\n\treturn attachValueDescriptor(Schema.optional(value), {\n\t\ttype: \"optional\",\n\t\tvalue: requireDescriptor(value)\n\t});\n};\nconst nullable = (value) => {\n\treturn attachValueDescriptor(Schema.NullOr(value), {\n\t\ttype: \"nullable\",\n\t\tvalue: requireDescriptor(value)\n\t});\n};\nconst record = (value) => {\n\treturn attachValueDescriptor(Schema.Record(Schema.String, value), {\n\t\ttype: \"record\",\n\t\tvalue: requireDescriptor(value)\n\t});\n};\nconst union = (...members) => {\n\treturn attachValueDescriptor(Schema.Union(members), {\n\t\ttype: \"union\",\n\t\tmembers: members.map(requireDescriptor)\n\t});\n};\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\tattachValueDescriptor(definition, {\n\t\ttype: \"error\",\n\t\ttag,\n\t\tfields: descriptorFields(errorFields)\n\t});\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 = (definition) => {\n\tconst boundId = (tableName) => makeIdSchema(tableName);\n\tconst doc = (tableName) => {\n\t\tconst tableDefinition = definition[tableName];\n\t\tif (tableDefinition === void 0) throw new Error(`Unknown table '${tableName}'.`);\n\t\tconst tableFields = tableDefinition.fields;\n\t\tconst systemFields = {\n\t\t\tid: boundId(tableName),\n\t\t\tcreatedAt: date(),\n\t\t\tupdatedAt: date()\n\t\t};\n\t\treturn fixedObject(Struct.assign(tableFields, systemFields));\n\t};\n\treturn {\n\t\t...values,\n\t\tdoc,\n\t\tid: boundId\n\t};\n};\n//#endregion\nexport { bindValues, table, values };\n\n//# sourceMappingURL=values.js.map","import { a as getValueDescriptor, n as ValueDescriptorTypeId, t as ValueDescriptor } from \"../descriptor-t6BOEGw9.js\";\nimport { Result } from \"../runtime/result.js\";\nimport { bindValues, table, values } from \"./values.js\";\nimport { attachFunctionSchema } from \"../runtime/schema.js\";\nimport { Predicate } from \"effect\";\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});\nconst isDefinedSchema = (value) => value._tag === \"Schema\" && Predicate.isObject(value[SchemaDefinitionTypeId]);\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(schema[SchemaDefinitionTypeId]),\n\t...makeFunctionBuilders(schema)\n});\n//#endregion\nexport { Result, SchemaDefinitionTypeId, ValueDescriptor, ValueDescriptorTypeId, bindSchema, bindValues, defineSchema, getValueDescriptor, isDefinedSchema, table, values };\n\n//# sourceMappingURL=index.js.map"],"mappings":"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"}
|
package/dist/runtime/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as ErrorValue, s as Result$1 } from "./result-
|
|
2
|
-
import { i as defineSchema$1, n as SchemaAuthoring, t as DefinedSchema } from "./index-
|
|
1
|
+
import { r as ErrorValue, s as Result$1 } from "./result-BgcHn25t.js";
|
|
2
|
+
import { i as defineSchema$1, n as SchemaAuthoring, t as DefinedSchema } from "./index-Dl_VQGmA.js";
|
|
3
3
|
//#region src/server/index.d.ts
|
|
4
4
|
declare const Result: typeof Result$1;
|
|
5
5
|
type Result<Success, Failure extends ErrorValue> = Result$1<Success, Failure>;
|
package/dist/runtime/server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { r as defineSchema$1 } from "./schema-
|
|
1
|
+
import { s as Result$1 } from "./descriptor-t6BOEGw9-BTHR-ZMv.js";
|
|
2
|
+
import { r as defineSchema$1 } from "./schema-B-jMZEbs.js";
|
|
3
3
|
//#region src/server/index.ts
|
|
4
4
|
const Result = Result$1;
|
|
5
5
|
const defineSchema = defineSchema$1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ignotum",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Ignotum is an opinionated TypeScript application cloud.",
|
|
5
5
|
"author": "Johannes Schießl",
|
|
6
6
|
"repository": {
|
|
@@ -43,6 +43,11 @@
|
|
|
43
43
|
"types": "./dist/runtime/internal/api.d.ts",
|
|
44
44
|
"import": "./dist/runtime/internal/api.js"
|
|
45
45
|
},
|
|
46
|
+
"./internal/host": {
|
|
47
|
+
"@ignotum/source": "./src/internal/host.ts",
|
|
48
|
+
"types": "./dist/runtime/internal/host.d.ts",
|
|
49
|
+
"import": "./dist/runtime/internal/host.js"
|
|
50
|
+
},
|
|
46
51
|
"./internal/server": {
|
|
47
52
|
"@ignotum/source": "./src/internal/server.ts",
|
|
48
53
|
"types": "./dist/runtime/internal/server.d.ts",
|
|
@@ -59,19 +64,24 @@
|
|
|
59
64
|
"registry": "https://registry.npmjs.org/"
|
|
60
65
|
},
|
|
61
66
|
"dependencies": {
|
|
62
|
-
"@effect/platform-
|
|
63
|
-
"@effect/sql-sqlite-node": "4.0.0-rc.111",
|
|
67
|
+
"@effect/platform-browser": "4.0.0-rc.111",
|
|
64
68
|
"@prefresh/vite": "3.0.1",
|
|
65
69
|
"@tailwindcss/vite": "4.3.3",
|
|
66
70
|
"effect": "4.0.0-rc.111",
|
|
67
71
|
"nanoid": "6.0.1",
|
|
72
|
+
"oxc-parser": "0.121.0",
|
|
68
73
|
"preact": "10.29.8",
|
|
69
74
|
"tailwindcss": "4.3.3",
|
|
70
75
|
"vite": "8.2.2"
|
|
71
76
|
},
|
|
72
77
|
"devDependencies": {
|
|
73
|
-
"@
|
|
74
|
-
"@
|
|
78
|
+
"@effect/platform-node": "4.0.0-rc.111",
|
|
79
|
+
"@effect/sql-sqlite-node": "4.0.0-rc.111",
|
|
80
|
+
"redis": "6.2.1",
|
|
81
|
+
"@ignotum/deployment": "1.0.0",
|
|
82
|
+
"@ignotum/runtime": "1.0.0",
|
|
83
|
+
"@ignotum/contracts": "1.0.0",
|
|
84
|
+
"@ignotum/shared": "1.0.0"
|
|
75
85
|
},
|
|
76
86
|
"engines": {
|
|
77
87
|
"node": ">=22.18.0"
|
package/src/cli/agent-files.ts
CHANGED
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
import agents from "../../../../docs/agent/AGENTS.md?raw";
|
|
2
2
|
import skill from "../../../../docs/agent/skills/ignotum/SKILL.md?raw";
|
|
3
3
|
import client from "../../../../docs/user/client.md?raw";
|
|
4
|
+
import deploy from "../../../../docs/user/deploy.md?raw";
|
|
4
5
|
import devServer from "../../../../docs/user/dev-server.md?raw";
|
|
5
6
|
import gettingStarted from "../../../../docs/user/getting-started.md?raw";
|
|
6
7
|
import index from "../../../../docs/user/index.md?raw";
|
|
8
|
+
import limits from "../../../../docs/user/limits.md?raw";
|
|
7
9
|
import manualSetup from "../../../../docs/user/manual-setup.md?raw";
|
|
8
10
|
import schema from "../../../../docs/user/schema.md?raw";
|
|
9
11
|
import serverFunctions from "../../../../docs/user/server-functions.md?raw";
|
|
10
12
|
import values from "../../../../docs/user/values.md?raw";
|
|
11
13
|
|
|
12
|
-
export interface
|
|
14
|
+
export interface AppFile {
|
|
13
15
|
readonly content: string;
|
|
14
16
|
readonly path: string;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
const references = [
|
|
18
20
|
["client.md", client],
|
|
21
|
+
["deploy.md", deploy],
|
|
19
22
|
["dev-server.md", devServer],
|
|
20
23
|
["getting-started.md", gettingStarted],
|
|
21
24
|
["index.md", index],
|
|
25
|
+
["limits.md", limits],
|
|
22
26
|
["manual-setup.md", manualSetup],
|
|
23
27
|
["schema.md", schema],
|
|
24
28
|
["server-functions.md", serverFunctions],
|
|
25
29
|
["values.md", values],
|
|
26
30
|
] as const;
|
|
27
31
|
|
|
28
|
-
export const
|
|
32
|
+
export const agentAppFiles: ReadonlyArray<AppFile> = [
|
|
29
33
|
{ content: agents, path: "AGENTS.md" },
|
|
30
34
|
{ content: skill, path: ".agents/skills/ignotum/SKILL.md" },
|
|
31
35
|
...references.map(([name, content]) => ({
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { AppSlug, type ControlApp } from "@ignotum/contracts/control";
|
|
2
|
+
import { AppId } from "@ignotum/contracts/runtime/identity";
|
|
3
|
+
import { Effect, FileSystem, Path, Schema } from "effect";
|
|
4
|
+
import { Prompt } from "effect/unstable/cli";
|
|
5
|
+
|
|
6
|
+
import { ControlApiError, ControlClient, HostedControlConfiguration } from "./control-client.js";
|
|
7
|
+
|
|
8
|
+
export const AppConfiguration = Schema.Struct({
|
|
9
|
+
formatVersion: Schema.Literal(1),
|
|
10
|
+
appId: AppId,
|
|
11
|
+
slug: AppSlug,
|
|
12
|
+
apiUrl: Schema.URLFromString,
|
|
13
|
+
});
|
|
14
|
+
export type AppConfiguration = typeof AppConfiguration.Type;
|
|
15
|
+
|
|
16
|
+
export class AppConfigurationInvalid extends Schema.TaggedError<AppConfigurationInvalid>()(
|
|
17
|
+
"AppConfigurationInvalid",
|
|
18
|
+
{
|
|
19
|
+
cause: Schema.optional(Schema.Defect()),
|
|
20
|
+
message: Schema.String,
|
|
21
|
+
},
|
|
22
|
+
) {}
|
|
23
|
+
|
|
24
|
+
const invalid = (message: string, cause?: unknown) =>
|
|
25
|
+
AppConfigurationInvalid.make(cause === undefined ? { message } : { cause, message });
|
|
26
|
+
|
|
27
|
+
const appConfigurationPath = (appDirectory: string, path: Path.Path): string =>
|
|
28
|
+
path.join(appDirectory, ".ignotum", "app.json");
|
|
29
|
+
|
|
30
|
+
const loadAppConfiguration = Effect.fn("AppConfiguration.load")(function* (appDirectory: string) {
|
|
31
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
32
|
+
const path = yield* Path.Path;
|
|
33
|
+
const configPath = appConfigurationPath(appDirectory, path);
|
|
34
|
+
if (!(yield* fileSystem.exists(configPath))) return undefined;
|
|
35
|
+
const text = yield* fileSystem
|
|
36
|
+
.readFileString(configPath)
|
|
37
|
+
.pipe(Effect.mapError((cause) => invalid(`Could not read ${configPath}.`, cause)));
|
|
38
|
+
return yield* Schema.decodeEffect(Schema.fromJsonString(AppConfiguration))(text).pipe(
|
|
39
|
+
Effect.mapError((cause) => invalid(`${configPath} is not a valid app configuration.`, cause)),
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const writeAppConfiguration = Effect.fn("AppConfiguration.write")(function* (
|
|
44
|
+
appDirectory: string,
|
|
45
|
+
configuration: AppConfiguration,
|
|
46
|
+
) {
|
|
47
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
48
|
+
const path = yield* Path.Path;
|
|
49
|
+
const stateDirectory = path.join(appDirectory, ".ignotum");
|
|
50
|
+
const configPath = appConfigurationPath(appDirectory, path);
|
|
51
|
+
const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(AppConfiguration))(
|
|
52
|
+
configuration,
|
|
53
|
+
).pipe(Effect.mapError((cause) => invalid("Could not encode the app configuration.", cause)));
|
|
54
|
+
yield* fileSystem
|
|
55
|
+
.makeDirectory(stateDirectory, { recursive: true })
|
|
56
|
+
.pipe(Effect.mapError((cause) => invalid(`Could not create ${stateDirectory}.`, cause)));
|
|
57
|
+
yield* Effect.scoped(
|
|
58
|
+
Effect.gen(function* () {
|
|
59
|
+
const temporaryPath = yield* fileSystem.makeTempFileScoped({
|
|
60
|
+
directory: stateDirectory,
|
|
61
|
+
prefix: ".app-",
|
|
62
|
+
suffix: ".json",
|
|
63
|
+
});
|
|
64
|
+
yield* fileSystem.writeFileString(temporaryPath, `${encoded}\n`);
|
|
65
|
+
yield* fileSystem.rename(temporaryPath, configPath);
|
|
66
|
+
}),
|
|
67
|
+
).pipe(Effect.mapError((cause) => invalid(`Could not write ${configPath}.`, cause)));
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const promptForSlug = Effect.fn("AppConfiguration.promptForSlug")(function* () {
|
|
71
|
+
const value = yield* Prompt.run(
|
|
72
|
+
Prompt.text({
|
|
73
|
+
message: "App slug",
|
|
74
|
+
validate: (input) =>
|
|
75
|
+
Schema.decodeEffect(AppSlug)(input).pipe(
|
|
76
|
+
Effect.map(String),
|
|
77
|
+
Effect.mapError(
|
|
78
|
+
() =>
|
|
79
|
+
"Use lowercase letters, numbers, and hyphens, with no leading or trailing hyphen.",
|
|
80
|
+
),
|
|
81
|
+
),
|
|
82
|
+
}),
|
|
83
|
+
);
|
|
84
|
+
return yield* Schema.decodeEffect(AppSlug)(value).pipe(
|
|
85
|
+
Effect.mapError((cause) => invalid("The app slug is invalid.", cause)),
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const sameApp = (configured: AppConfiguration, remote: ControlApp): boolean =>
|
|
90
|
+
configured.appId === remote.id && configured.slug === remote.slug;
|
|
91
|
+
|
|
92
|
+
export const configureApp = Effect.fn("AppConfiguration.configure")(function* (
|
|
93
|
+
appDirectory: string,
|
|
94
|
+
requestedSlug: AppSlug | undefined,
|
|
95
|
+
) {
|
|
96
|
+
const control = yield* ControlClient;
|
|
97
|
+
const hosted = yield* HostedControlConfiguration;
|
|
98
|
+
const configured = yield* loadAppConfiguration(appDirectory);
|
|
99
|
+
|
|
100
|
+
if (configured !== undefined) {
|
|
101
|
+
if (configured.apiUrl.href !== hosted.apiUrl.href) {
|
|
102
|
+
return yield* invalid(
|
|
103
|
+
`.ignotum/app.json belongs to ${configured.apiUrl.href}, not ${hosted.apiUrl.href}.`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
if (requestedSlug !== undefined && requestedSlug !== configured.slug) {
|
|
107
|
+
return yield* invalid(
|
|
108
|
+
`.ignotum/app.json is already linked to '${configured.slug}', not '${requestedSlug}'.`,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
const remote = yield* control.getApp(configured.appId);
|
|
112
|
+
if (!sameApp(configured, remote)) {
|
|
113
|
+
return yield* invalid("The stored app identity does not match the Ignotum API.");
|
|
114
|
+
}
|
|
115
|
+
return configured;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const slug = requestedSlug ?? (yield* promptForSlug());
|
|
119
|
+
const app = yield* control.getAppBySlug(slug).pipe(
|
|
120
|
+
Effect.catchTags({
|
|
121
|
+
ControlApiError: (error: ControlApiError) =>
|
|
122
|
+
error.code === "AppNotFound" ? control.createApp(slug) : Effect.fail(error),
|
|
123
|
+
}),
|
|
124
|
+
);
|
|
125
|
+
const configuration = {
|
|
126
|
+
formatVersion: 1,
|
|
127
|
+
appId: app.id,
|
|
128
|
+
slug: app.slug,
|
|
129
|
+
apiUrl: hosted.apiUrl,
|
|
130
|
+
} satisfies AppConfiguration;
|
|
131
|
+
yield* writeAppConfiguration(appDirectory, configuration);
|
|
132
|
+
return configuration;
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
export const appUrl = (slug: AppSlug): string => `https://${slug}.ignotum.app`;
|
package/src/cli/bin.ts
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
|
|
5
|
+
import { NodeRuntime, NodeServices } from "@effect/platform-node";
|
|
6
|
+
import { Effect } from "effect";
|
|
7
|
+
|
|
3
8
|
import { main } from "./command.js";
|
|
9
|
+
import { runServerDiscoveryWorker } from "./build/server.js";
|
|
10
|
+
|
|
11
|
+
const discoveryWorker = process.argv[2] === "__ignotum_discover_server";
|
|
4
12
|
|
|
5
|
-
|
|
13
|
+
if (discoveryWorker) {
|
|
14
|
+
const appDirectory = process.argv[3];
|
|
15
|
+
const moduleNames = process.argv[4];
|
|
16
|
+
const outputPath = process.argv[5];
|
|
17
|
+
globalThis.fetch = () => Promise.reject(new Error("Network access is disabled during builds."));
|
|
18
|
+
(appDirectory === undefined || moduleNames === undefined || outputPath === undefined
|
|
19
|
+
? Effect.die("Invalid isolated discovery arguments.")
|
|
20
|
+
: runServerDiscoveryWorker(appDirectory, moduleNames, outputPath)
|
|
21
|
+
).pipe(
|
|
22
|
+
// @effect-diagnostics-next-line strictEffectProvide:off The isolated worker is a process entry point.
|
|
23
|
+
Effect.provide(NodeServices.layer),
|
|
24
|
+
NodeRuntime.runMain,
|
|
25
|
+
);
|
|
26
|
+
} else {
|
|
27
|
+
main();
|
|
28
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Array, Effect, Path, Predicate, Schema } from "effect";
|
|
2
|
+
import { normalizePath } from "vite";
|
|
3
|
+
import type { InlineConfig } from "vite";
|
|
4
|
+
import { build as viteBuild } from "vite";
|
|
5
|
+
|
|
6
|
+
import { BuildBoundaryViolation } from "../module-boundaries.js";
|
|
7
|
+
|
|
8
|
+
const GeneratedChunk = Schema.Struct({
|
|
9
|
+
type: Schema.Literal("chunk"),
|
|
10
|
+
dynamicImports: Schema.Array(Schema.String),
|
|
11
|
+
exports: Schema.Array(Schema.String),
|
|
12
|
+
fileName: Schema.String,
|
|
13
|
+
imports: Schema.Array(Schema.String),
|
|
14
|
+
isEntry: Schema.Boolean,
|
|
15
|
+
});
|
|
16
|
+
export type GeneratedChunk = typeof GeneratedChunk.Type;
|
|
17
|
+
|
|
18
|
+
const GeneratedAsset = Schema.Struct({
|
|
19
|
+
type: Schema.Literal("asset"),
|
|
20
|
+
fileName: Schema.String,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const GeneratedBuild = Schema.Struct({
|
|
24
|
+
output: Schema.Array(Schema.Union([GeneratedChunk, GeneratedAsset])),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const GeneratedBuilds = Schema.Union([GeneratedBuild, Schema.Array(GeneratedBuild)]);
|
|
28
|
+
|
|
29
|
+
export type GeneratedBuildOutput = (typeof GeneratedBuild.Type)["output"][number];
|
|
30
|
+
|
|
31
|
+
export class ViteBuildFailed extends Schema.TaggedError<ViteBuildFailed>()("ViteBuildFailed", {
|
|
32
|
+
cause: Schema.Defect(),
|
|
33
|
+
message: Schema.String,
|
|
34
|
+
}) {}
|
|
35
|
+
|
|
36
|
+
export class InvalidBuildOutput extends Schema.TaggedError<InvalidBuildOutput>()(
|
|
37
|
+
"InvalidBuildOutput",
|
|
38
|
+
{
|
|
39
|
+
message: Schema.String,
|
|
40
|
+
},
|
|
41
|
+
) {}
|
|
42
|
+
|
|
43
|
+
export const causeMessage = (cause: unknown): string =>
|
|
44
|
+
Predicate.isError(cause) ? cause.message : String(cause);
|
|
45
|
+
|
|
46
|
+
export const runViteBuild = Effect.fn("Deploy.runViteBuild")(function* (
|
|
47
|
+
name: string,
|
|
48
|
+
config: InlineConfig,
|
|
49
|
+
) {
|
|
50
|
+
const result = yield* Effect.tryPromise({
|
|
51
|
+
try: () => viteBuild(config),
|
|
52
|
+
catch: (cause) =>
|
|
53
|
+
Schema.is(BuildBoundaryViolation)(cause)
|
|
54
|
+
? cause
|
|
55
|
+
: ViteBuildFailed.make({
|
|
56
|
+
cause,
|
|
57
|
+
message: `Vite could not build the ${name}: ${causeMessage(cause)}`,
|
|
58
|
+
}),
|
|
59
|
+
});
|
|
60
|
+
const decoded = yield* Schema.decodeUnknownEffect(GeneratedBuilds)(result).pipe(
|
|
61
|
+
Effect.mapError(() =>
|
|
62
|
+
InvalidBuildOutput.make({ message: `Vite returned an invalid result for the ${name}.` }),
|
|
63
|
+
),
|
|
64
|
+
);
|
|
65
|
+
const builds = Predicate.hasProperty(decoded, "output") ? [decoded] : decoded;
|
|
66
|
+
|
|
67
|
+
return Array.flatMap(builds, (build) => build.output);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export const sourceMapPathTransform = Effect.fn("Deploy.sourceMapPathTransform")(function* (
|
|
71
|
+
appDirectory: string,
|
|
72
|
+
) {
|
|
73
|
+
const path = yield* Path.Path;
|
|
74
|
+
|
|
75
|
+
return (relativeSourcePath: string, sourcemapPath: string): string => {
|
|
76
|
+
const normalizedSource = normalizePath(relativeSourcePath);
|
|
77
|
+
const dependencyMarker = "/node_modules/";
|
|
78
|
+
const dependencyIndex = normalizedSource.lastIndexOf(dependencyMarker);
|
|
79
|
+
if (dependencyIndex >= 0) {
|
|
80
|
+
return `ignotum://dependency/${normalizedSource.slice(dependencyIndex + dependencyMarker.length)}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (normalizedSource.startsWith("\0") || normalizedSource.startsWith("virtual:")) {
|
|
84
|
+
return `ignotum://runtime/${normalizedSource.replace(/^\0|^virtual:/, "")}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const absoluteSource = path.resolve(path.dirname(sourcemapPath), relativeSourcePath);
|
|
88
|
+
const relativeAppPath = normalizePath(path.relative(appDirectory, absoluteSource));
|
|
89
|
+
if (relativeAppPath !== ".." && !relativeAppPath.startsWith("../")) {
|
|
90
|
+
return `ignotum://app/${relativeAppPath}`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return `ignotum://runtime/${path.basename(normalizedSource)}`;
|
|
94
|
+
};
|
|
95
|
+
});
|