create-absolutejs 0.6.1 → 0.8.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 (78) hide show
  1. package/LICENSE +24 -24
  2. package/README.md +179 -179
  3. package/dist/commands/formatProject.js +3 -2
  4. package/dist/commands/initializeGit.js +1 -1
  5. package/dist/commands/installDependencies.js +4 -3
  6. package/dist/data.js +22 -21
  7. package/dist/generators/configurations/generateDrizzleConfig.js +15 -15
  8. package/dist/generators/configurations/generatePackageJson.js +41 -62
  9. package/dist/generators/configurations/generatePrettierrc.js +9 -9
  10. package/dist/generators/db/dockerInitTemplates.d.ts +4 -0
  11. package/dist/generators/db/dockerInitTemplates.js +83 -79
  12. package/dist/generators/db/generateDatabaseTypes.js +6 -6
  13. package/dist/generators/db/generateDockerContainer.js +53 -16
  14. package/dist/generators/db/generateDrizzleSchema.js +17 -17
  15. package/dist/generators/db/generateSqliteSchema.js +8 -8
  16. package/dist/generators/db/handlerTemplates.d.ts +1 -1
  17. package/dist/generators/db/handlerTemplates.js +260 -260
  18. package/dist/generators/db/scaffoldDatabase.d.ts +3 -1
  19. package/dist/generators/db/scaffoldDatabase.js +4 -2
  20. package/dist/generators/db/scaffoldDocker.d.ts +3 -1
  21. package/dist/generators/db/scaffoldDocker.js +21 -11
  22. package/dist/generators/html/generateHTMLPage.js +60 -60
  23. package/dist/generators/htmx/generateHTMXPage.js +86 -86
  24. package/dist/generators/project/generateAbsoluteAuthConfig.d.ts +1 -1
  25. package/dist/generators/project/generateAbsoluteAuthConfig.js +100 -89
  26. package/dist/generators/project/generateDBBlock.js +9 -9
  27. package/dist/generators/project/generateImportsBlock.js +4 -1
  28. package/dist/generators/project/generateMarkupCSS.js +145 -145
  29. package/dist/generators/project/generateRoutesBlock.d.ts +3 -2
  30. package/dist/generators/project/generateRoutesBlock.js +37 -36
  31. package/dist/generators/project/generateServer.js +22 -18
  32. package/dist/generators/project/scaffoldBackend.js +2 -1
  33. package/dist/generators/project/scaffoldFrontends.d.ts +2 -2
  34. package/dist/generators/project/scaffoldFrontends.js +5 -2
  35. package/dist/generators/react/generateReactComponents.js +95 -95
  36. package/dist/generators/svelte/generateSveltePage.js +210 -210
  37. package/dist/generators/vue/generateVuePage.js +261 -261
  38. package/dist/index.js +11 -2
  39. package/dist/messages.js +43 -43
  40. package/dist/questions/projectName.js +1 -1
  41. package/dist/scaffold.d.ts +3 -1
  42. package/dist/scaffold.js +10 -5
  43. package/dist/templates/README.md +35 -35
  44. package/dist/templates/assets/svg/google-logo.svg +7 -7
  45. package/dist/templates/assets/svg/htmx-logo-black.svg +9 -9
  46. package/dist/templates/assets/svg/htmx-logo-white.svg +9 -9
  47. package/dist/templates/assets/svg/vue-logo.svg +4 -4
  48. package/dist/templates/configurations/.prettierignore +3 -3
  49. package/dist/templates/configurations/.prettierrc.json +9 -9
  50. package/dist/templates/configurations/drizzle.config.ts +13 -13
  51. package/dist/templates/configurations/eslint.config.mjs +243 -243
  52. package/dist/templates/configurations/tsconfig.example.json +98 -98
  53. package/dist/templates/constants.ts +2 -2
  54. package/dist/templates/db/docker-compose.db.yml +15 -15
  55. package/dist/templates/git/gitignore +51 -51
  56. package/dist/templates/html/scripts/typescript-example.ts +21 -21
  57. package/dist/templates/react/components/App.tsx +52 -52
  58. package/dist/templates/react/components/Head.tsx +34 -34
  59. package/dist/templates/react/components/OAuthLink.tsx +39 -39
  60. package/dist/templates/react/components/ProfilePicture.tsx +56 -56
  61. package/dist/templates/styles/colors.ts +11 -11
  62. package/dist/templates/styles/reset.css +84 -84
  63. package/dist/templates/svelte/components/Counter.svelte +19 -19
  64. package/dist/templates/svelte/composables/counter.svelte.ts +14 -14
  65. package/dist/templates/tailwind/postcss.config.ts +8 -8
  66. package/dist/templates/tailwind/tailwind.config.ts +7 -7
  67. package/dist/templates/tailwind/tailwind.css +1 -1
  68. package/dist/templates/vue/components/CountButton.vue +39 -39
  69. package/dist/templates/vue/composables/useCount.ts +14 -14
  70. package/dist/utils/checkDockerInstalled.d.ts +9 -1
  71. package/dist/utils/checkDockerInstalled.js +137 -39
  72. package/dist/utils/checkSqliteInstalled.js +13 -13
  73. package/dist/utils/commandMaps.d.ts +1 -1
  74. package/dist/utils/commandMaps.js +4 -4
  75. package/dist/versions.d.ts +50 -0
  76. package/dist/versions.js +62 -0
  77. package/package.json +22 -21
  78. package/dist/templates/styles/tailwind.css +0 -1
