table-import-structure
Generate ServiceNow import scaffolding from a table .now.ts definition: data.csv headers, dataSource.now.ts, importSet.now.ts, and transformMap.now.ts with reference/coalesce rules. Use when creating or fixing src/fluent/data/<TableName>/ structures.
Install
mkdir -p .claude/skills/table-import-structure && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15313" && unzip -o skill.zip -d .claude/skills/table-import-structure && rm skill.zipInstalls to .claude/skills/table-import-structure
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Generate ServiceNow import scaffolding from a table .now.ts definition: data.csv headers, dataSource.now.ts, importSet.now.ts, and transformMap.now.ts with reference/coalesce rules. Use when creating or fixing src/fluent/data/<TableName>/ structures.About this skill
Table Import Structure
Creates the data import structure for one ServiceNow table folder at:
- src/fluent/data/<TableName>/data.csv
- src/fluent/data/<TableName>/dataSource.now.ts
- src/fluent/data/<TableName>/importSet.now.ts
- src/fluent/data/<TableName>/transformMap.now.ts
When To Use
- You have a table definition file in src/fluent/table/*.now.ts.
- You want the matching import files generated with consistent conventions.
- You want transform map rules that correctly handle display-name coalescing and reference mappings.
Inputs
- Required: path to one table definition file (for example src/fluent/table/Set.now.ts).
- Optional: explicit display field override if table display is not declared.
Procedure
- Read the table .now.ts file and extract:
- table technical name from name (for example x_776055_snworkout_set)
- table label and short table name from file name (for example Set)
- schema fields and field types
- display field from display if present
- extends value if present
- Build folder and CSV header:
- target folder is src/fluent/data/<ShortTableName>/
- create or update data.csv
- first line is a comma-separated list of schema field names in declared order
- do not add sys_id unless explicitly present in schema
- Build or update dataSource.now.ts by copying the Exercice template pattern exactly:
- Template pattern : import { Record } from '@servicenow/sdk/core'
Record({ $id: Now.ID['8e37becf83f84f107bdea530ceaad337'], table: 'sys_data_source', data: { batch_size: 1000, connection_timeout: 0, connection_url: 'attachment://sys_data_source:8e37becf83f84f107bdea530ceaad337/', data_in_single_column: false, data_loader: `(function loadData(import_set_table, data_source, import_log, last_success_import_time, partition_info) {
// Add your code here to insert data to import_set_table
})(import_set_table, data_source, import_log, last_success_import_time, partition_info);, discard_arrays: true, enable_parallel_loading: false, expand_node_children: false, file_retrieval_method: 'Attachment', format: 'CSV', glide_keystore: false, header_row: 0, import_set_table_label: 'Import Exercice', import_set_table_name: 'x_776055_snworkout_import_exercice', ldapprobe_result_set_rows: 200, name: 'Exercice', offset: 0, oracle_port: '1521', oracle_sid: 'orcl', parallel_loading_script: (function loadTasks(parallel_job_loader, data_source, import_log, last_success_import_time) {
// Invoke third party API, create partitions and insert partitions info in parallel job table
})(parallel_job_loader, data_source, import_log, last_success_import_time);, parsing_script: // The input value can be accessed through the variables named "line", "lineNumber" and "result"
// The function uses result variable to return parse result back.
(function(line,lineNumber,result) {
// add code here
})(line,lineNumber,result);`,
query: 'All Rows from Table',
query_timeout: 0,
scp_authentication: 'Username and Password',
sheet_name: 1,
sheet_number: 1,
support_pagination: false,
type: 'File',
use_batch_import: false,
use_import_connection_alias: false,
use_integrated_authentication: false,
use_last_run_datetime: false,
zipped: false,
properties: 'charset=utf-8',
},
})
as the canonical shape
- keep all non-table attributes unchanged
- only change table-related attributes:
- $id (new stable key)
- data.name
- data.import_set_table_name
- data.import_set_table_label
- data.connection_url
- Build or update importSet.now.ts pattern:
- template pattern : import { Table, StringColumn } from '@servicenow/sdk/core'
export const x_776055_snworkout_import_exercice = Table({ allowWebServiceAccess: true, attributes: { enforce_dot_walk_cross_scope_access: true, }, extends: 'sys_import_set_row', label: 'Exercice', name: 'x_776055_snworkout_import_exercice', schema: { u_title: StringColumn({ attributes: { import_attribute_name: 'title', }, label: 'title', maxLength: 41, }), u_description: StringColumn({ attributes: { import_attribute_name: 'description', }, label: 'description', maxLength: 40, }), u_rest: StringColumn({ attributes: { import_attribute_name: 'rest', }, label: 'rest', }), u_preparation: StringColumn({ attributes: { import_attribute_name: 'preparation', }, label: 'preparation', }), u_effort: StringColumn({ attributes: { import_attribute_name: 'effort', }, label: 'effort', }), }, })
- table extends sys_import_set_row
- name is x_776055_snworkout_import_<short_table_snake_case>
- for each schema field create a StringColumn named u_<field_name>
- label uses the raw field name
- set attributes.import_attribute_name to original field name
- for StringColumn in source table, copy maxLength from source (or use a greater value)
- for non-string source fields, StringColumn with no maxLength is acceptable unless project standards require one
- Build or update transformMap.now.ts using the same structure :
- structure : import { ImportSet } from '@servicenow/sdk/core'
ImportSet({ $id: Now.ID['27d73a43833c4f107bdea530ceaad3ee'], name: 'Exercice', targetTable: 'x_776055_snworkout_exercice', sourceTable: 'x_776055_snworkout_import_exercice', active: true, runBusinessRules: true, runScript: false, fields: { effort: { sourceField: 'u_effort', choiceAction: 'create', useSourceScript: false, dateFormat: 'yyyy-MM-dd HH:mm:ss', }, preparation: { sourceField: 'u_preparation', choiceAction: 'create', useSourceScript: false, dateFormat: 'yyyy-MM-dd HH:mm:ss', }, title: { sourceField: 'u_title', choiceAction: 'create', useSourceScript: false, dateFormat: 'yyyy-MM-dd HH:mm:ss', coalesce: true, }, rest: { sourceField: 'u_rest', choiceAction: 'create', useSourceScript: false, dateFormat: 'yyyy-MM-dd HH:mm:ss', }, description: { sourceField: 'u_description', choiceAction: 'create', useSourceScript: false, dateFormat: 'yyyy-MM-dd HH:mm:ss', }, }, })
- use ImportSet({ ... }) shape
- include $id, name, targetTable, sourceTable, active, runBusinessRules, runScript, fields
- for each target field map sourceField to matching u_<field>
- set useSourceScript to false
- omit sourceScript attribute entirely
- Apply mapping rules:
- display field of target table must be coalesced in transform map field entry
- Important ! if the table is a m2m table (2 reference fields and no display), then coalesce both the reference fields
- reference target fields must:
- map using referenceValueField set to target reference table display field
- use choiceAction: 'reject'
- use referenceValueField : <target reference field display field> if reference target has a display field
- otherwise use referenceValueField : sys_id
- Validate generated files:
- import set table/column names align with CSV headers
- transform map fields align with import set columns and target fields
- no sourceScript attribute remains
- run build/transform checks if requested
Decision Points
-
Display field resolution:
-
if table has display, coalesce that field
-
if not, prefer title, then name, then first mandatory string-like field
-
Reference mapping mode:
-
if existing table folder pattern already uses script lookup, keep that style
-
otherwise use direct u_<field> mapping + referenceValueField + choiceAction reject
-
Max length policy:
-
exact source maxLength is preferred
-
larger is allowed
-
do not choose smaller than source maxLength
Completion Checks
- The folder src/fluent/data/<ShortTableName>/ contains exactly the four files.
- data.csv columns match table schema fields.
- dataSource.now.ts follows Exercice pattern with only table-specific naming changes.
- importSet.now.ts has only u_-prefixed StringColumn fields for schema columns.
- transformMap.now.ts follows Exercice structure, has useSourceScript false, has no sourceScript attribute, coalesces display field, and handles references with reject + referenceValueField.
Example Prompts
- /table-import-structure src/fluent/table/Category.now.ts
- Generate import structure from src/fluent/table/SessionDefinitionSet.now.ts
- Rebuild transform map for src/fluent/table/Set.now.ts and preserve Exercice pattern