diff --git a/NixSupport/haskell-packages/ihp-datasync-typescript.nix b/NixSupport/haskell-packages/ihp-datasync-typescript.nix
new file mode 100644
index 000000000..84385b124
--- /dev/null
+++ b/NixSupport/haskell-packages/ihp-datasync-typescript.nix
@@ -0,0 +1,15 @@
+{ mkDerivation, ihp, ihp-ide, neat-interpolation, lib, with-utf8_1_1_0_0, megaparsec }:
+mkDerivation {
+ pname = "ihp-datasync-typescript";
+ version = "v1.3.0";
+ src = ./../../ihp-datasync-typescript;
+ libraryHaskellDepends = [
+ ihp ihp-ide neat-interpolation
+ ];
+ testHaskellDepends = [
+ ihp ihp-ide neat-interpolation megaparsec
+ ];
+ executableHaskellDepends = [ ihp with-utf8_1_1_0_0 ];
+ description = "TypeScript code generation for IHP DataSync";
+ license = lib.licenses.mit;
+}
\ No newline at end of file
diff --git a/devenv-module.nix b/devenv-module.nix
index 737af7554..1205c97dd 100644
--- a/devenv-module.nix
+++ b/devenv-module.nix
@@ -119,6 +119,7 @@ that is defined in flake-module.nix
ide = ghcCompiler.ihp-ide;
ssc = ghcCompiler.ihp-ssc;
migrate = ghcCompiler.ihp-migrate;
+ datasync-typescript = ghcCompiler.ihp-datasync-typescript;
};
};
}
diff --git a/ihp-datasync-typescript/IHP/DataSync/TypeScript/Compiler.hs b/ihp-datasync-typescript/IHP/DataSync/TypeScript/Compiler.hs
new file mode 100644
index 000000000..33973f1b0
--- /dev/null
+++ b/ihp-datasync-typescript/IHP/DataSync/TypeScript/Compiler.hs
@@ -0,0 +1,472 @@
+module IHP.DataSync.TypeScript.Compiler where
+
+import IHP.Prelude
+import IHP.IDE.SchemaDesigner.Types
+import NeatInterpolation
+
+generateTypeScriptTypeDefinitions :: [Statement] -> Text
+generateTypeScriptTypeDefinitions schema = [trimming|
+declare module 'ihp-datasync' {
+ ${tableNameTypeDef}
+ ${tableNameToRecordType}
+ ${enumTypes}
+ ${recordInterfaces}
+ ${newRecordInterfaces}
+ ${newRecordType'}
+
+ type UUID = string;
+
+ class ConditionBuildable
> {
+ conditionBuildableType: table;
+
+ where>(column: column, value: IHPRecord[column]): T;
+ where(conditionBuilder: ConditionBuilder): T;
+ where(filterRecord: Partial>): T;
+ filterWhere>(column: column, value: IHPRecord[column]): T;
+ whereNot>(column: column, value: IHPRecord[column]): T;
+ whereLessThan>(column: column, value: IHPRecord[column]): T;
+ whereLessThanOrEqual>(column: column, value: IHPRecord[column]): T;
+ whereGreaterThan>(column: column, value: IHPRecord[column]): T;
+ whereGreaterThanOrEqual>(column: column, value: IHPRecord[column]): T;
+
+ or (...conditionBuilder: ConditionBuilder[]): T;
+ and(...conditionBuilder: ConditionBuilder[]): T;
+
+ whereIn>(column: column, value: Array[column]>): T;
+ }
+
+ class ConditionBuilder extends ConditionBuildable> {}
+
+ function or ( conditions: ConditionBuilder[]): ConditionBuilder;
+ function or (...conditions: ConditionBuilder[]): ConditionBuilder;
+ function and( conditions: ConditionBuilder[]): ConditionBuilder;
+ function and(...conditions: ConditionBuilder[]): ConditionBuilder;
+
+ class QueryBuilder extends ConditionBuildable> {
+ query: Query;
+
+ select>(columns: column[]): QueryBuilder ? {} : result) & Pick, column>>;
+ select>(...columns: column[]): QueryBuilder ? {} : result) & Pick, column>>;
+
+ whereTextSearchStartsWith, value extends IHPRecord[column] & string>(column: column, value: value): QueryBuilder;
+
+ orderBy(column: keyof IHPRecord): QueryBuilder;
+ orderByAsc(column: keyof IHPRecord): QueryBuilder;
+ orderByDesc(column: keyof IHPRecord): QueryBuilder;
+ limit(limit: number): QueryBuilder;
+ offset(limit: number): QueryBuilder;
+
+ fetch(): Promise>;
+ fetchOne(): Promise;
+ subscribe(subscribe: (value: Array) => void): (() => void);
+ }
+
+ ${conditionBuilderConstructors}
+
+ interface Query {
+ table: table;
+ }
+
+ /**
+ * Returns a new database query builder.
+ *
+ * @example
+ * const tasks = await query('tasks')
+ * .orderBy('createdAt')
+ * .limit(10)
+ * .fetch();
+ *
+ * @param {string} table The name of one of your project's table.
+ */
+ function query(table: table): QueryBuilder>;
+ function query>(table: table, columns: column[]): QueryBuilder, column>>;
+
+ class DataSubscription {
+ isClosed: boolean;
+ isConnected: boolean;
+
+ constructor(query: Query);
+ createOnServer(): Promise;
+ close(): Promise;
+ closeIfNotUsed(): Promise;
+ getRecords(): Array