@remix-run/data-table 0.0.0 → 0.2.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 (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +549 -2
  3. package/dist/index.d.ts +15 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +7 -0
  6. package/dist/lib/adapter.d.ts +550 -0
  7. package/dist/lib/adapter.d.ts.map +1 -0
  8. package/dist/lib/adapter.js +1 -0
  9. package/dist/lib/column.d.ts +193 -0
  10. package/dist/lib/column.d.ts.map +1 -0
  11. package/dist/lib/column.js +302 -0
  12. package/dist/lib/database/execution-context.d.ts +10 -0
  13. package/dist/lib/database/execution-context.d.ts.map +1 -0
  14. package/dist/lib/database/execution-context.js +1 -0
  15. package/dist/lib/database/helpers.d.ts +26 -0
  16. package/dist/lib/database/helpers.d.ts.map +1 -0
  17. package/dist/lib/database/helpers.js +116 -0
  18. package/dist/lib/database/query-execution.d.ts +7 -0
  19. package/dist/lib/database/query-execution.d.ts.map +1 -0
  20. package/dist/lib/database/query-execution.js +401 -0
  21. package/dist/lib/database/relations.d.ts +4 -0
  22. package/dist/lib/database/relations.d.ts.map +1 -0
  23. package/dist/lib/database/relations.js +207 -0
  24. package/dist/lib/database/write-lifecycle.d.ts +13 -0
  25. package/dist/lib/database/write-lifecycle.d.ts.map +1 -0
  26. package/dist/lib/database/write-lifecycle.js +279 -0
  27. package/dist/lib/database.d.ts +264 -0
  28. package/dist/lib/database.d.ts.map +1 -0
  29. package/dist/lib/database.js +319 -0
  30. package/dist/lib/errors.d.ts +59 -0
  31. package/dist/lib/errors.d.ts.map +1 -0
  32. package/dist/lib/errors.js +76 -0
  33. package/dist/lib/inflection.d.ts +3 -0
  34. package/dist/lib/inflection.d.ts.map +1 -0
  35. package/dist/lib/inflection.js +56 -0
  36. package/dist/lib/migrations/filename.d.ts +12 -0
  37. package/dist/lib/migrations/filename.d.ts.map +1 -0
  38. package/dist/lib/migrations/filename.js +20 -0
  39. package/dist/lib/migrations/helpers.d.ts +11 -0
  40. package/dist/lib/migrations/helpers.d.ts.map +1 -0
  41. package/dist/lib/migrations/helpers.js +77 -0
  42. package/dist/lib/migrations/journal-store.d.ts +15 -0
  43. package/dist/lib/migrations/journal-store.d.ts.map +1 -0
  44. package/dist/lib/migrations/journal-store.js +83 -0
  45. package/dist/lib/migrations/registry.d.ts +27 -0
  46. package/dist/lib/migrations/registry.d.ts.map +1 -0
  47. package/dist/lib/migrations/registry.js +51 -0
  48. package/dist/lib/migrations/runner.d.ts +20 -0
  49. package/dist/lib/migrations/runner.d.ts.map +1 -0
  50. package/dist/lib/migrations/runner.js +273 -0
  51. package/dist/lib/migrations/schema-api.d.ts +7 -0
  52. package/dist/lib/migrations/schema-api.d.ts.map +1 -0
  53. package/dist/lib/migrations/schema-api.js +326 -0
  54. package/dist/lib/migrations-node.d.ts +17 -0
  55. package/dist/lib/migrations-node.d.ts.map +1 -0
  56. package/dist/lib/migrations-node.js +65 -0
  57. package/dist/lib/migrations.d.ts +292 -0
  58. package/dist/lib/migrations.d.ts.map +1 -0
  59. package/dist/lib/migrations.js +38 -0
  60. package/dist/lib/operators.d.ts +154 -0
  61. package/dist/lib/operators.d.ts.map +1 -0
  62. package/dist/lib/operators.js +218 -0
  63. package/dist/lib/query.d.ts +159 -0
  64. package/dist/lib/query.d.ts.map +1 -0
  65. package/dist/lib/query.js +401 -0
  66. package/dist/lib/references.d.ts +41 -0
  67. package/dist/lib/references.d.ts.map +1 -0
  68. package/dist/lib/references.js +33 -0
  69. package/dist/lib/sql-helpers.d.ts +50 -0
  70. package/dist/lib/sql-helpers.d.ts.map +1 -0
  71. package/dist/lib/sql-helpers.js +111 -0
  72. package/dist/lib/sql.d.ts +45 -0
  73. package/dist/lib/sql.d.ts.map +1 -0
  74. package/dist/lib/sql.js +65 -0
  75. package/dist/lib/table.d.ts +569 -0
  76. package/dist/lib/table.d.ts.map +1 -0
  77. package/dist/lib/table.js +519 -0
  78. package/dist/lib/types.d.ts +4 -0
  79. package/dist/lib/types.d.ts.map +1 -0
  80. package/dist/lib/types.js +1 -0
  81. package/dist/migrations/node.d.ts +2 -0
  82. package/dist/migrations/node.d.ts.map +1 -0
  83. package/dist/migrations/node.js +1 -0
  84. package/dist/migrations.d.ts +8 -0
  85. package/dist/migrations.d.ts.map +1 -0
  86. package/dist/migrations.js +5 -0
  87. package/dist/operators.d.ts +3 -0
  88. package/dist/operators.d.ts.map +1 -0
  89. package/dist/operators.js +1 -0
  90. package/dist/sql-helpers.d.ts +3 -0
  91. package/dist/sql-helpers.d.ts.map +1 -0
  92. package/dist/sql-helpers.js +1 -0
  93. package/package.json +56 -7
  94. package/src/index.ts +198 -0
  95. package/src/lib/adapter.ts +653 -0
  96. package/src/lib/column.ts +384 -0
  97. package/src/lib/database/execution-context.ts +15 -0
  98. package/src/lib/database/helpers.ts +216 -0
  99. package/src/lib/database/query-execution.ts +638 -0
  100. package/src/lib/database/relations.ts +332 -0
  101. package/src/lib/database/write-lifecycle.ts +487 -0
  102. package/src/lib/database.ts +856 -0
  103. package/src/lib/errors.ts +119 -0
  104. package/src/lib/inflection.ts +69 -0
  105. package/src/lib/migrations/filename.ts +25 -0
  106. package/src/lib/migrations/helpers.ts +108 -0
  107. package/src/lib/migrations/journal-store.ts +122 -0
  108. package/src/lib/migrations/registry.ts +62 -0
  109. package/src/lib/migrations/runner.ts +374 -0
  110. package/src/lib/migrations/schema-api.ts +417 -0
  111. package/src/lib/migrations-node.ts +71 -0
  112. package/src/lib/migrations.ts +328 -0
  113. package/src/lib/operators.ts +436 -0
  114. package/src/lib/query.ts +958 -0
  115. package/src/lib/references.ts +78 -0
  116. package/src/lib/sql-helpers.ts +146 -0
  117. package/src/lib/sql.ts +84 -0
  118. package/src/lib/table.ts +1309 -0
  119. package/src/lib/types.ts +3 -0
  120. package/src/migrations/node.ts +1 -0
  121. package/src/migrations.ts +26 -0
  122. package/src/operators.ts +18 -0
  123. package/src/sql-helpers.ts +9 -0
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Symbol key used to store non-enumerable table metadata.
3
+ */
4
+ export const tableMetadataKey = Symbol('data-table.tableMetadata')
5
+
6
+ /**
7
+ * Symbol key used to store non-enumerable column metadata.
8
+ */
9
+ export const columnMetadataKey = Symbol('data-table.columnMetadata')
10
+
11
+ type UnknownTableMetadata<
12
+ name extends string = string,
13
+ columns extends Record<string, unknown> = Record<string, unknown>,
14
+ primaryKey extends readonly string[] = readonly string[],
15
+ timestamps = unknown,
16
+ > = {
17
+ name: name
18
+ columns: columns
19
+ primaryKey: primaryKey
20
+ timestamps: timestamps
21
+ }
22
+
23
+ export type TableMetadataLike<
24
+ name extends string = string,
25
+ columns extends Record<string, unknown> = Record<string, unknown>,
26
+ primaryKey extends readonly string[] = readonly string[],
27
+ timestamps = unknown,
28
+ > = {
29
+ [tableMetadataKey]: UnknownTableMetadata<name, columns, primaryKey, timestamps>
30
+ }
31
+
32
+ export type ColumnReferenceLike<qualifiedName extends string = string> = {
33
+ kind: 'column'
34
+ [columnMetadataKey]: {
35
+ tableName: string
36
+ columnName: string
37
+ qualifiedName: qualifiedName
38
+ }
39
+ }
40
+
41
+ export type ColumnInput<qualifiedName extends string = string> =
42
+ | qualifiedName
43
+ | ColumnReferenceLike<qualifiedName>
44
+
45
+ export type NormalizeColumnInput<input> =
46
+ input extends ColumnReferenceLike<infer qualifiedName> ? qualifiedName : input
47
+
48
+ /**
49
+ * Returns `true` when a value is a `data-table` column reference.
50
+ * @param value Value to inspect.
51
+ * @returns Whether the value is a column reference object.
52
+ */
53
+ export function isColumnReference(value: unknown): value is ColumnReferenceLike {
54
+ if (typeof value !== 'object' || value === null) {
55
+ return false
56
+ }
57
+
58
+ if (!('kind' in value) || (value as { kind?: unknown }).kind !== 'column') {
59
+ return false
60
+ }
61
+
62
+ return columnMetadataKey in (value as object)
63
+ }
64
+
65
+ /**
66
+ * Normalizes string/column-reference inputs to a qualified column name.
67
+ * @param input Column name or column reference.
68
+ * @returns The normalized qualified column name.
69
+ */
70
+ export function normalizeColumnInput<input extends string | ColumnReferenceLike>(
71
+ input: input,
72
+ ): NormalizeColumnInput<input> {
73
+ if (typeof input === 'string') {
74
+ return input as NormalizeColumnInput<input>
75
+ }
76
+
77
+ return input[columnMetadataKey].qualifiedName as NormalizeColumnInput<input>
78
+ }
@@ -0,0 +1,146 @@
1
+ import type { DataManipulationOperation, DataMigrationOperation, TableRef } from './adapter.ts'
2
+
3
+ /**
4
+ * Function used to quote SQL identifiers for a dialect.
5
+ */
6
+ export type QuoteIdentifier = (value: string) => string
7
+
8
+ /**
9
+ * Type guard that narrows an operation to the data-manipulation union.
10
+ * @param operation Operation to inspect.
11
+ * @returns `true` when the operation is a data-manipulation operation.
12
+ */
13
+ export function isDataManipulationOperation(
14
+ operation: DataManipulationOperation | DataMigrationOperation,
15
+ ): operation is DataManipulationOperation {
16
+ return (
17
+ operation.kind === 'select' ||
18
+ operation.kind === 'count' ||
19
+ operation.kind === 'exists' ||
20
+ operation.kind === 'insert' ||
21
+ operation.kind === 'insertMany' ||
22
+ operation.kind === 'update' ||
23
+ operation.kind === 'delete' ||
24
+ operation.kind === 'upsert' ||
25
+ operation.kind === 'raw'
26
+ )
27
+ }
28
+
29
+ /**
30
+ * Normalizes an arbitrary join type string into `inner`, `left`, or `right`.
31
+ * @param type Input join type.
32
+ * @returns Normalized join type.
33
+ */
34
+ export function normalizeJoinType(type: string): string {
35
+ if (type === 'left') {
36
+ return 'left'
37
+ }
38
+
39
+ if (type === 'right') {
40
+ return 'right'
41
+ }
42
+
43
+ return 'inner'
44
+ }
45
+
46
+ /**
47
+ * Returns stable column order from the union of keys in the provided rows.
48
+ * @param rows Row objects to scan for keys.
49
+ * @returns Deduplicated key list in encounter order.
50
+ */
51
+ export function collectColumns(rows: Record<string, unknown>[]): string[] {
52
+ let columns: string[] = []
53
+ let seen = new Set<string>()
54
+
55
+ for (let row of rows) {
56
+ for (let key in row) {
57
+ if (!Object.prototype.hasOwnProperty.call(row, key)) {
58
+ continue
59
+ }
60
+
61
+ if (seen.has(key)) {
62
+ continue
63
+ }
64
+
65
+ seen.add(key)
66
+ columns.push(key)
67
+ }
68
+ }
69
+
70
+ return columns
71
+ }
72
+
73
+ /**
74
+ * Quotes each segment of a dotted identifier path.
75
+ *
76
+ * Wildcard segments (`*`) are preserved.
77
+ * @param path Dotted path to quote.
78
+ * @param quoteIdentifier Dialect-specific identifier quote function.
79
+ * @returns Quoted path string.
80
+ */
81
+ export function quotePath(path: string, quoteIdentifier: QuoteIdentifier): string {
82
+ if (path === '*') {
83
+ return '*'
84
+ }
85
+
86
+ return path
87
+ .split('.')
88
+ .map((segment) => {
89
+ if (segment === '*') {
90
+ return '*'
91
+ }
92
+
93
+ return quoteIdentifier(segment)
94
+ })
95
+ .join('.')
96
+ }
97
+
98
+ /**
99
+ * Quotes a `{ schema?, name }` table reference using a dialect quote function.
100
+ * @param table Table reference to quote.
101
+ * @param quoteIdentifier Dialect-specific identifier quote function.
102
+ * @returns Quoted table reference.
103
+ */
104
+ export function quoteTableRef(table: TableRef, quoteIdentifier: QuoteIdentifier): string {
105
+ if (table.schema) {
106
+ return quoteIdentifier(table.schema) + '.' + quoteIdentifier(table.name)
107
+ }
108
+
109
+ return quoteIdentifier(table.name)
110
+ }
111
+
112
+ /**
113
+ * Converts a JavaScript value into a SQL literal string.
114
+ * @param value Value to serialize.
115
+ * @param options Serialization options.
116
+ * @param options.booleansAsIntegers When `true`, booleans render as `1`/`0`.
117
+ * @returns SQL literal text.
118
+ */
119
+ export function quoteLiteral(
120
+ value: unknown,
121
+ options?: {
122
+ booleansAsIntegers?: boolean
123
+ },
124
+ ): string {
125
+ if (value === null) {
126
+ return 'null'
127
+ }
128
+
129
+ if (typeof value === 'number' || typeof value === 'bigint') {
130
+ return String(value)
131
+ }
132
+
133
+ if (typeof value === 'boolean') {
134
+ if (options?.booleansAsIntegers) {
135
+ return value ? '1' : '0'
136
+ }
137
+
138
+ return value ? 'true' : 'false'
139
+ }
140
+
141
+ if (value instanceof Date) {
142
+ return quoteLiteral(value.toISOString(), options)
143
+ }
144
+
145
+ return "'" + String(value).replace(/'/g, "''") + "'"
146
+ }
package/src/lib/sql.ts ADDED
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Parameterized SQL payload.
3
+ *
4
+ * The `text` may contain positional placeholders (`?`) or dialect-native
5
+ * placeholders (for example `$1`, `$2`) depending on compiler stage.
6
+ */
7
+ export type SqlStatement = {
8
+ text: string
9
+ values: unknown[]
10
+ }
11
+
12
+ /**
13
+ * Tagged-template helper for building parameterized SQL statements.
14
+ * @param strings Template string parts.
15
+ * @param values Interpolated values or nested {@link SqlStatement} values.
16
+ * @returns A normalized {@link SqlStatement}.
17
+ * @example
18
+ * ```ts
19
+ * import { sql } from 'remix/data-table'
20
+ *
21
+ * let email = 'user@example.com'
22
+ * let statement = sql`select * from users where email = ${email}`
23
+ * // => { text: 'select * from users where email = ?', values: ['user@example.com'] }
24
+ * ```
25
+ */
26
+ export function sql(strings: TemplateStringsArray, ...values: unknown[]): SqlStatement {
27
+ let text = ''
28
+ let parameters: unknown[] = []
29
+ let index = 0
30
+
31
+ while (index < strings.length) {
32
+ text += strings[index]
33
+
34
+ if (index < values.length) {
35
+ let value = values[index]
36
+
37
+ if (isSqlStatement(value)) {
38
+ text += value.text
39
+ parameters.push(...value.values)
40
+ } else {
41
+ text += '?'
42
+ parameters.push(value)
43
+ }
44
+ }
45
+
46
+ index += 1
47
+ }
48
+
49
+ return {
50
+ text,
51
+ values: parameters,
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Returns `true` when a value matches the {@link SqlStatement} shape.
57
+ * @param value Value to inspect.
58
+ * @returns Whether the value is a {@link SqlStatement} object.
59
+ */
60
+ export function isSqlStatement(value: unknown): value is SqlStatement {
61
+ if (typeof value !== 'object' || value === null) {
62
+ return false
63
+ }
64
+
65
+ let statement = value as { text?: unknown; values?: unknown }
66
+
67
+ return typeof statement.text === 'string' && Array.isArray(statement.values)
68
+ }
69
+
70
+ /**
71
+ * Creates a SQL statement from raw text and values.
72
+ * @param text SQL text containing placeholders expected by the target adapter.
73
+ * @param values Placeholder values.
74
+ * @returns A normalized SQL statement.
75
+ * @example
76
+ * ```ts
77
+ * import { rawSql } from 'remix/data-table'
78
+ *
79
+ * let statement = rawSql('select * from users where id = ?', [1])
80
+ * ```
81
+ */
82
+ export function rawSql(text: string, values: unknown[] = []): SqlStatement {
83
+ return { text, values }
84
+ }