@@ -4,37 +4,17 @@ import { spinner } from '@clack/prompts';
4
4
  import { green } from 'picocolors';
5
5
  import { absoluteAuthPlugin, availablePlugins, defaultDependencies, defaultPlugins, eslintAndPrettierDependencies, eslintReactDependencies } from '../../data';
6
6
  import { getPackageVersion } from '../../utils/getPackageVersion';
7
- import { initTemplates } from '../db/dockerInitTemplates';
7
+ import { versions } from '../../versions';
8
8
  import { computeFlags } from '../project/computeFlags';
9
- const dbScripts = {
10
- cockroachdb: {
11
- clientCmd: 'cockroach sql --insecure --database=database',
12
- waitCmd: initTemplates.cockroachdb.wait
13
- },
14
- gel: {
15
- clientCmd: 'gel -H localhost -P 5656 -u admin --tls-security insecure -b main',
16
- waitCmd: initTemplates.gel.wait
17
- },
18
- mariadb: {
19
- clientCmd: 'MYSQL_PWD=userpassword mariadb -h127.0.0.1 -u user database',
20
- waitCmd: initTemplates.mariadb.wait
21
- },
22
- mssql: {
23
- clientCmd: '/opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P SApassword1',
24
- waitCmd: initTemplates.mssql.wait
25
- },
26
- mysql: {
27
- clientCmd: 'MYSQL_PWD=userpassword mysql -h127.0.0.1 -u user database',
28
- waitCmd: initTemplates.mysql.wait
29
- },
30
- postgresql: {
31
- clientCmd: 'psql -h localhost -U user -d database',
32
- waitCmd: initTemplates.postgresql.wait
33
- },
34
- singlestore: {
35
- clientCmd: 'singlestore -u root -ppassword -D database',
36
- waitCmd: initTemplates.singlestore.wait
37
- }
9
+ const dbClientCommands = {
10
+ cockroachdb: 'cockroach sql --insecure --database=database',
11
+ gel: 'gel -H localhost -P 5656 -u admin --tls-security insecure -b main',
12
+ mariadb: 'MYSQL_PWD=userpassword mariadb -h127.0.0.1 -u user database',
13
+ mongodb: 'mongosh -u user -p password --authenticationDatabase admin database',
14
+ mssql: '/opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P SApassword1',
15
+ mysql: 'MYSQL_PWD=userpassword mysql -h127.0.0.1 -u user database',
16
+ postgresql: 'psql -h localhost -U user -d database',
17
+ singlestore: 'singlestore -u root -ppassword -D database'
38
18
  };
39
19
  export const createPackageJson = ({ projectName, authOption, plugins, databaseEngine, orm, databaseHost, useTailwind, latest, frontendDirectories, codeQualityTool }) => {
40
20
  const s = spinner();
@@ -43,7 +23,7 @@ export const createPackageJson = ({ projectName, authOption, plugins, databaseEn
43
23
  const resolveVersion = (name, listed) => latest ? (getPackageVersion(name) ?? listed) : listed;
44
24
  const dependencies = {};
45
25
  const devDependencies = {};
46
- devDependencies['typescript'] = resolveVersion('typescript', '5.9.3');
26
+ devDependencies['typescript'] = resolveVersion('typescript', versions['typescript']);
47
27
  const flags = computeFlags(frontendDirectories);
48
28
  for (const p of defaultPlugins) {
49
29
  dependencies[p.value] = resolveVersion(p.value, p.latestVersion);
@@ -66,14 +46,15 @@ export const createPackageJson = ({ projectName, authOption, plugins, databaseEn
66
46
  });
67
47
  }
68
48
  if (useTailwind) {
69
- devDependencies['autoprefixer'] = resolveVersion('autoprefixer', '10.4.21');
70
- devDependencies['postcss'] = resolveVersion('postcss', '8.5.3');
71
- devDependencies['tailwindcss'] = resolveVersion('tailwindcss', '4.1.7');
72
- devDependencies['@tailwindcss/cli'] = resolveVersion('@tailwindcss/cli', '4.1.7');
49
+ devDependencies['autoprefixer'] = resolveVersion('autoprefixer', versions['autoprefixer']);
50
+ devDependencies['postcss'] = resolveVersion('postcss', versions['postcss']);
51
+ devDependencies['tailwindcss'] = resolveVersion('tailwindcss', versions['tailwindcss']);
52
+ devDependencies['@tailwindcss/cli'] = resolveVersion('@tailwindcss/cli', versions['@tailwindcss/cli']);
73
53
  }
74
54
  if (flags.requiresReact) {
75
- dependencies['react'] = resolveVersion('react', '19.2.1');
76
- devDependencies['@types/react'] = resolveVersion('@types/react', '19.2.0');
55
+ dependencies['react'] = resolveVersion('react', versions['react']);
56
+ dependencies['react-dom'] = resolveVersion('react-dom', versions['react-dom']);
57
+ devDependencies['@types/react'] = resolveVersion('@types/react', versions['@types/react']);
77
58
  }
78
59
  if (flags.requiresReact && codeQualityTool === 'eslint+prettier') {
79
60
  eslintReactDependencies.forEach((dep) => {
@@ -81,35 +62,35 @@ export const createPackageJson = ({ projectName, authOption, plugins, databaseEn
81
62
  });
82
63
  }
83
64
  if (flags.requiresSvelte) {
84
- dependencies['svelte'] = resolveVersion('svelte', '5.34.7');
65
+ dependencies['svelte'] = resolveVersion('svelte', versions['svelte']);
85
66
  }
86
67
  if (flags.requiresSvelte && codeQualityTool === 'eslint+prettier') {
87
- devDependencies['prettier-plugin-svelte'] = resolveVersion('prettier-plugin-svelte', '3.4.0');
68
+ devDependencies['prettier-plugin-svelte'] = resolveVersion('prettier-plugin-svelte', versions['prettier-plugin-svelte']);
88
69
  }
89
70
  if (flags.requiresVue) {
90
- dependencies['vue'] = resolveVersion('vue', '3.5.17');
71
+ dependencies['vue'] = resolveVersion('vue', versions['vue']);
91
72
  }
92
73
  if (flags.requiresHtmx) {
93
- dependencies['elysia-scoped-state'] = resolveVersion('elysia-scoped-state', '0.1.1');
74
+ dependencies['elysia-scoped-state'] = resolveVersion('elysia-scoped-state', versions['elysia-scoped-state']);
94
75
  }
95
76
  if (orm === 'drizzle') {
96
- dependencies['drizzle-orm'] = resolveVersion('drizzle-orm', '0.41.0');
77
+ dependencies['drizzle-orm'] = resolveVersion('drizzle-orm', versions['drizzle-orm']);
97
78
  }
98
79
  switch (databaseHost) {
99
80
  case 'neon':
100
- dependencies['@neondatabase/serverless'] = resolveVersion('@neondatabase/serverless', '1.0.0');
81
+ dependencies['@neondatabase/serverless'] = resolveVersion('@neondatabase/serverless', versions['@neondatabase/serverless']);
101
82
  break;
102
83
  case 'planetscale':
103
- dependencies['@planetscale/database'] = resolveVersion('@planetscale/database', '1.19.0');
84
+ dependencies['@planetscale/database'] = resolveVersion('@planetscale/database', versions['@planetscale/database']);
104
85
  break;
105
86
  case 'turso':
106
- dependencies['@libsql/client'] = resolveVersion('@libsql/client', '0.15.9');
87
+ dependencies['@libsql/client'] = resolveVersion('@libsql/client', versions['@libsql/client']);
107
88
  break;
108
89
  }
109
90
  if (latest)
110
91
  s.stop(green('Package versions resolved'));
111
92
  const scripts = {
112
- dev: 'bash -c \'trap "exit 0" INT; bun run --watch src/backend/server.ts\'',
93
+ dev: 'absolutejs dev',
113
94
  format: `prettier --write "./**/*.{js,ts,css,json,mjs,md${flags.requiresReact ? ',jsx,tsx' : ''}${flags.requiresSvelte ? ',svelte' : ''}${flags.requiresVue ? ',vue' : ''}${flags.requiresHtml || flags.requiresHtmx ? ',html' : ''}}"`,
114
95
  lint: 'eslint ./src',
115
96
  test: 'echo "Error: no test specified" && exit 1',
@@ -119,40 +100,38 @@ export const createPackageJson = ({ projectName, authOption, plugins, databaseEn
119
100
  if (isLocal &&
120
101
  databaseEngine !== undefined &&
121
102
  databaseEngine !== 'none' &&
122
- databaseEngine !== 'sqlite' &&
123
- databaseEngine !== 'mongodb') {
124
- const config = dbScripts[databaseEngine];
103
+ databaseEngine !== 'sqlite') {
104
+ const clientCmd = dbClientCommands[databaseEngine];
125
105
  const dockerPrefix = `docker compose -p ${databaseEngine} -f db/docker-compose.db.yml`;
126
- scripts['db:up'] = `${dockerPrefix} up -d db`;
127
- scripts['postdb:up'] =
128
- `${dockerPrefix} exec db bash -lc '${config.waitCmd}'`;
106
+ scripts['db:up'] = `${dockerPrefix} up -d --wait db`;
129
107
  scripts['db:down'] = `${dockerPrefix} down`;
130
108
  scripts['db:reset'] = `${dockerPrefix} down -v`;
131
109
  scripts[`db:${databaseEngine}`] =
132
- `${dockerPrefix} exec -it db bash -lc '${config.clientCmd}'`;
133
- scripts['predev'] = 'bun db:up';
110
+ `${dockerPrefix} exec -it db bash -lc '${clientCmd}'`;
134
111
  scripts[`predb:${databaseEngine}`] = 'bun db:up';
135
- scripts['postdev'] = 'bun db:down';
136
112
  scripts[`postdb:${databaseEngine}`] = 'bun db:down';
137
113
  }
138
114
  if (isLocal &&
139
115
  (databaseEngine === 'mysql' || databaseEngine === 'mariadb') &&
140
116
  orm === 'drizzle') {
141
- dependencies['mysql2'] = resolveVersion('mysql2', '3.14.2');
117
+ dependencies['mysql2'] = resolveVersion('mysql2', versions['mysql2']);
142
118
  }
143
119
  if (isLocal && databaseEngine === 'singlestore') {
144
- dependencies['mysql2'] = resolveVersion('mysql2', '3.14.2');
120
+ dependencies['mysql2'] = resolveVersion('mysql2', versions['mysql2']);
145
121
  }
146
122
  if (databaseEngine === 'postgresql' && databaseHost === 'planetscale') {
147
- dependencies['pg'] = resolveVersion('pg', '8.11.0');
148
- devDependencies['@types/pg'] = resolveVersion('@types/pg', '8.6.1');
123
+ dependencies['pg'] = resolveVersion('pg', versions['pg']);
124
+ devDependencies['@types/pg'] = resolveVersion('@types/pg', versions['@types/pg']);
149
125
  }
150
126
  if (isLocal && databaseEngine === 'mssql') {
151
- dependencies['mssql'] = resolveVersion('mssql', '12.1.0');
152
- devDependencies['@types/mssql'] = resolveVersion('@types/mssql', '9.1.8');
127
+ dependencies['mssql'] = resolveVersion('mssql', versions['mssql']);
128
+ devDependencies['@types/mssql'] = resolveVersion('@types/mssql', versions['@types/mssql']);
153
129
  }
154
130
  if (isLocal && databaseEngine === 'gel') {
155
- dependencies['gel'] = resolveVersion('gel', '2.1.1');
131
+ dependencies['gel'] = resolveVersion('gel', versions['gel']);
132
+ }
133
+ if (databaseEngine === 'mongodb') {
134
+ dependencies['mongodb'] = resolveVersion('mongodb', versions['mongodb']);
156
135
  }
157
136
  if (isLocal && databaseEngine === 'sqlite') {
158
137
  scripts['db:sqlite'] = 'sqlite3 db/database.sqlite';
@@ -1,13 +1,13 @@
1
1
  export const generatePrettierrc = (frontends) => {
2
2
  const usesSvelte = frontends.some((frontend) => frontend === 'svelte');
3
- return `{
4
- "endOfLine": "auto",
5
- "printWidth": 80,
6
- "semi": true,
7
- "singleQuote": true,
8
- "tabWidth": 4,
9
- "trailingComma": "none",
10
- "useTabs": true
11
- ${usesSvelte ? `,"plugins": ["prettier-plugin-svelte"],\n"overrides": [{"files": "*.svelte", "options": {"parser": "svelte"}}]` : ''}
3
+ return `{
4
+ "endOfLine": "auto",
5
+ "printWidth": 80,
6
+ "semi": true,
7
+ "singleQuote": true,
8
+ "tabWidth": 4,
9
+ "trailingComma": "none",
10
+ "useTabs": true
11
+ ${usesSvelte ? `,"plugins": ["prettier-plugin-svelte"],\n"overrides": [{"files": "*.svelte", "options": {"parser": "svelte"}}]` : ''}
12
12
  }`;
13
13
  };
@@ -29,6 +29,10 @@ export declare const initTemplates: {
29
29
  readonly cli: "MYSQL_PWD=userpassword mariadb -h127.0.0.1 -u user database -e";
30
30
  readonly wait: "until mariadb-admin ping -h127.0.0.1 --silent; do sleep 1; done";
31
31
  };
32
+ readonly mongodb: {
33
+ readonly cli: "mongosh -u user -p password --authenticationDatabase admin database --eval";
34
+ readonly wait: "for i in $(seq 1 60); do mongosh -u user -p password --authenticationDatabase admin --eval \"db.adminCommand(\\\"ping\\\")\" --quiet 2>/dev/null && exit 0; sleep 1; done; exit 1";
35
+ };
32
36
  readonly mssql: {
33
37
  readonly cli: "/opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P SApassword1 -Q";
34
38
  readonly wait: "until /opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P SApassword1 -Q \"SELECT 1\" >/dev/null 2>&1; do sleep 1; done";
@@ -1,95 +1,95 @@
1
- const postgresqlUsers = `CREATE TABLE IF NOT EXISTS users (
2
- auth_sub VARCHAR(255) PRIMARY KEY,
3
- created_at TIMESTAMP NOT NULL DEFAULT NOW(),
4
- metadata JSONB DEFAULT '{}'::jsonb
1
+ const postgresqlUsers = `CREATE TABLE IF NOT EXISTS users (
2
+ auth_sub VARCHAR(255) PRIMARY KEY,
3
+ created_at TIMESTAMP NOT NULL DEFAULT NOW(),
4
+ metadata JSONB DEFAULT '{}'::jsonb
5
5
  );`;
6
- const postgresqlCountHistory = `CREATE TABLE IF NOT EXISTS count_history (
7
- uid INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
8
- count INTEGER NOT NULL,
9
- created_at TIMESTAMP NOT NULL DEFAULT NOW()
6
+ const postgresqlCountHistory = `CREATE TABLE IF NOT EXISTS count_history (
7
+ uid INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
8
+ count INTEGER NOT NULL,
9
+ created_at TIMESTAMP NOT NULL DEFAULT NOW()
10
10
  );`;
11
- const mysqlUsers = `CREATE TABLE IF NOT EXISTS users (
12
- auth_sub VARCHAR(255) PRIMARY KEY,
13
- created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
14
- metadata JSON DEFAULT (JSON_OBJECT())
11
+ const mysqlUsers = `CREATE TABLE IF NOT EXISTS users (
12
+ auth_sub VARCHAR(255) PRIMARY KEY,
13
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
14
+ metadata JSON DEFAULT (JSON_OBJECT())
15
15
  );`;
16
- const mysqlCountHistory = `CREATE TABLE IF NOT EXISTS count_history (
17
- uid INT AUTO_INCREMENT PRIMARY KEY,
18
- count INT NOT NULL,
19
- created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
16
+ const mysqlCountHistory = `CREATE TABLE IF NOT EXISTS count_history (
17
+ uid INT AUTO_INCREMENT PRIMARY KEY,
18
+ count INT NOT NULL,
19
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
20
20
  );`;
21
- const mariadbUsers = `CREATE TABLE IF NOT EXISTS users (
22
- auth_sub VARCHAR(255) PRIMARY KEY,
23
- created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
24
- metadata JSON DEFAULT ('{}')
21
+ const mariadbUsers = `CREATE TABLE IF NOT EXISTS users (
22
+ auth_sub VARCHAR(255) PRIMARY KEY,
23
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
24
+ metadata JSON DEFAULT ('{}')
25
25
  );`;
26
- const mariadbCountHistory = `CREATE TABLE IF NOT EXISTS count_history (
27
- uid INT AUTO_INCREMENT PRIMARY KEY,
28
- count INT NOT NULL,
29
- created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
26
+ const mariadbCountHistory = `CREATE TABLE IF NOT EXISTS count_history (
27
+ uid INT AUTO_INCREMENT PRIMARY KEY,
28
+ count INT NOT NULL,
29
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
30
30
  );`;
31
- const singlestoreUsers = `CREATE TABLE IF NOT EXISTS users (
32
- auth_sub VARCHAR(255) PRIMARY KEY,
33
- created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
34
- metadata JSON DEFAULT ('{}')
31
+ const singlestoreUsers = `CREATE TABLE IF NOT EXISTS users (
32
+ auth_sub VARCHAR(255) PRIMARY KEY,
33
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
34
+ metadata JSON DEFAULT ('{}')
35
35
  );`;
36
- const singlestoreCountHistory = `CREATE TABLE IF NOT EXISTS count_history (
37
- uid INT AUTO_INCREMENT PRIMARY KEY,
38
- count INT NOT NULL,
39
- created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
36
+ const singlestoreCountHistory = `CREATE TABLE IF NOT EXISTS count_history (
37
+ uid INT AUTO_INCREMENT PRIMARY KEY,
38
+ count INT NOT NULL,
39
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
40
40
  );`;
41
- const cockroachdbUsers = `CREATE TABLE IF NOT EXISTS users (
42
- auth_sub VARCHAR(255) PRIMARY KEY,
43
- created_at TIMESTAMP NOT NULL DEFAULT NOW(),
44
- metadata JSONB DEFAULT '{}'::jsonb
41
+ const cockroachdbUsers = `CREATE TABLE IF NOT EXISTS users (
42
+ auth_sub VARCHAR(255) PRIMARY KEY,
43
+ created_at TIMESTAMP NOT NULL DEFAULT NOW(),
44
+ metadata JSONB DEFAULT '{}'::jsonb
45
45
  );`;
46
- const cockroachdbCountHistory = `CREATE SEQUENCE IF NOT EXISTS count_history_uid_seq START WITH 1 INCREMENT BY 1;
47
- CREATE TABLE IF NOT EXISTS count_history (
48
- uid BIGINT PRIMARY KEY DEFAULT nextval('count_history_uid_seq'),
49
- count INT NOT NULL,
50
- created_at TIMESTAMP NOT NULL DEFAULT NOW()
46
+ const cockroachdbCountHistory = `CREATE SEQUENCE IF NOT EXISTS count_history_uid_seq START WITH 1 INCREMENT BY 1;
47
+ CREATE TABLE IF NOT EXISTS count_history (
48
+ uid BIGINT PRIMARY KEY DEFAULT nextval('count_history_uid_seq'),
49
+ count INT NOT NULL,
50
+ created_at TIMESTAMP NOT NULL DEFAULT NOW()
51
51
  );`;
52
- const mssqlUsers = `IF OBJECT_ID('users','U') IS NULL
53
- BEGIN
54
- CREATE TABLE users (
55
- auth_sub NVARCHAR(255) PRIMARY KEY,
56
- created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),
57
- metadata NVARCHAR(MAX) NULL
58
- );
52
+ const mssqlUsers = `IF OBJECT_ID('users','U') IS NULL
53
+ BEGIN
54
+ CREATE TABLE users (
55
+ auth_sub NVARCHAR(255) PRIMARY KEY,
56
+ created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),
57
+ metadata NVARCHAR(MAX) NULL
58
+ );
59
59
  END;`;
60
- const mssqlCountHistory = `IF OBJECT_ID('count_history','U') IS NULL
61
- BEGIN
62
- CREATE TABLE count_history (
63
- uid INT IDENTITY(1,1) PRIMARY KEY,
64
- count INT NOT NULL,
65
- created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME()
66
- );
60
+ const mssqlCountHistory = `IF OBJECT_ID('count_history','U') IS NULL
61
+ BEGIN
62
+ CREATE TABLE count_history (
63
+ uid INT IDENTITY(1,1) PRIMARY KEY,
64
+ count INT NOT NULL,
65
+ created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME()
66
+ );
67
67
  END;`;
68
- const gelUsers = `create type users {
69
- create required property auth_sub: str {
70
- create constraint exclusive;
71
- };
72
-
73
- create required property created_at: datetime {
74
- set default := datetime_current();
75
- };
76
-
77
- create required property metadata: json {
78
- set default := to_json('{}');
79
- };
68
+ const gelUsers = `create type users {
69
+ create required property auth_sub: str {
70
+ create constraint exclusive;
71
+ };
72
+
73
+ create required property created_at: datetime {
74
+ set default := datetime_current();
75
+ };
76
+
77
+ create required property metadata: json {
78
+ set default := to_json('{}');
79
+ };
80
80
  };`;
81
- const gelCountHistory = `create scalar type CountHistoryUid extending sequence;
82
- create type count_history {
83
- create required property uid: CountHistoryUid {
84
- create constraint exclusive;
85
- set default := sequence_next(introspect CountHistoryUid);
86
- };
87
-
88
- create required property count: int16;
89
-
90
- create required property created_at: datetime {
91
- set default := datetime_current();
92
- };
81
+ const gelCountHistory = `create scalar type CountHistoryUid extending sequence;
82
+ create type count_history {
83
+ create required property uid: CountHistoryUid {
84
+ create constraint exclusive;
85
+ set default := sequence_next(introspect CountHistoryUid);
86
+ };
87
+
88
+ create required property count: int16;
89
+
90
+ create required property created_at: datetime {
91
+ set default := datetime_current();
92
+ };
93
93
  };`;
94
94
  export const userTables = {
95
95
  cockroachdb: cockroachdbUsers,
@@ -122,6 +122,10 @@ export const initTemplates = {
122
122
  cli: 'MYSQL_PWD=userpassword mariadb -h127.0.0.1 -u user database -e',
123
123
  wait: 'until mariadb-admin ping -h127.0.0.1 --silent; do sleep 1; done'
124
124
  },
125
+ mongodb: {
126
+ cli: 'mongosh -u user -p password --authenticationDatabase admin database --eval',
127
+ wait: 'for i in $(seq 1 60); do mongosh -u user -p password --authenticationDatabase admin --eval "db.adminCommand(\\"ping\\")" --quiet 2>/dev/null && exit 0; sleep 1; done; exit 1'
128
+ },
125
129
  mssql: {
126
130
  cli: '/opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P SApassword1 -Q',
127
131
  wait: 'until /opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P SApassword1 -Q "SELECT 1" >/dev/null 2>&1; do sleep 1; done'
@@ -55,13 +55,13 @@ export const generateDatabaseTypes = ({ databaseEngine, databaseHost, authOption
55
55
  ? `import { users, schema } from '../../db/schema';`
56
56
  : `import { countHistory } from '../../db/schema';`;
57
57
  const extraTypes = authOption === 'abs'
58
- ? `export type User = typeof users.$inferSelect;
58
+ ? `export type User = typeof users.$inferSelect;
59
59
  export type NewUser = typeof users.$inferInsert;`
60
- : `export type CountHistory = typeof countHistory.$inferSelect;
60
+ : `export type CountHistory = typeof countHistory.$inferSelect;
61
61
  export type NewCountHistory = typeof countHistory.$inferInsert;`;
62
- return `${schemaImport}
63
- ${dbImport}
64
-
65
- ${`${dbTypeLine}\n`}export type SchemaType = typeof schema;\n\n${extraTypes}
62
+ return `${schemaImport}
63
+ ${dbImport}
64
+
65
+ ${`${dbTypeLine}\n`}export type SchemaType = typeof schema;\n\n${extraTypes}
66
66
  `;
67
67
  };
@@ -4,6 +4,10 @@ const templates = {
4
4
  env: {
5
5
  COCKROACH_DATABASE: 'database'
6
6
  },
7
+ healthcheck: {
8
+ startPeriod: '5s',
9
+ test: 'cockroach sql --insecure -e "select 1" >/dev/null 2>&1'
10
+ },
7
11
  image: 'cockroachdb/cockroach:latest-v25.3',
8
12
  port: '26257:26257',
9
13
  volumePath: '/cockroach/cockroach-data'
@@ -12,6 +16,10 @@ const templates = {
12
16
  env: {
13
17
  GEL_SERVER_SECURITY: 'insecure_dev_mode'
14
18
  },
19
+ healthcheck: {
20
+ startPeriod: '30s',
21
+ test: 'gel query -H localhost -P 5656 -u admin --tls-security insecure "select 1" >/dev/null 2>&1'
22
+ },
15
23
  image: 'geldata/gel:latest',
16
24
  port: '5656:5656',
17
25
  volumePath: '/var/lib/gel/data'
@@ -23,6 +31,10 @@ const templates = {
23
31
  MYSQL_ROOT_PASSWORD: 'rootpassword',
24
32
  MYSQL_USER: 'user'
25
33
  },
34
+ healthcheck: {
35
+ startPeriod: '5s',
36
+ test: 'mariadb-admin ping -h127.0.0.1 --silent'
37
+ },
26
38
  image: 'mariadb:11.4',
27
39
  port: '3306:3306',
28
40
  volumePath: '/var/lib/mysql'
@@ -33,6 +45,10 @@ const templates = {
33
45
  MONGO_INITDB_ROOT_PASSWORD: 'password',
34
46
  MONGO_INITDB_ROOT_USERNAME: 'user'
35
47
  },
48
+ healthcheck: {
49
+ startPeriod: '5s',
50
+ test: 'mongosh -u user -p password --authenticationDatabase admin --eval "db.adminCommand(\'ping\')" --quiet'
51
+ },
36
52
  image: 'mongo:7.0',
37
53
  port: '27017:27017',
38
54
  volumePath: '/data/db'
@@ -42,6 +58,10 @@ const templates = {
42
58
  ACCEPT_EULA: 'Y',
43
59
  MSSQL_SA_PASSWORD: 'SApassword1'
44
60
  },
61
+ healthcheck: {
62
+ startPeriod: '30s',
63
+ test: '/opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P SApassword1 -Q "SELECT 1" >/dev/null 2>&1'
64
+ },
45
65
  image: 'mcr.microsoft.com/mssql/server:2022-latest',
46
66
  port: '1433:1433',
47
67
  volumePath: '/var/opt/mssql'
@@ -53,6 +73,10 @@ const templates = {
53
73
  MYSQL_ROOT_PASSWORD: 'rootpassword',
54
74
  MYSQL_USER: 'user'
55
75
  },
76
+ healthcheck: {
77
+ startPeriod: '5s',
78
+ test: 'mysqladmin ping -h127.0.0.1 --silent'
79
+ },
56
80
  image: 'mysql:8.0',
57
81
  port: '3306:3306',
58
82
  volumePath: '/var/lib/mysql'
@@ -63,6 +87,10 @@ const templates = {
63
87
  POSTGRES_PASSWORD: 'password',
64
88
  POSTGRES_USER: 'user'
65
89
  },
90
+ healthcheck: {
91
+ startPeriod: '5s',
92
+ test: 'pg_isready -U user -h localhost --quiet'
93
+ },
66
94
  image: 'postgres:15',
67
95
  port: '5432:5432',
68
96
  volumePath: '/var/lib/postgresql/data'
@@ -71,6 +99,10 @@ const templates = {
71
99
  env: {
72
100
  ROOT_PASSWORD: 'password'
73
101
  },
102
+ healthcheck: {
103
+ startPeriod: '30s',
104
+ test: 'singlestore -u root -ppassword -e "SELECT 1" >/dev/null 2>&1'
105
+ },
74
106
  image: 'ghcr.io/singlestore-labs/singlestoredb-dev', // NOTE: No tag specified due to data persistence
75
107
  port: '3306:3306',
76
108
  volumePath: '/data'
@@ -82,24 +114,29 @@ export const generateDockerContainer = (databaseEngine) => {
82
114
  databaseEngine === 'sqlite') {
83
115
  throw new Error('Internal type error: Expected a valid local database engine');
84
116
  }
85
- const { image, port, env, volumePath, command } = templates[databaseEngine];
86
- const commandLines = command ? ` command: ${command}` : '';
117
+ const { command, env, healthcheck, image, port, volumePath } = templates[databaseEngine];
118
+ const commandLine = command ? `\n command: ${command}` : '';
87
119
  const envLines = Object.entries(env)
88
120
  .map(([key, value]) => ` ${key}: ${value}`)
89
121
  .join('\n');
90
- return `services:
91
- db:
92
- image: ${image}
93
- restart: always
94
- environment:
95
- ${envLines}
96
- ports:
97
- - "${port}"
98
- ${commandLines}
99
- volumes:
100
- - db_data:${volumePath}
101
-
102
- volumes:
103
- db_data:
122
+ return `services:
123
+ db:
124
+ image: ${image}
125
+ restart: always
126
+ environment:
127
+ ${envLines}
128
+ ports:
129
+ - "${port}"${commandLine}
130
+ healthcheck:
131
+ test: ["CMD-SHELL", "${healthcheck.test.replaceAll('"', '\\"')}"]
132
+ interval: 2s
133
+ timeout: 5s
134
+ retries: 30
135
+ start_period: ${healthcheck.startPeriod}
136
+ volumes:
137
+ - db_data:${volumePath}
138
+
139
+ volumes:
140
+ db_data:
104
141
  `;
105
142
  };
@@ -80,31 +80,31 @@ export const generateDrizzleSchema = ({ databaseEngine, authOption }) => {
80
80
  uidColumn = `integer('uid').primaryKey().generatedAlwaysAsIdentity()`;
81
81
  }
82
82
  const constsBlock = databaseEngine === 'sqlite'
83
- ? `const JULIAN_DAY_UNIX_EPOCH_OFFSET = 2440587.5;
83
+ ? `const JULIAN_DAY_UNIX_EPOCH_OFFSET = 2440587.5;
84
84
  const MILLIS_PER_DAY = 86400000;\n\n`
85
85
  : '';
86
86
  const timestampColumn = databaseEngine === 'sqlite'
87
87
  ? `${cfg.time}.notNull().default(sql\`(julianday('now') - \${JULIAN_DAY_UNIX_EPOCH_OFFSET}) * \${MILLIS_PER_DAY}\`)`
88
88
  : `${cfg.time}.notNull().defaultNow()`;
89
89
  const tableBlock = authOption === 'abs'
90
- ? `export const users = ${cfg.table}('users', {
91
- auth_sub: ${cfg.string}.primaryKey(),
92
- created_at: ${timestampColumn},
93
- metadata: ${cfg.json}.$type<Record<string, unknown>>().default({})
90
+ ? `export const users = ${cfg.table}('users', {
91
+ auth_sub: ${cfg.string}.primaryKey(),
92
+ created_at: ${timestampColumn},
93
+ metadata: ${cfg.json}.$type<Record<string, unknown>>().default({})
94
94
  });`
95
- : `export const countHistory = ${cfg.table}('count_history', {
96
- uid: ${uidColumn},
97
- count: ${intBuilder}('count').notNull(),
98
- created_at: ${timestampColumn}
95
+ : `export const countHistory = ${cfg.table}('count_history', {
96
+ uid: ${uidColumn},
97
+ count: ${intBuilder}('count').notNull(),
98
+ created_at: ${timestampColumn}
99
99
  });`;
100
100
  const schemaKey = authOption === 'abs' ? 'users' : 'countHistory';
101
- return `
102
- ${sqliteImports}${builderImport}
103
-
104
- ${constsBlock}${tableBlock}
105
-
106
- export const schema = {
107
- ${schemaKey}
108
- };
101
+ return `
102
+ ${sqliteImports}${builderImport}
103
+
104
+ ${constsBlock}${tableBlock}
105
+
106
+ export const schema = {
107
+ ${schemaKey}
108
+ };
109
109
  `;
110
110
  };
@@ -1,11 +1,11 @@
1
1
  export const generateSqliteSchema = (authOption) => authOption && authOption !== 'none'
2
- ? `CREATE TABLE IF NOT EXISTS users (
3
- auth_sub TEXT PRIMARY KEY,
4
- created_at INTEGER NOT NULL DEFAULT ((julianday('now') - 2440587.5) * 86400000),
5
- metadata TEXT DEFAULT '{}'
2
+ ? `CREATE TABLE IF NOT EXISTS users (
3
+ auth_sub TEXT PRIMARY KEY,
4
+ created_at INTEGER NOT NULL DEFAULT ((julianday('now') - 2440587.5) * 86400000),
5
+ metadata TEXT DEFAULT '{}'
6
6
  );`
7
- : `CREATE TABLE IF NOT EXISTS count_history (
8
- uid INTEGER PRIMARY KEY AUTOINCREMENT,
9
- count INTEGER NOT NULL,
10
- created_at INTEGER NOT NULL DEFAULT ((julianday('now') - 2440587.5) * 86400000)
7
+ : `CREATE TABLE IF NOT EXISTS count_history (
8
+ uid INTEGER PRIMARY KEY AUTOINCREMENT,
9
+ count INTEGER NOT NULL,
10
+ created_at INTEGER NOT NULL DEFAULT ((julianday('now') - 2440587.5) * 86400000)
11
11
  );`;
@@ -30,7 +30,7 @@ declare const driverConfigurations: {
30
30
  readonly importLines: "";
31
31
  readonly queries: QueryOperations;
32
32
  };
33
- readonly 'mongodb:native:local': {
33
+ readonly 'mongodb:sql:local': {
34
34
  readonly dbType: "Db";
35
35
  readonly importLines: "";
36
36
  readonly queries: QueryOperations;